Skip to content

Commit c2c11af

Browse files
committed
Add loading/fetchpriority post
1 parent a1be63b commit c2c11af

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
---
2+
layout: post
3+
title: "When All You Can Do Is All or Nothing, Do Nothing"
4+
date: 2026-03-30 11:30:00
5+
categories: Web Development
6+
main: ""
7+
meta: "If your design system can only apply `loading=lazy` or `fetchpriority=high` blindly, it may be safer not to apply them at all."
8+
---
9+
10+
I’ve been working a lot over the last few years on the idea of **web performance
11+
for design systems**. While a lot of my clients want me to start at the end and
12+
work back (<q>we have a slow site, how can we make it faster?</q>), particularly
13+
ambitious clients ask <q>how can we bake web performance in from the start?</q>
14+
This post comes from a specific bit of advice I gave a client recently.
15+
16+
Their design system sits on top of a highly permissive CMS. Editors have a lot
17+
of freedom—which is great—but it means the system often does not know, or cannot
18+
tell, if a component will render above or below the fold, on or off screen, or
19+
whether it will appear once or many times on the page.
20+
21+
This makes things like `loading=lazy` and `fetchpriority=high` awkward: if an
22+
image might be an LCP candidate, then `loading=lazy` is bad news; if several
23+
images might be LCP candidates, then `fetchpriority=high` on all of them is bad
24+
news, too—when everything is high priority, nothing is.
25+
26+
And so my take is this: **when all you can do is all or nothing, _do nothing_.**
27+
28+
## Tools and Context
29+
30+
`loading=lazy` only helps if you apply it to things the user does not yet need,
31+
but apply it to something needed immediately and you may have made the page
32+
worse.
33+
34+
Similarly, `fetchpriority=high` only helps if you use it to identify one likely
35+
winner among a field of contenders: apply it to all contenders and you have not
36+
clarified anything, you’ve just added noise.
37+
38+
These are not magic <i>make it faster</i> attributes, they are hints, and hints
39+
are only useful when they are specific and contextual.
40+
41+
## Dumb Design Systems
42+
43+
A design system (or any system, really) should never try to know more than it
44+
really does. Imagine a reusable card component:
45+
46+
```html
47+
<article class=c-card>
48+
<img src=/img/promo.jpg
49+
alt="Promotional image"
50+
width=640
51+
height=360
52+
loading=lazy>
53+
54+
<h2>Spring Collection</h2>
55+
<p>Discover the latest arrivals.</p>
56+
</article>
57+
```
58+
59+
If this component always lived in a product grid halfway down the page, sure,
60+
lazy-load it. But if CMS users can also use it:
61+
62+
* as a hero/LCP candidate;
63+
* as the first component below the masthead;
64+
* in a two-up where one card is above the fold and the other beneath;
65+
* or in a genuinely off-screen position;
66+
67+
…then the design system doesn’t have the right to guess.
68+
69+
In that world, this version is safer:
70+
71+
```html
72+
<article class=c-card>
73+
<img src=/img/promo.jpg
74+
alt="Promotional image"
75+
width=640
76+
height=360>
77+
78+
<h2>Spring Collection</h2>
79+
<p>Discover the latest arrivals.</p>
80+
</article>
81+
```
82+
83+
In other words, I would recommend you leave the browser to handle it.
84+
85+
That might mean you load a handful of below-the-fold images a little earlier
86+
than ideal, and that’s fine. I would certainly rather this be the baseline than
87+
potentially inadvertently lazily loading content that doesn’t need it.
88+
89+
<small>As a brief but important side note: `loading=lazy` does not necessarily
90+
mean <i>below the fold</i>.</small>
91+
92+
<small>There are plenty of perfectly reasonable above-the-fold use cases for
93+
`loading=lazy`:</small>
94+
95+
* <small>the second image onward in a carousel;</small>
96+
* <small>thumbnail images in a larger image gallery;</small>
97+
* <small>assets hidden in a hamburger or flyout menu;</small>
98+
* <small>imagery that is present in the DOM but not meaningfully useful until
99+
some JS has initialised the relevant UI.</small>
100+
101+
<small>Those are all cases where an image may be in or near the initial viewport
102+
but still not needed _yet_.</small>
103+
104+
<small>That is the distinction I care about: not strictly below the fold, but
105+
not immediately necessary.</small>
106+
107+
## `fetchpriority=high`
108+
109+
The same thinking carries through to `fetchpriority`. Consider a larger media
110+
component:
111+
112+
```html
113+
<img src=/img/campaign.jpg
114+
alt="Campaign image"
115+
width=1200
116+
height=675
117+
fetchpriority=high>
118+
```
119+
120+
If you know this is _the_ LCP candidate, then that is a sensible hint! But if
121+
the CMS allows three of these near the top of the page, then you end up with:
122+
123+
```html
124+
<img src=/img/hero-1.jpg fetchpriority=high alt="" width=1200 height=675>
125+
<img src=/img/hero-2.jpg fetchpriority=high alt="" width=1200 height=675>
126+
<img src=/img/hero-3.jpg fetchpriority=high alt="" width=1200 height=675>
127+
```
128+
129+
At that point, you are no longer really prioritising anything. The browser is
130+
already trying to work out which requests matter most. If your design system or
131+
CMS cannot confidently identify one winner, it shouldn’t flood the network
132+
claiming that several things are equally urgent. **When everything is high
133+
priority, nothing is.**
134+
135+
## The Browser Default Is Not Failure
136+
137+
Doing nothing here is not negligent, but normal. We didn’t even have these
138+
primitives a few years ago. Omitting them is not some devolution; it is just
139+
falling back to the norm. The browser discovers images, requests them, and
140+
prioritises them as best it can. In ambiguous systems, that is often the most
141+
honest and least harmful baseline. Put another way…
142+
143+
Given three options, and the first is taken away from you, would you rather:
144+
145+
1. <s>do the right thing,</s>
146+
2. do the wrong thing, or
147+
3. do nothing?
148+
149+
I think we’d all opt for the latter. Doing nothing is better than doing the
150+
wrong thing. This leads me nicely on to…
151+
152+
## Missed Opportunities Are Safer Than Bad Optimisations
153+
154+
If I fail to lazy-load an image that turns out not to be needed immediately,
155+
I have left a little performance gain on the table, but if I lazy-load an LCP
156+
candidate, I have actively made the page worse. Without lazy loading, the worst
157+
case scenario is that the browser puts the request(s) out to the network
158+
a little eagerly, but it will fall back to other heuristics to prioritise from
159+
there.
160+
161+
Likewise, if I omit `fetchpriority=high` from a hero image, perhaps the browser
162+
takes a fraction longer to realise its importance, but if I add
163+
`fetchpriority=high` to every possible hero, I have turned a useful hint into
164+
noise. Without `fetchpriority=high`, the worst case scenario is that the browser
165+
puts the request(s) out to the network a little slowly, but **it will fall back
166+
to other heuristics to prioritise from there**.
167+
168+
Both scenarios have great safety nets.
169+
170+
## Use Hints Where You Have Certainty
171+
172+
Naturally, this is not an argument against either hint. If your design system
173+
really _does_ know that:
174+
175+
* article-body images after paragraph three are below the fold;
176+
* the homepage hero is always first, or;
177+
* carousel slides after the first are off-screen;
178+
179+
…then use them! If you have enough context to be precise, be precise. But if you
180+
do not, don’t risk it.
181+
182+
## Do Nothing, Deliberately
183+
184+
Sometimes, at design system level, the least clever option is the safest. If all
185+
you can do is lazy-load everything or lazy-load nothing, choose nothing; if all
186+
you can do is mark several possible winners as high priority, choose none.
187+
188+
And I don’t mean forever, I mean until your system has the knowledge to do more.
189+
If or when you can communicate more to the front end, err on the side of caution
190+
and do nothing at all.
191+
192+
When all you can do is all or nothing, **do nothing**.

0 commit comments

Comments
 (0)