The image loading method that the front end must know

foreword

      Front-end picture display loading is a very important part of the website. Many website pictures take up a lot of space. The performance of the website is also a different experience for users. A good experience will increase the "happiness" of users. Nowadays, pictures on many websites often occupy a lot of resources. If the picture is too large, the loading efficiency is low, more resources are occupied, the loading display is incomplete, and the user's perception will be uncomfortable. So let us briefly understand which methods are used for front-end image loading.

Basic usage

<img src="https://img95.699pic.com/photo/50044/9004.jpg_wh300.jpg" alt="xxx">

      Generally, the images displayed on our pages are displayed with img tags. This is the most direct way, but there are also many problems. If the pictures on the current page are large, there are many pictures, and the network is not very good, then we may see that some pictures are displayed incompletely, some are displayed partially or are blank pages. Then we will take corresponding strategies to improve.

Scroll monitor loading lazy loading

The example directly monitors page scrolling for position calculation, and when the page scrolls to the corresponding position, we load the corresponding image content.

<div>
  <img class="lazy-load" src="https://source.unsplash.com/random/600" alt="">
  <img class="lazy-load" src="https://source.unsplash.com/random/700" alt="">
  <img class="lazy-load" src="https://source.unsplash.com/random/800" alt="">
  <img class="lazy-load" src="https://source.unsplash.com/random/900" alt="">
</div>
<style>
  div {
    
    
    margin-top: 350px;
  }
  .lazy-load {
    
    
    width: 200px;
    height: 150px;
  }
</style>
// 引入 lodash 库
<script src="https://cdn.bootcss.com/lodash.js/4.17.12-pre/lodash.core.min.js"></script>  
let lazyImages = [...document.querySelectorAll('.lazy-load')]
let inAdvance = 300
function lazyLoad() {
    
    
    lazyImages.forEach(image => {
    
    
        if (image.offsetTop < window.innerHeight + window.pageYOffset + inAdvance) {
    
    
            image.src = image.dataset.src;   // 替换真实图片的  URL
        }
    })
}
lazyLoad();
window.addEventListener('scroll', _.throttle(lazyLoad, 50))
window.addEventListener('resize', _.throttle(lazyLoad, 50))

Now Jingdong, Taobao and other pc malls adopt this method, by monitoring whether there are unloaded pictures in the current viewable area, and if not, they will be loaded. The following method is also a way of scrolling lazy loading.

Intersection Observer API

      Now, there is an Intersection observer interface that is convenient for us to operate. It can asynchronously observe the intersection changes between the target element and the ancestor element or the top-level file. To put it simply, in the past, we needed to write scroll monitoring event functions by ourselves. Now, this API can help us. We only need to write an observation function uniformly. Whenever the element we want to observe enters the viewport, that is, when we see it, it will Take the appropriate action. Code example:

<template>
  <div class="content">
    <img
      v-for="(item, index) in arr"
      :key="index"
      src="https://bpic.51yuansu.com/pic/cover/00/19/12/57b66d41d79ad_610.jpg?x-oss-process=image/sharpen,100"
      alt="网图"
      data-src="https://img95.699pic.com/photo/50044/9004.jpg_wh300.jpg"
    />
  </div>
</template>
<script lang="ts">
import {
    
    
  defineComponent,
  Directive,
  isMemoSame,
  onMounted,
  reactive,
} from "@vue/runtime-core";
export default defineComponent({
    
    
  setup() {
    
    
    const arr = new Array(30);
    onMounted(() => {
    
    
      const imgs = document.querySelectorAll("img[data-src]");
      const config = {
    
    
        rootMargin: "0px",
        threshold: 1,
      };
      let observer = new IntersectionObserver((entries, self) => {
    
    
        entries.forEach((entry) => {
    
    
          if (entry.isIntersecting) {
    
    
            let img: any = entry.target;
            let src = img.dataset.src;
            if (src) {
    
    
              img.src = src;
              //console.log(src)
              img.removeAttribute("data-src");
            }
            // 解除观察
            self.unobserve(entry.target);
          }
        });
      }, config);

      imgs.forEach((image) => {
    
    
        observer.observe(image);
      });
    });
    return {
    
    
      arr,
    };
  },
});
</script>


After running, as shown in the figure, when all the fuzzy pictures at the bottom are exposed to the field of view, it will be displayed as the blue picture above.

Chrome comes with

Enter chrome://flags/#enable-lazy-image-loading in the browser address

and set it to Enabled. The code is used as follows:

<img src="https://source.unsplash.com/random/600" alt="" lazyload="on">

AwesomeImage

AwesomeImage is a general image component that supports lazy loading/progressive loading/response loading/automatic webp, and is compatible with vue2/vue3/nuxt. The usage document
address is as follows AwesomeImage
installation method

