I’ll provide some clarifications to close things out / settle any lingering questions.
You are also correct that using the “if()” approach won’t help performance issues which are caused by very broad or very deep question dependencies. It’s primarily helpful when you have a single (or small number) expression which consumes a significant amount of time (such as a lookup into the casedb database or a large lookup table).
In the pattern I mentioned above, the only effect of the if() function is that the last function call isn’t triggered, but the calculation itself is always triggered when var1, var2, var3, etc are changed. This is because the engine determines the graph of calculations to update before it identifies what the new values themselves are. This makes the engine performance deterministic and overall more efficient, but does make it difficult to defer “no-op” calculation updates where a value didn’t actually change.
There are a few ways to work around this challenge depending on the size of the form, but the most reliable one is to split up very long forms into multiple forms and to store the values from earlier logic into cases which can be loaded back as “default value” calculations later, rather than having a single form needing to keep the complex web of updates up to date consistently.
It can also help to minimize the “Depth” of dependent calculations. (IE: “A effects B which effect C and D, which …”). One way to accomplish that is to remove most hidden value calculations from groups, where they are affected by relevant conditions from the parents, into a separate section of the form where they can be updated in isolation.