Do background-images lazy-load with display:none?

So, do background-images lazy-load with display:none? I did a quick test by loading this testpage created by Steve Souders on webpagetest.org. These are the results:

Conclusion: don’t rely on setting display:none on background-images to have them lazy load.

High performance YouTube embeds

It’s all about speed! I mean, you want your visitors to stick around, enjoying your content instead of waiting for stuff to download, no? And I bet you would love Google to consider your site quick, now that speed has been confirmed to have an impact on search ranking?
“High Performance web sites”-guru Steve Souders is doing incredible work studying the impact of 3rd party content -and especially javascript-based services such as analytics and bannering- on the performance of a web site.
An entirely different type of 3rd party content is Flash video, especially YouTube embeds, but there are a number of indicators that these indeed do impact performance as well:

  • opening a page with embedded YouTube can take some time when on dialup (or mobile data)
  • YouTube-heavy pages tend to slow down older computers (flashblock or adblock anyone?)
  • Facebook doesn’t really embed YouTube by default, but uses a placeholder with a thumbnail instead that is replaced by the embedded YouTube only when clicked
  • Google Webmaster Tools “Site Performance” seems to sometimes single out pages with YouTube embeds (e.g. stating that there is a DNS-resolution overhead)

Indeed, when testing this simple page with some text and 2 embedded YouTube clips on webpagetest.org, these were the main results (full results including nice graphs here):

  • (base) download complete: 0.356s for 2KB
  • start render: 0.426s
  • full page download complete: 3.005s for 315KB

There’s good and bad news in those figures. As could be expected the YouTube Flash embed doesn’t impact the rendering of the base page. But 2.6 seconds and 312KB just to display 2 video’s a visitor might not even bother to look at (I bet that the click-rate for embedded YouTube video is somewhere between 2 and 20%), that’s … sub-optimal?
So I threw some JavaScript at my computer to build an alternative to the default YouTube embed, the main goal being to build a Flash-less initial view with only a few lines of html/javascript which at some point people could copy/paste in their site just like they do now. And LYTE (Lite YouTube Embed) came into the world.
The main results when testing this LYTE-test-page on webpagetest.org (full results here):

  • (base) download complete: 0.324s for 4KB (which is marginally faster)
  • start render: 0.363s (again marginally faster)
  • full page download complete: 0.803s for 35KB (leaner, meaner and faster!)

The code that would have to be copy/pasted (multi-line for clarity):
<div class="lyte" id="gnDh6PqWqD8" style="width:480;height:385;"><noscript><a href="http://youtu.be/gnDh6PqWqD8">Watch on YouTube</a></noscript>
<script>(function(){d=document;if(!document.getElementById('lytescr')){lyte=d.createElement('script');lyte.async=true;lyte.id="lytescr";lyte.src="http://futtta.be/lyte/lyte.js";d.getElementsByTagName('head')[0].appendChild(lyte)}})();</script></div>

The nitty-gritty (do skip if you’re not inclined to get aroused by technical details): this code attaches (a minified version of) lyte.js to the page’s head. The real work is done in that javascript-file: get all divs with class-name “lyte” (with a hack for friggin’ IE inlined), use the videoid which is in the divs’ id to fetch the thumbnail and title from YouTube, display these in a fashion which is very YouTube-like and add an onclick eventhandler to replace the fake with a real player when clicked (and remove the eventhandler to clean things up).
So using LYTE you can embed YouTube in such a way that the amount of data, the total download time and the total rendering time are significantly lower, without loosing any functionality.
And this -to conclude this long post- is what LYTE looks like (soundtrack by Nôze – “Meet me in the toilet”, it’s Friday after all);