This content originally appeared on phpied.com and was authored by Stoyan
You know the pattern: spit out some markup, probably server-side, but hide it for later. On-demand features (not to overwhelm the UI), dialogs waiting to pop, and so on.
<div class="modal hidden">content here...<div>
And what happens when the "content here..." includes resources, such as images? Is the browser going to download them? Let's check.
What to test
- image in a div hidden with
visibility: hidden
. The theory is that this is more likely to be downloaded because invisibility still takes a section of the page, the browser needs to calculate geometry of the content, so an image (exp one that has no width/height) will be required to load - image in a div hidden with
display: none
- image in a non-expanded
<details>
HTML element - same three things above but with
loading="lazy"
on the contained images - all of the 6 scenarios above but below the fold
Test page
/files/display/test.html, you can see the full source and play with show/hiding and scrolling. At the top of the pages all downloaded images are being listed (thanks to their respective load
events)
Results
X-browser!
I tested Firefox, Safari and Chrome and they all behave exactly the same.
More details
- All non-lazy images are loaded
- no matter if they are above or below the fold
- no matter how their containers are hidden
- A lazy image above the fold inside a
visibility: hidden
loads too - Lazy images inside a
display: none
or<details>
do not load - Scrolling all the way down loads another image, the lazy one inside
visibility: hidden
- Expanding all the containers (while above the fold) loads the lazy images above the fold
- Finally expanding all the containers (and scrolling all the way down) loads the lazy images below the fold
Discussion
So what does all that mean? Assuming we prefer to not load images in hidden content...
visibility: hidden
is the worst, as expected, avoiddisplay: none
and<details>
(both behave the same) are slightly better if you useloading=lazy
on the images, prefer. And so...- Always use
loading=lazy
on images in hidden content - For a foolproof non-loading, use the old technique of commented-out HTML, see below
The old commented out technique
This is a technique that was somewhat preferred in the recent past when we worried about low-powered devices that take a moment to parse large chunks of HTML, when such HTML is not initially required. Since we always need to worry about low-powered devices, it makes sense to refresh on this technique again.
Say this is the hidden content you want to unhide when appropriate:
<h3>Stuff</h3> <p> <img src="https://slowfil.es/file?type=png"> Integer luctus metus eros, ... </p>
- Step 0: make sure there are no HTML comments inside the hidden content
- Step 1: wrap in HTML comments and put in a container:
<div id="commented"> <!-- <h3>Stuff</h3> <p> <img src="https://slowfil.es/file?type=png"> Integer luctus metus eros, ... </p> --> </div>
- Step 3: unhide in an opportune moment:
const trimmed = commented.innerHTML.trim(); commented.innerHTML = trimmed.substring(4, trimmed.length - 3); /* alternatively... commented.innerHTML = commented.innerHTML.replace('<!--', '').replace('-->', ''); */
Happy new 2024!
Feb 9 update
Added experimentation with content-visibility: hidden
. It's only supported in Chromes and also didn't help, behaved just like display: none
. Sad trombone.
This content originally appeared on phpied.com and was authored by Stoyan
Stoyan | Sciencx (2024-01-02T03:41:52+00:00) Image requests in hidden content. Retrieved from https://www.scien.cx/2024/01/02/image-requests-in-hidden-content/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.