@let and @defer
The plant details page has two problems. The expression plant().everyDays - daysSince() appears three times, and a heavy GrowthChart at the very bottom slows every visit, even though most people never scroll that far. Two small blocks fix both.
The rule
@letnames a value once;@deferloads a piece only when it is needed.
@let declares a named value inside a template:
@let daysLeft = plant().everyDays - daysSince();
<h2>{{ plant().name }}</h2>
@if (daysLeft <= 0) {
<p class="alert">Water today!</p>
} @else {
<p>Next watering in {{ daysLeft }} days.</p>
}The value updates whenever the signals it reads change. It is read-only: you cannot assign to it from a template statement. It is visible only after its declaration, within the same block and blocks nested inside it. Note the closing semicolon.
@defer delays part of a template:
@defer (on viewport) {
<app-growth-chart [plant]="plant()" />
} @placeholder {
<p>Growth chart</p>
} @loading (minimum 300ms) {
<p>Loading chart…</p>
} @error {
<p>The chart could not load.</p>
}At build time, Angular moves GrowthChart's code into a separate file. The page ships without it; the file downloads only when the trigger fires. Until then, @placeholder shows. While downloading, @loading shows. If it fails, @error shows.
Common triggers:
on idle(the default): when the browser is idle.on viewport: when the placeholder scrolls into view.on interactionoron hover: when the user clicks or hovers the placeholder.on timer(2s),on immediate, orwhen someCondition().
For the code to be split out, a deferred component must be standalone and not used anywhere else in the same template file.
The shortcut
For @let, the test is "did I write this expression twice?" Name it once. For @defer, the test is "does every visitor need this the moment the page opens?" If not, and it is heavy, defer it on the trigger that matches when people actually reach it.
Plant name and watering status
Everyone needs them immediately. Keep them normal.
Drills
Answer fast — trust the rule.
What is the default trigger when you write @defer with no trigger?
Which block shows while the deferred content has not yet been triggered?
What is true about @let total = plants().length;?
Why might a deferred GrowthChart still load with the rest of the page?
Remember
@let name = expr;names a read-only value, visible after its declaration.@defer (trigger) { } @placeholder { } @loading { } @error { }splits heavy parts out; default trigger ison idle.- Trap: using the deferred component elsewhere in the template keeps it in the main bundle.
