• A Deep Dive into Native lazy-loading for Images and Frames
  • Erk Struwe
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: Baddyo
  • Proofread by: Mcskiller

Websites today are flooded with media resources such as pictures and videos. Images account for about 50% of the average traffic on a website. However, most of these images do not make it to the user’s view because they are located outside the front page of the site page.

Looking at the title of this article and asking “What is lazy loading?” There are many articles on lazy loading at CSS-Tricks, including a very detailed guide to Lazy loading with JavaScript Tricks. In short, we are talking about a mechanism for delaying the loading of web resources, in which web content is loaded on demand or, to put it more bluntly, triggered when web content comes into view.

What’s the good of that? Compress the size of the initial page to improve loading speed; Avoid wasting network requests for content that users will never see.

If you’ve read other articles on lazy loading, you know that lazy loading has to be implemented in a variety of ways. When native HTML supports lazy loading with the loading feature, it’s a different story. Loading is currently only supported by Chrome, but is expected to be fully implemented. Chrome is currently developing and testing support for the native lazy loading feature, which is expected to be available in Chrome 77 in early September 2019.

Non-native methods

So far, we developers have had to implement lazy loading in JavaScript (either through third-party libraries or by writing it from scratch). Most lazy-loaded libraries work like this:

  • The HTML response returned by the server contains an initial, no-bandsrcCharacteristics of theimgElement so that the browser does not load any data. And the link to the picture is inimgElement, for exampledata-src.
<img data-src="https://tiny.pictures/example1.jpg" alt="...">
Copy the code
  • Then, load a lazy-loading library and run it.
<script src="LazyLoadingLibrary.js"></script>
<script>LazyLoadingLibrary.run()</script>
Copy the code
  • The lazy loading library records the user’s scrolling and tells the browser to load images that are about to roll into the user’s view. The loading mode is thedata-srcAssigns the value of the property to an otherwise emptysrcFeatures.
<img src="https://tiny.pictures/example1.jpg" data-src="https://tiny.pictures/example1.jpg" alt="...">
Copy the code

We’ve been doing lazy loading this way for a long time. But that’s not the ideal way to do it.

The obvious problem with this approach is that there are several key steps to go through in order to present a web page. There are three steps, and they have to be done in sequence:

  1. Load the initial HTML response content
  2. Loading lazy loading libraries
  3. Loading pictures

If such a lazy loading technique is applied to the front page of the picture, page flickering happens during loading, because a began to draw the page without pictures (after flashing occurs in steps 1 or 2, depending on the load of the script is defer or async), lazy loading library comes into force, picture is long overdue. It can also give users the illusion that web pages load slowly.

In addition, lazily loading libraries themselves is also a drain on bandwidth and CPU power. And don’t forget if the user disables JavaScript (it’s 2019, we don’t consider that scenario, right?). Lazy loading libraries won’t work.

Oh, and what about sites that rely on RSS for content (like CSS-Tricks)? If the original page does not load the image, the RSS version of the page will never show the image.

And so on and so forth.

Native lazy loading come to the rescue!

As mentioned earlier, the Chromium team and The Google Chrome team started with Chrome 75 and loaded the native lazy loading feature supported by loading. We’ll discuss this feature and its value later, but let’s start by enabling it in the browser.

Enable native lazy loading

Starting with Chrome 75, you can toggle two switches to manually enable lazy loading. It’s expected to be on by default starting with Chrome 77 (scheduled for Release in September 2019).

  1. Open it in Chromium or Chrome Canarychrome://flags.
  2. Search keywordslazy.
  3. Enable Enable lazy image loading and Enable lazy frame loading.
  4. Click the button in the bottom right corner of the screen to restart the browser.

Schematic diagram: The native lazy loading switch in Google Chrome

Open the JavaScript console (press F12) to see if lazy loading has been successfully enabled. If activated successfully, you will see the following warning message:

Intervention] Images loaded lazily and act with placeholder. Load events are deferred. The loading event is delayed.

Are you all set? Learn more about Loading.

Loading features

Both img and iframe elements support loading. Keep in mind that the loading feature is not a command to be rigorously executed by the browser, but rather to help the browser decide whether to lazily load images or frames.

