Written by Harry Roberts on CSS Wizardry.
Desk of Contents
This yr, I’ve been working intently with the fantastic
Coingaming crew out in stunning
Tallinn. We’ve
been working fairly onerous on making their suite of on-line merchandise a lot
quicker, and I’ve
been the technical guide main the undertaking. It’s been an extremely enjoyable
and rewarding engagement, and we’ve made some actual business- and customer-facing
enhancements. One of many key causes I’ve discovered the undertaking so enjoyable is that it’s
given me an actual likelihood to get very forensic. Naturally, a crew ought to all the time
deal with the low-hanging fruit first, however as soon as that’s executed, you get to delve a lot
deeper into the weeds. This weblog publish comes from there.
Background
To be able to get higher management over how a collection of thumbnail pictures are
displayed on the homepage of certainly one of their merchandise, the crew opted to construct them
not as <img />
parts, however as CSS background-image
s: this allowed them to
higher dimension and place the pictures of their container, and, placing apart any
semantic issues, it made sense from a styling perspective. My solely
reservation was realizing that, as a result of the pictures are outlined in CSS relatively than
HTML, their outgoing requests received’t begin till the browser has created the
Render Tree: it’s not till all of the CSS has been downloaded, parsed, and the
CSSOM constructed that the browser really is aware of This
.div
with this class
is presently seen on the web page and its background is about to be this picture: I’d
higher obtain it!
The waterfall beneath reveals the browser ready for CSSOM completion earlier than it
dispatches any requests for any pictures—you possibly can clearly see that the CSS must
end earlier than any pictures begin. That is all the way down to the straightforward undeniable fact that the browser
doesn’t know which (if any) pictures it’ll want till the CSSOM has been constructed:

CSSOM has accomplished.
That is too late for such vital content material of theirs—customers need to see the
thumbnails as quickly as attainable.
By shifting the pictures to <img />
parts (which can be semantically extra
acceptable), the browser can uncover them far sooner—as they grow to be uncovered to
the browser’s preload scanner—and dispatch their requests earlier than (or in parallel
to) CSSOM completion:

