Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript lazy loading the progressive enhancement way?

I'm building a website for a gallery owner that has a lot of images per webpage. Therefore I want to lazy load the images on the webpage, making the initial load less heavy. However, I would like to implement this in a "progressive enhancement" way.

I've found a lot of lazy loading methods but they all require fiddling with the html code in such a way that the webpage would be useless with javascript turned off. (eg. the src attribute of the img tags remains unset until the images is lazy loaded).

To implement a lazy loading method progressivly I think one would need the following:

  1. prevent the browser from fetching the images, even though thers are on the page, but only do this when javascript is on (so on non-javascript browsers, the images still load as normal). This should be done without altering the html.
  2. save the src attribute in a data-src attribute
  3. sequentually load the images when scrolling down

Of these three steps the first one seems the hardest one. Even this stackoverflow discussion did not provide an answer that doesn't ruin progressive enhancement.

Has anyone got any ideas?

like image 462
romeovs Avatar asked Sep 08 '13 01:09

romeovs


People also ask

Does lazy loading improve performance?

Lazy-loading images and video reduces initial page load time, initial page weight, and system resource usage, all of which have positive impacts on performance.

What is Javascript lazy loading?

Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the length of the critical rendering path, which translates into reduced page load times.

Can I use iframe loading lazy?

Can I lazy-load iframes cross-browser? Yes # iframe lazy-loading can be applied as a progressive enhancement. Browsers which support loading=lazy on iframes will lazy-load the iframe, while the loading attribute will be safely ignored in browsers which do not support it yet.

What is lazy loading technique?

Lazy loading is the practice of delaying load or initialization of resources or objects until they're actually needed to improve performance and save system resources.


2 Answers

Since none has come up with an answer, I'll post what I found a reasonable solution.

This problem boils down to the following: while we want to prevent the browser from downloading the images when javascript is turned on, we must be sure the images are downloaded when javascript is turned off or not available.

It is hard to consistently use javascript to stop loading images on a page when they are in the "normal" format:

<img src="path/to/image.jpg"></img>

To stop the images from downloading we'd have to remove their src attributes, but in order to do this, the DOM should be loaded already. With the optimisations a lot of browsers have nowadays it is hard to guarantee that the images aren't downloading already.

On top of that, we certainly want to prevent interrupting images that are already downloading, because this would simply be a waste.

Therefore, I choose to use the following solution:

<img data-src="path/to/image.jpg" class="lazy"></img>
<noscript>
    <img  src="path/to/image.jpg"></img>
</noscript>

Notice how the images outside of the noscript tag have no src but a data-src attribute instead. This can be used by a lazyloading script to load the images one by one for instance.

Only when javascript is not available, will the images inside the noscript block be visible, so there's no need to load the .lazy images (and no way to do this, since javascript is unavailable).

We do need to hide the images though:

<noscript>
    <style>
        .lazy {
            display: none;
        }
    </style>
 </noscript>

Like the img tags inside the noscript block, this style block will only be visible to the browser when javascript is unavailable.

On a related note: I thought I could reduce the html size by not putting a src or data-src attributes on the lazy images at all. This would be nice because it eliminates the redundant url from the page, saving us some bandwidth.

I thought I could pluck the src attribute out of the noscript block using javascript anyways. However, this is impossible: javascript has no access to the contents of a noscript block. The above scheme is therefore the most efficient I could come up with.

like image 77
romeovs Avatar answered Oct 26 '22 22:10

romeovs


Not specifying a src attribute is invalid HTML, which is unfortunately how most lazy image loaders work.

I am working on a lazyloader that uses valid html markup, github link: https://github.com/tvler/lazy-progressive-enhancement

A lazyloaded image would be declared by wrapping it in a noscript element:

<noscript><img alt="hello!" src="..."></noscript>

and the final outputted html would be

<img alt="hello!" src="...">.

You can view the whole project on github, which deals with batch loading, event hooking & more, but here's the basic functionality at the scope of a single noscript image:

var noscript = document.querySelector('noscript'), img;
(img = document.createElement('div')).innerHTML = noscript.textContent;
noscript.parentElement.replaceChild(img.firstChild, noscript);
like image 43
Tyler Avatar answered Oct 26 '22 23:10

Tyler