Do hidden elements load background images?
One thing I have always pondered about is whether elements that are hidden will load any images associated with it, either inline or through CSS, directly at page load. And apparently, my colleague Jonatan Larsson has as well.
Jonatan and I discussed this back and forth, how it actually works and how we’d want it to work. Both he and I felt fairly certain that if an element, for instance, had a background image associated with it but was hidden (i.e. has
display: none), it wouldn’t load its background image until it was shown.
So, Jonatan set about on doing some tests and his findings were that images for hidden elements, set via CSS or inline in the element, would load every time – contrary to what we thought/expected.
Part of me thinks this is good that when the element is shown, everything is already loaded and will look good, but the performance fan in me is thinking that a web browser should only load what is actually displayed.
What would you want or expect? And do you have any other findings
I would prefer that the images do load, for the reasons that you outlined.
However, as a slight tweak to somewhat alleviate your concerns, the browser could load that element last. You would still incur the bandwidth and slight CPU hit, but the apparent speed of the page loading would be the same as if the element had not loaded.
Interesting. I have been pondering about this as well. Even though I also have been to lazy to actually try it out I also expected hidden images to not load until visible (but I suspected that that wasn't really the case).
If I remember it correctly, Opera is the the only browser around not loading background-images for hidden elements.
Anyway, I think the current behavior is correct. The CSS file should neither have the power nor the responsibility to lazy-load background images. I think WAI-ARIA or something similar should make this work, much like how the DEFER attribute is used for .
My brief thoughts.
It makes sense to me that they would load because, in the grand scheme of things, having an element with a background image on a web page is there for the purpose of being displayed eventually.
You have tested with background images. But what about img elements?
That's what I would expect: everything called in the markup is loaded.
Browsers load hidden images. If is in your markup, it will be loaded.
I would like it to load but "asynchronously". I mean just load content with prio one first and then just load "hidden" images in the background.
In this particular case I think the images shouldn't be downloaded. Why spent my time waiting images that I will never see?
Bleyder: it's very uggly when you toggle the visibility of elements and they start to load the images after the element has been displayed. Therefor I opt it should load in the background, after visible stuff has loaded.
I mean this discussion could extend to stuff below your screen that you need to scroll to see. You dont want to load that initially but the user probably is going to scroll so load it before the he/she does so…
The fact that they are loaded when they're in the HTML (regardless of visibility or display) gives you the choice: if you don't want them to be loaded you should dynamically add the background-image (through inline style or by setting a class or id) when you make the element visible.
I would expect all images to load. If I don't want them to load I'll add them with JS on demand. I don't want browsers to be "clever" about what will be shown. The downsides far outweigh the upsides.
Good feedback everyone. I like that, no matter the opinion, I feel an urge to agree completely with every comment. 🙂
I think I can live with that they are boing loaded, but like Andreas said, I'd prefer it asynchronously when idle, or at the least loaded last in the document.
This made me wonder whether or not all background images in your CSS are loaded. After a quick check I found out that that, thankfully, wasn't the case. Only background images in rules that match some element are loaded.
Yes, that would have been scary if it had been the case. 🙂
If it's in the markup or the CSS, it should be loaded. That doesn't mean you can't do lazy loading – but you'll need JS to do it.
For example: put in a div or something and only assign it a background-image once it's positioned inside the viewable area via JS. If that image isn't just for decoration, i still wouldn't like that, since you can't put an alt-attribute on it. But there's still the title attrib, so i might be able to live with it.
On the other hand: people without JS could never see those images. So if they convey some meaning you better stay away of this.
You say it loads the images if they are defined in CSS. But as far as I see it doesn’t load them till the browser has to display them, even if they are defined in CSS.
As most of us need, I’d like the background images from hidden elements to be loaded in the browser, so that when the users do some actions which causes some elements change, the image to be changed “instantly”, not showing a white area for a few moments.
BUT there’s good news: I’ve found a very nice way to do the “trick”: Just set the z-index as -100 or some “negative infinite” value and change it on user actions. Et voila! 🙂
This blog post is nearly two years old, so I can imagine that the behavior in web browsers might have changed over time.
If you want them to load, though, using position: absolute and placing it off screen seems more reliable than a negative z-index.