independently of CSSOM building.
That is stuff we already knew:
- Browsers can’t probably obtain
background-image
s till they’ve constructed the
CSSOM. - Browsers shouldn’t base—thus delay—the downloading of
<img />
s on CSSOM
completion. Extra on this later…
The place it will get attention-grabbing is after I began to surprise how completely different browsers
deal with various kinds of picture after they’re seen or not: an <img />
component with show: none;
utilized to it ideally wouldn’t get downloaded, however
the one approach the browser would know that the picture is certainly hidden is that if it
waits for CSSOM completion, thus slowing down the default conduct of the <img
: what’s going to occur?
/>
background-image
I’ll begin with background-image
as that’s what my shopper’s preliminary use case
was. I really feel just like the behaviour for background-image
ought to be essentially the most
predictable as there are particular impossibilities at play (e.g. we are able to’t obtain
a background-image
till we’ve constructed the CSSOM).
What I Would Anticipate
I’ve a few expectations (or hopes) that I predict:
- Browsers don’t (can’t) set off a obtain for a
background-image
till
it is aware of it wants it (i.e. till the CSSOM has been constructed). - Browsers wouldn’t obtain
background-image
that’s utilized to a component
that’s hidden from view (e.g.show: none;
).
What Truly Occurs
Chrome (v67.0.3396.79)
- Expectedly Chrome doesn’t obtain any
background-image
till the CSSOM
has been constructed:View full dimension/high quality - Unexpectedly, Chrome will obtain a
background-image
that isn’t seen
to the consumer:View full dimension/high quality
Safari (v11.1 (13605.1.33.1.4))
- Expectedly Safari doesn’t obtain any
background-image
till the CSSOM
has been constructed:View full dimension/high quality - Expectedly, Safari won’t obtain a
background-image
that isn’t
seen to the consumer:View full dimension/high quality
Firefox (v60.0.1)
- Expectedly Firefox doesn’t obtain any
background-image
till the
CSSOM has been constructed:View full dimension/high quality - Expectedly, Firefox won’t obtain a
background-image
that isn’t
seen to the consumer:View full dimension/high quality
Opera (v53.0.2907.68)
- Expectedly Opera doesn’t obtain any
background-image
till the CSSOM
has been constructed:View full dimension/high quality - Unexpectedly, Opera will obtain a
background-image
that isn’t seen
to the consumer:View full dimension/high quality
Edge (v17.17134)
- Expectedly Edge doesn’t obtain any
background-image
till the CSSOM
has been constructed.View full dimension/high quality - Unexpectedly, Edge will obtain a
background-image
that isn’t seen
to the consumer.View full dimension/high quality
Abstract
N.B. Sure or No represents factual data. ✓ and ✗
signify what I’d think about good/anticipated and unhealthy/surprising behaviour,
respectively.
Chrome | Safari | Firefox | Opera | Edge | |
---|---|---|---|---|---|
Block on CSSOM | Sure ✓ | Sure ✓ | Sure ✓ | Sure ✓ | Sure ✓ |
Obtain if Invisible | Sure ✗ | No ✓ | No ✓ | Sure ✗ | Sure ✗ |
Verdict
Firefox and Safari appear to have essentially the most most popular behaviour right here: they
received’t obtain background-image
s that they know they received’t want.
Chrome, Opera, and Edge will all obtain background-image
s that
are utilized to invisible parts. This feels wasteful, however I think it’s
a preemptive optimisation to make sure that the picture is on the shopper earlier than the
potential occasion that the component turns into seen. I really feel that—if that is the
case—that is an optimisation that ought to be left to the developer.
<img />
Subsequent, let’s check out how browsers deal with <img />
s.
What I Would Anticipate
- Browsers will obtain
<img />
utterly independently of CSSOM
building. Blocking<img />
on CSSOM building appears very
inefficient, and would result in delays in downloading content material. - Accordingly, browsers will obtain
<img />
that find yourself being hidden from
view, i.e.show: none;
. If the browser begins downloading<img />
earlier than CSSOM building (as I count on) then it has no approach of realizing but
whether or not that picture is required or not.
What Truly Occurs
Chrome
- Expectedly, Chrome won’t block
<img />
requests on CSSOM
building:View full dimension/high quality - Expectedly, on account of the above, Chrome will obtain
<img />
that
finally find yourself invisible:View full dimension/high quality
Safari
- Expectedly, Safari won’t block
<img />
requests on CSSOM
building:View full dimension/high quality - Expectedly, on account of the above, Safari will obtain
<img />
that
finally find yourself invisible:View full dimension/high quality
Firefox
- Unxpectedly, Firefox will block
<img />
requests on CSSOM building.
Because of this<img />
requests will not be dispatched till the CSSOM has been
constructed. This represents a stunning inefficiency:View full dimension/high quality - Unexpectedly, regardless of Firefox realizing it received’t want the
<img />
—as
a results of it unexpectedly blocking on CSSOM building—it’ll nonetheless
obtain the<img />
even when it is aware of it won’t be seen. I discover this
extraordinarily weird: it appears to get issues unsuitable on each counts:View full dimension/high quality
Opera
Edge
Abstract
N.B. Sure or No represents factual data. ✓ and ✗
signify what I’d think about good/anticipated and unhealthy/surprising behaviour,
respectively.
Chrome | Safari | Firefox | Opera | Edge | |
---|---|---|---|---|---|
Block on CSSOM | No ✓ | No ✓ | Sure ✗ | No ✓ | No ✓ |
Obtain if Invisible | Sure ✓ | Sure ✓ | Sure ✗ | Sure ✓ | Sure ✓ |
Verdict
Firefox seems to dam <img />
on CSSOM building. This looks like
a foul thought—no <img />
s will start downloading till Firefox has downloaded,
parsed, and utilized the CSS. Because of this you probably have blocking stylesheets,
they’re blocking your <img />
. This might be notably troublesome if <img
are key content material (suppose Imgur, Flickr, and so forth.).
/>
Firefox will get weirder nonetheless! It waits till it’s constructed the CSSOM earlier than
it fires off any <img />
requests, which implies it is aware of if the <img />
will
be seen or not, but when the <img />
is invisible, it’ll obtain it
anyway. This can be a double-hit: Firefox blocks <img />
on CSSOM building but
nonetheless downloads <img />
that aren’t seen.
Key Takeaways
The Details
- Chrome, Opera, and Edge will obtain
background-image
s that
aren’t required for first render. Because of this hidden DOM nodes which have
abackground-image
utilized to them will nonetheless have thatbackground-image
downloaded. Beware surprising downloads. - Firefox will block
<img />
downloads on CSSOM building, that means
later-than-expected downloads. Beware delays. - Additional, Firefox will nonetheless obtain the
<img />
even when it wasn’t
wanted. Beware surprising downloads.
How May this Have an effect on You?
In case you’re a product that depends closely on content material imagery (e.g. Flickr, on-line
publication, photographer) then Firefox won’t obtain any of these pictures
till it’s dealt along with your CSS. It’s best to look into preloading any key picture
content material.
In case you’re making heavy use of background pictures and, for no matter cause, are
not exhibiting all of them for first render, beware that some browsers will go
forward and obtain them anyway: you may need to look into higher methods
for hidden content material (e.g. removing from the DOM relatively than show: none;
).