Three values for the loading feature are described below. Below each image below, you can see a table listing the loading time of each image resource. A Range response is a request to pre-inspect parts of an image to determine the size of an image file (see detailed principles). If the column has content, the browser successfully issued the scope request.

Notice the startTime column, which shows how long the loading of the image is delayed after DOM parsing. You can use force refresh (CTRL + Shift + R) to retrigger the range request.

Default value:auto

<img src="auto-cat.jpg" loading="auto" alt="...">
<img src="auto-cat.jpg" alt="...">
<iframe src="https://css-tricks.com/" loading="auto"></iframe>
<iframe src="https://css-tricks.com/"></iframe>
Copy the code

Schematic diagram: auto loading model photo: Car

Measure/request # 1
encodedBodySize 20718 bytes
decodedBodySize 20718 bytes
transferSize 0 bytes
startTime 54 ms
requestStart 592 ms
responseStart 596 ms
responseEnd 601 ms
timeToFirstByte 4 ms
downloadDuration 5 ms

Setting loading to auto (or leaving it blank: loading=””) lets the browser decide whether to load images lazily or not. There are many factors to consider when deciding whether to be lazy, such as the platform, whether you are in The Data Saver mode, network condition, image size, whether it is an image or an iframe, and the display property of your CSS. (See here for reasons for considering these factors.)

Value of temper:eager

<img src="auto-cat.jpg" loading="eager" alt="...">
<iframe src="https://css-tricks.com/" loading="eager"></iframe>
Copy the code

Schematic diagram: Eager to load the urgent leopard figure

Measure/request # 1
encodedBodySize 24019 bytes
decodedBodySize 24019 bytes
transferSize 0 bytes
startTime 54 ms
requestStart 592 ms
responseStart 600 ms
responseEnd 605 ms
timeToFirstByte 7 ms
downloadDuration 5 ms

Eager tells the browser that the image needs to load immediately. If the load is already delayed (for example, the initial value was lazy and later changed to eager with JavaScript), the browser should load the image immediately as well.

Lazy values:lazy

<img src="auto-cat.jpg" loading="lazy" alt="...">
<iframe src="https://css-tricks.com/" loading="lazy"></iframe>
Copy the code

Schematic diagram: Lazy cat with lazy loading

Measure/request # 1
encodedBodySize 12112 bytes
decodedBodySize 12112 bytes
transferSize 0 bytes
startTime 54 ms
requestStart 593 ms
responseStart 599 ms
responseEnd 604 ms
timeToFirstByte 6 ms
downloadDuration 5 ms

Lazy tells the browser that the image should load lazily. It’s up to the browser to explain just how “lazy” lazy loading is, and the documentation states that lazy loading starts when the user scrolls the page close to the image, meaning when the image is about to come into view.

loadingPrinciple of characteristic

Unlike javascript-based lazy loading libraries, native lazy loading uses a precheck request to get the first 2048 bytes of data from an image file. Based on the pre-acquired data, the browser tries to determine the size of the image so that an invisible placeholder can be inserted in place of the full image to prevent flickering during loading.

After the first (if the image size is less than 2 KB, a precheck request is sufficient) or the second request is completed, the load event is unlistened upon the complete image being loaded. Note that the Load event may remain bound if the second request is not completed.

From now on, the number of browser requests for images is likely to double. Each image corresponds to two requests: a range request and then a complete request. Make sure your server supports HTTP Range: 0-2047 headers, and 206 (partial content) for the response status code, preventing the entire image from being sent twice.

Each user sends a large number of subsequent requests, so Web server support for the HTTP/2 protocol is becoming increasingly important.

