We are happy to announce that we added lazy loading support to our pixboost.js library.
What is Lazy Loading?
Very often you have quite a few images on a page. When user is loading the page he doesn’t see all the images, but a browser will load all of them which will unnecessary increase load time and number of transferred bytes.
So, if we can only load images that a user sees then it can improve performance of the web application or website. When the user will scroll or open other images then we will load them. Below is the basic idea:
It doesn’t only apply to scrolling, but also for any images that aren’t visible. For instance, images in the menu or preview images that appear on click.
Obviously, you’ll need lazy loading in case if you have images that are not visible on initial load of the web page. We recommend to use Lighthouse Chrome extension to test your page on off screen images. Below is a step-by-step guide on how to do that:
- Install Lighthouse extension into Chrome.
- After installation you should see lighthouse icon on the Chrome toolbar.
3. Load the page that you want to test. We created a small demo page with and without lazy loading. URL of the original demo page is www.midday.coffee/original/cups.html
4. Once loaded click on the lighthouse icon and click “Generate report” button
5. Once lighthouse finished a scan you will see a report where you’ll find “Offscreen Images” section. That’s a list of images that can be lazy loaded and will give you performance boost.
We’ve also created optimized version of the demo page that is using lazy loading. If you’ll run Lighthouse on it then you’ll see that “Offscreen images” are now in “Passed Audit” section:
Enabling Lasy Load in Pixboost
There are two simple steps to enable lazy loading. The first is to include library that we are using before pixboost.js script:
Then you would need add attribute “data-lazy” for elements that you want to lazy load. Below are examples for responsive images and standard <img> tag:
We are using library called lozad to do lazy loading. It’s using browser’s feature called Intersection Observer. Pretty much all modern browsers except Safari supports it. If you want all browsers to support it then you’ll need to include polyfill as well:
However, we strongly recommend to do thorough testing as we had some problems with the polyfill. We found some issues on Safari when a page has absolute positioned elements. Also, IE 9 and IE10 didn’t behave properly in some complicated cases.
Under the hood
Lazy loading is not a new thing. It’s been around for quite a while. In early days implementation of the lazy loading was quite tricky. It was using Element.getBoundingClientRect() function and was checking visibility of elements on every scroll event. Of course running that much listeners and tests on main thread caused performance issues.
W3C knew about the developers needs and came up with a new API called Intersection Observer. API is quite simple and give you an ability to add listeners for events when the target element intersects with the other element. Below is a simple example:
In this example we created a new observer that will detect intersection with #scrollArea element. If you don’t specify root option then it will use window.document.
“rootMargin” option is used to specify margin around root element. Values can be specified in pixels or percentages. By default is 0px.
“threshold” is a number in 0.0–1.0 range. It specifies how much of target element should intersect before firing callback. You can also set an array of values. For instance, [0.1, 0.5] fires callback when 10 and 50 percent of a target element are inside a root element. Default threshold is set to 0.
“callback” is a function that is called with arguments (entries, observer). Entries is an array of changes for each target element.
Since loading of an image can take some time, it would make sense to preload them before user is actually sees the element. To do that we setup a margin in pixboost.js library:
That means when 1% of the image will be 40 pixels below viewport then we should start loading it.
At the time of writing article all major browsers except Safari supported Intersection Observer API. You can always check updated support on caniuse.com.
We noticed a really good performance boost on pages that we infused with lazy loading. We are really encouraging our customers to try a new feature. If you have any questions feel free to contact myself on firstname.lastname@example.org.