First of all - are you using modelsManager and joins ? If not start using them. If you don't use them, and you just do:
$users = Users::find();
and then you do something like:
{% for user in users %}
{{ user.fkCity.title }}
{% endfor %}
Then you will got additional database queries in number of those users. That's mostly the performance you can got if you switch to modelsManager and just do database joins.
About your question. I would stick to {{user.firstName}} from {{user.fkCity.title}}
beacause it's just looks better. I don't think so that there is big diffrence when set variable first. At least there might be some advatange if you use it like this:
{% set fkCity = user.fkCity %}
{{user.firstName}} from {{fkCity.title}}
At least if you are gonna use fkCity
again somewhere(but im't not sure, maybe opcache is already doing stuff like this ?). The same way is with title, if you are gonna use title value many times in template then yea - better to store it in variable to remove additional method calls.
I would recommend to use modelsManager and select only columns you need - that will be fastest possible way, but this way you will don't have fkCity
in user, you will just have title
(and other columns you select from fkCity
) in user
. If you will full select objects like users.*,fkCity.*
then it will by hydrated how it should be and you could access fkCity
in user
but that will cost additional time. I am using in most of cases modelsManager and selecting columns only i need.
Also remember that each new variable will use some amount of memory. But in this case it will be like nothing i guess.
But as i wrote above, it's mostly about how you select those users and their cities, not how you displaying them.