yarn add @awesome-image/image
//或者
npm install @awesome-image/image

The reference in vue is as follows

import AsImage from '@awesome-image/image'
import '@awesome-image/image/dist/style.css'
createApp(App).use(store).use(AsImage,{
    
    
    responsive: true,//是否是响应
    progressive: true,//是否渐进加载
}).use(router).mount('#app')

References in main.ts may encounter errors, and the corresponding life cannot be found when the error content is reported, as shown in the figure:
image.png
then we can declare a declare module in the .d.ts file

declare module '@awesome-image/image';

Basic usage

  • Set image size
  • set picture style
  • A loading slot can be added as a placeholder element before loading
<style>
  .demoimage {
    
    
    width: 100%;
  }
  .loading {
    
    
    width: 100%;
    height: 100%;
    background: #eee;
  }
</style>
<template>
  <AsImage
    class="demoimage"
    :width="1280"
    :height="640"
    src="//cdn.com/image.jpg"
  >
    <template #loading>
      <div class="loading" />
    </template>
  </AsImage>
</template>

lazy loading

Lazy loading uses IntersectionObserver to load images when they enter the viewable area. We also mentioned it separately above.

  • Use the lazy (default false) attribute to control whether to enable lazy loading, use imageLazyOffset (default 0px) to set how many pixels in advance to load the image
  • If progressive loading is used at the same time, use placeholderLazyOffset (default 0px) to set how many pixels in advance to load the thumbnail image
<style>
...
</style>
<template>
  <AsImage
    class="demoimage"
    :width="1280"
    :height="640"
    :lazy="true"
    :imageLazyOffset="1000px"
    src="//cdn.com/image.jpg"
  >
    <template #loading>
      <div class="loading" />
    </template>
  </AsImage>
</template>

progressive loading

Progressive loading uses a 48px scaled image (need to be generated in advance or dynamically generated with an image service) as the placeholder, and is displayed smoothly through the fading animation when the placeholder and the original image are loaded. Supports progressive loading of images before client water injection in SSR mode.

  • The imageUrlGenerator needs to be configured for details, see Get the corresponding 48px thumbnail image
  • Use the progressive (default false) attribute to control whether progressive loading is enabled
  • Set the duration (default 1, unit second) attribute to control the duration of the fade-in animation
<template>
  <AsImage
    class="demoimage"
    :width="1280"
    :height="640"
    :progressive="true"
    src="//cdn.com/image.jpg"
  >
    <template #loading>
      <div class="loading" />
    </template>
  </AsImage>
</template>

response load

Responsive loading loads images of different sizes according to the screen width (need to be generated in advance or dynamically generated with image services)

  • ImageUrlGenerator needs to be configured for details, see Obtaining image urls of different sizes
  • Use the responsive (default false) attribute to control whether response loading is enabled
  • Use the breakpoints (default [640, 768, 1024, 1280, 1536]) property to control the optional image width
  • Use the sizes (default 100vw) attribute to control how to choose the image width

simple example

<template>
  <AsImage
    class="demoimage"
    :width="1536"
    :height="640"
    :responsive="true"
    src="//cdn.com/image.jpg"
  >
    <template #loading>
      <div class="loading" />
    </template>
  </AsImage>
</template>

Load 640, 768, 1024, 1280, 1536 size images according to the screen width, for example: when the screen width is 1000px, the width is 1024px

complex example

<template>
  <AsImage
    class="demoimage"
    :width="1440"
    :height="640"
    :responsive="true"
    :sizes="(max-width: 640px) 100vw, (max-width: 1200px) 1000px, 50vw"
    :breakpoints="[640, 1024, 1440]"
    src="//cdn.com/image.jpg"
  >
    <template #loading>
      <div class="loading" />
    </template>
  </AsImage>
</template>

Used above to represent:

  • When the screen width is less than 640px, select the image at 100% width, corresponding to breakpoints, then load the image with a width of 640px
  • When the screen width is less than 1200px, select the picture according to the width of 1000px, corresponding to the breakpoints, then load the picture with a width of 1024px
  • In other cases, select the image according to the width of 50% (in actual use, the width will be set to 50% with css), corresponding to breakpoints, then:
    • The screen width is less than 1280px and the loading width is 640px image
    • The screen width is less than 2048px and the loading width is 1024px image
    • The screen width is less than 2880px and the loading width is 1440px image

Load WebP

Some image service providers or self-developed services provide the function of automatically loading images in WebP format. For situations that do not support automatic compatibility, you can specify auto-webp as true (default false) to add the function of being compatible with WebP format. For compatible browsing The browser automatically loads webp images.