Now let’s talk about delays. Chrome’s rendering engine Blink uses heuristic techniques to determine what should be deferred and for how long. Scott Little lays out the criteria for determining a delay strategy comprehensively in his design document. Here is a short strategy for determining the delay object:

  • Images and frames with Loading =”lazy” set on all platforms

  • The browser is Chrome in the Android system and the Data Saver mode is enabled. And meet the following conditions:

    • Set uploading="auto"loading=""
    • widthheightNone of the properties has a value less than 10 px
    • Non-javascript inserted images
  • A framework that satisfies the following conditions:

    • Set uploading="auto"loading=""
    • From a third party (different from the domain name or protocol being inserted into the page)
    • Greater than 4 pixels in width and height (to prevent lazy loading of miniature trace frames together)
    • Is not setdisplay: nonevisibility: hidden(To prevent the trace framework from being lazy loaded altogether)
    • Not positioned outside the screen area with negative coordinates

withsrcsetA responsive picture of the feature

Native lazy loading is also effective for responsive images with srCset features. The SRCset feature provides a series of image files for the browser to choose from. Depending on the user’s screen size, device pixel ratio, network status and other factors, the browser will select the image that best fits the situation. Image optimization CDNS like Tiny.Pictures can provide alternative images in real time without the need for back-end development.

<img src="https://demo.tiny.pictures/native-lazy-loading/lazy-cat.jpg" srcset="https://demo.tiny.pictures/native-lazy-loading/lazy-cat.jpg?width=400 400w, https://demo.tiny.pictures/native-lazy-loading/lazy-cat.jpg?width=800 800w" loading="lazy" alt="...">
Copy the code

Browser support

At the time of this writing, no browser supports native lazy loading by default. But as mentioned earlier, Chrome will have lazy loading enabled by default starting with version 77. In addition, no browser vendor claims to support this feature. (Edge will be an exception, as it is moving to the Chromium kernel.)

You can check for support with a few lines of JavaScript code:

if ("loading" in HTMLImageElement.prototype) {
  / / support.
} else {
  // Not supported. You may need to introduce lazy loading libraries (listed below).
}
Copy the code

See Erk Struwe (@erkstruwe) in CodePen for a code example: browser native lazy load support probe

Automatic fallback to JavaScript scheme with blurred images

Most javascripts based lazy loading libraries have one cool feature: fuzzy placeholder images (LQIP). This feature basically takes advantage of the fact that the browser will load the IMG element immediately from the beginning, even if the SRC attribute’s value is later replaced by another URL. This way, we can load a small image that is not clear when the page loads and then replace it with a full image later.

Now we can use this feature to simulate the 2 KB range request of native lazy loading in browsers that do not support lazy loading to achieve the same effect as fuzzy placeholder images.

See Erk Struwe (@erkstruwe) in CodePen for code examples: JavaScript fallback scheme for native lazy loading, and fuzzy placeholder image functionality

conclusion

I’m really excited about this new feature. The release of original lazy loading function is close at hand, can produce special effect to global Internet communication. Even if it only changes a small part of heuristic technology, I honestly still don’t understand why people aren’t paying enough attention.

Just think, the world’s most popular browser is about to apply lazy loading technology to images and frames outside the viewport, with auto becoming the default option across different Chrome platforms. Levees of traffic can overwhelm less robust sites and flood web servers with image-detection requests.

Tracking technology is next in line: assuming that the trust-laden tracking pixels and tracking frameworks don’t load, the analytics world and its surrounding industries are in a passive state. We can only hope that they don’t panic and don’t add loading=”eager” to every image. It’s a waste of time to add loading to every image. Rather, they should rewrite their code so that it can be identified by heuristic techniques to track pixels.

Web developers, data analytics managers, and operations managers should immediately check their websites to make sure that the front end supports native lazy loading and the back end supports range requests and HTTP/2 protocols.

In case the native lazy loading feature has problems, or if you want to optimize your image loading to the utmost (including automatic WebP support, fuzzy placeholder images, etc.), the image optimization CDN can help you. See Tiny.pictures for more!

reference

  • Blink engine design document on lazy loading
  • Blink engine design document on lazy loading of images
  • Blink engine design document on lazy loading of frameworks
  • Blink engine design document on image replacement
  • Chromium public bug tracking
  • Policy proposal for disabling page-wide
  • Addy Osmani’s blog on native lazy loading
  • Lazy loading in Chrome platform
  • Lazy loading by Scott Little
  • HTML standard Pull Request
  • Chrome platform status and release timeline

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.