This is the 12th day of my participation in Gwen Challenge

Lazy loading of images

define

What is picture lazy loading? It’s an optimization to speed up page loading

Suppose we have a lot of images on the page, if we load all the images as soon as we enter the page, now the images are hundreds of k, it will take a long time to complete the loading, all the users run out of images are not ready to load, so there is a lazy image loading method

Picture lazy loading, that is, the page scroll down, when the picture is fast to our visual area, to load the picture, not in our visual area we do not load, this is picture lazy loading, can better save bandwidth, improve the speed of page loading.

General implementation method

The usual way to do this is to listen for scrolling events on the page, and just before scrolling to the image, replace the img SRC with the real SRC, and so on. The code for the simplified version is as follows

    // Check if it is visible
    function checkDomIsInVisibleArea(dom) {
      // Spacing, which is how much spacing in advance is considered to be in the visible area
      const distance = 100
      const rect = dom.getBoundingClientRect()
      return rect.top < window.innerHeight + distance && rect.top > -distance && rect.left < window.innerWidth + distance && rect.left > -distance
    }
    // The buffeting function
    function debounce(fn, delay = 100) {
      let timer = null
      return function (. args) {
        if (timer) clearTimeout(timer)
        timer = setTimeout(() = >{ fn(... args) }, delay) } }/ / lazy loading
    function lazyLoad() {
      const imgs = document.querySelectorAll('img')
      imgs.forEach(dom= > {
        // In the viewable area with data-src
        if (checkDomIsInVisibleArea(dom) && dom.dataset['src']) {
          dom.setAttribute('src', dom.dataset['src'])
          dom.removeAttribute('data-src')}}}// Listen for scroll events
    window.addEventListener('scroll', debounce(lazyLoad))
Copy the code

Another nATIVE-API that can also be implemented is IntersectionObserver. Let’s talk about this in detail.

IntersectionObserver

A cross-observer can asynchronously observe the cross-state of a target element with its ancestor or top-level document viewport. In short, it listens to an element that fires a callback if it is in or scrolls through the viewport.

IntersectionObserver API is asynchronous and does not trigger with rolling synchronization of target elements, so there is no need to worry about affecting webpage performance

grammar

Const Observer = new IntersectionObserver(callback[, options]) // Returns an instance of IntersectionObserver

Callback Executes this callback function if an element intersects with an ancestor element, returning two arguments

  1. Entries, including IntersectionObserverEntry array of objects

    Print IntersectionObserverEntry object

    IntersectionObserverEntry object stated below

    attribute instructions
    boundingClientRect Location information for the target element
    intersectionRatio The proportion of the target element in the viewable area
    intersectionRect Cross location information between the target element and the viewable area
    isIntersecting Whether the target element is in the viewable area
    rootBounds The location of the visible area
    target The target element
    time Record the timestamp from the time origin to where the crossover occurred, in milliseconds

options

This parameter is optional. The object type is as follows

attribute instructions
root The Element object that acts as a viewable area, the default isThe viewport of the browser
rootMargin Enlarges or diminishes the size of the visible area. The syntax is roughly the same as the margin property in the CSS. The default is0px 0px 0px 0px
threshold Specifies how much of the viewable area the target element occupies before firingcallback, can beNumbers or arrays. The default is 0, which is triggered when the listener element appears in the viewable area. The maximum value is 1, which is triggered when the entire element appears. You can also set arrays,[0, 0.25, 1], triggers a callback when entering (0%), triggers a callback when entering 25%, and triggers a callback when the entire element appears (100%)

IntersectionObserver instance method

  1. observe(Element)

    Start listening for a target element with the node of the target element

  2. unobserve(Element)

    Unlisten on a target element. The argument is the node of the target element

  3. takeRecords()

    No parameters and return all of the target element IntersectionObserverEntry array of objects

  4. Disconnect () Without any parameter, disconnects the IntersectionObserver and stops all monitoring

Image lazy loading -IntersectionObserver implementation

    // Create a cross observation instance
    const observer = new IntersectionObserver(entries= > {
      entries.forEach(item= > {
        // If you are crossing
        if (item.isIntersecting) {
          item.target.setAttribute('src', item.target.dataset['src'])
          // Cancel the listener
          observer.unobserve(item.target)
        }
      })
    }, {
      threshold: 1.
    })
    const imgs = document.querySelectorAll('img')
    // Walk through the IMGS and start listening
    imgs.forEach(item= > {
      // Start listening
      observer.observe(item)
    })
Copy the code

compatibility

The current compatibility is not very good, check the figure below, the data is from Caniuse

conclusion

IntersectionObserver is a very useful API, and lazy loading of images is only one of its applications. It can also be used for infinite scrolling, exposure buried points, and scrolling animation, etc. You can learn this API first and use it if necessary later. Thank you ~