<template>
  <AsImage
    class="demoimage"
    :width="1280"
    :height="640"
    :auto-webp="true"
    src="//cdn.com/image.jpg"
  >
    <template #loading>
      <div class="loading" />
    </template>
  </AsImage>
</template>

//cdn.com/image.jpg?format=webp will be loaded as above ( see imageUrlGenerator for specific url )

Other Image Processing Parameters

  • Quanlity specifies the image quality
  • format specifies the image format
<template>
  <AsImage
    class="demoimage"
    :width="1280"
    :height="640"
    :quanlity="90"
    :format="png"
    src="//cdn.com/image.jpg"
  >
    <template #loading>
      <div class="loading" />
    </template>
  </AsImage>
</template>

//cdn.com/image.jpg?quanlity=90&format=png will be loaded as above ( see imageUrlGenerator for specific url )

awesomeImageSummary

The plug-in has many ways to load pictures, which can adapt to the processing of pictures in our project. It also loads wenGL, and interested students can go to its official website to check and learn.

Progressive image display loading

Vue uses progressive-image plug-in display

npm install progressive-image --save

Referenced in main.js

import progressive from 'progressive-image/dist/vue'; // 渐进式
import 'progressive-image/dist/index.css';//样式
 Vue.use(progressive, {
    
    
   	removePreview: true,
   	scale: true
 })

The page code is as follows

<template>
    <div class="progressive">
      <img class="preview" v-progressive="http://7xiblh.com1.z0.glb.clouddn.com/progressive/2.jpg"  src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/r2.jpg" />
    </div>
 </template>

Responsive loading srcSet

According to the size of our current screen, the corresponding image is loaded, which reduces the waste of resources. The code example is as follows:

<img src="4.jpg" srcset="3.jpg 229w,2.png 618w,1.jpg 1000w", sizes="300px">

Display the corresponding picture according to the currently set picture size, and the code on the picture. If the size is set to 300px, a 2.png image will be displayed. If the sizes are changed to 1200px, a 1.jpg image will be displayed. The order of srcset will not affect the final display result.

Background image lazy loading method

vue-lazyLoad

The plugin used in vue is vue-lazyLoad, which is used as follows

// npm or cnpm
(c)npm install vue-lazyLoad --save-dev
// yarn
yarn add vue-lazyLoad -D

Referenced in main.ts as follows

import {
    
     createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import VueLazyLoad from "vue-lazyload"
createApp(App).use(store).use(VueLazyLoad,{
    
    
    preLoad:1,//如果该参数没有就是初始全部加载 范围时0-1 是距离顶部距离多少进行加载
}).use(router).mount('#app')

The example used in the code is as follows

//html
<div class="boximag" v-lazy:background-image="require('../assets/img/1.jpeg')"></div>
//css
.boximag{
    width: 100%;
    height: 300px;
    border: 1px solid #ccc;
    background-repeat: no-repeat;
    background-size: cover;
}

The above code is the lazy loading of the background, if it is the lazy loading of the picture, the code is as follows

<img v-lazy="require('../assets/img/1.jpeg')">

By using v-lazy instead of v-bind:src, there will also be scrolling to the corresponding position for loading effect.
image.png
If the parameter preLoad is set to 0.5 in main.ts, the page picture effect is as shown above, the first picture is displayed normally, and the second The first and third pictures do not reach the middle of the current page and are displayed as empty.

vue3-lazy

There is also a vue lazy loading plugin vue3-lazy

// npm or cnpm
npm install vue3-lazy -S
// yarn
yarn add vue3-lazy

The code is quoted as follows

import lazyPlugin from 'vue3-lazy'

createApp(App)
  .use(lazyPlugin, {
    
    
    loading: require('@/assets/images/default.png'), // 图片加载时默认图片
    error: require('@/assets/images/error.png')// 图片加载失败时默认图片
  })
  .mount('#app')

Use the code example

<img v-lazy="require('../assets/img/1.jpeg')">

It is used in the same way as vue-lazyLoad in which the image tag is used, but it lacks the lazy loading method of the background image. You can use it according to your own usage scenarios.

Summarize

      There are many ways to load front-end images, and the application scenarios will be different. There are also many problems in the image loading process. In order to make our website more comfortable to use, we need to continuously optimize it. This is what our front-end must learn. There may be a lot of content I have not summarized above. If you have a better way, you can tell me, let us learn and grow together.

References

https://github.com/hilongjw/vue-lazyload
https://github.com/ustbhuangyi/vue3-lazy
https://awesome-image.vercel.app/
https://zhuanlan.zhihu.com/p/323174003

Guess you like

Origin blog.csdn.net/gaojinbo0531/article/details/129294875