• Scotland team
  • Author: Jason

background

Due to business requirements, the author recently needed to implement a requirement of loading a large number of images simultaneously. In the process of realizing this requirement, the author encountered many pits and summarized some optimization schemes. Here is a summary of the optimization scheme that the author uses or plans to use.

The scenario

Before describing how to solve the problem, let’s start by saying, what is the problem? My goal is to display 1~1000 images, 200~ 500K in size, on a page. The good news is these images are from local hard drives and not the Internet. (Otherwise the question becomes optimizing the network….)

Hit the pit course

Since it is not a pure front-end project, I can read the files from a local folder. And then a piece of code pops up.

    const fileList = this.props.fileList;
    return (
        <div className="list-wrapper">
            {
                fileList.map((file) => {
                    <img className="img-item" src={file.src}>
                })
            }
        <div>
    )
Copy the code

Just when THE author is happy to think that this demand is basically done, it’s time to go downstairs to add chicken legs. Harsh reality slapped me in the face. With the refresh of the web page, a pure white screen was displayed in front of me, and then I saw the pictures loading out of it bit by bit. I can not help but fell into a meditation, is the CPU can not run or memory floating? In one think, I this computer all this performance, really want to line, this customer can bear? Wrong, on this performance, did not go online before the product little sister ko me…

Scheme 1 lazy loading

This scenario must be everyone’s first reaction is lazy loading. A brief introduction to lazy loading of pictures. A common image lazy loading scheme is when a page loads and only renders images in and around the visible area of the screen. Load images that need to be displayed while the page is scrolling. For the purpose of improving efficiency (TOU) rate (LAN), the author found a relatively easy to use lazy loading library on the Internet and introduced the project. However, the situation is not good. In this scenario, the width and height of each picture is 50*50, so the number of pictures displayed on the first screen of a common 1080p device on PC is up to 400+. Even if we ignore this issue, the experience of loading images when the user scrolls the page quickly is not ok. So lazy loading is not a panacea.

Plan 2 Preloading

The first thing we need to know is that the hardware performance stays the same and CPU scheduling cannot be more aggressive. Theoretically we can’t reduce the image rendering time. So we have to find ways to adjust the image rendering way to improve the user experience. So we use preloading.

    const fileList = this.props.fileList;
    fileList.forEach((element) => {
        letimg = new Image(); img.src = element.src; Img. onload = () => {// render this image... }})Copy the code

We can also decode the image using the img.decode() method, which returns a Promise object.

Img.decode ().then(() => {// render this image... })Copy the code

With this scheme, images are loaded one after another. However, the speed of loading is really unflattering. If the user wants to see the last image, he will have to wait a long time there…

Plan three: lazy loading + preloading

As we all know, 3 = 1 + 2. So plan three is a combination of plan one and Plan two. First we load an unloaded base image (placeholder). Then we continued to preload images one by one in the way of plan 2. When the user scrolls the image, we change the next pre-rendered image to the first one in the user’s visible area. Still, the picture is not rosy. When the user’s scroll bar keeps moving down in a straight line at a constant speed, the effect is still very poor.

Put an end to the scheme

Comprehensive above several programs, basic can optimize we have optimized. So how do you continue to improve the user experience? It seems we have to start with the picture itself, right? As mentioned above, the display width and height of the picture in the requirement scenario I am facing is 50 * 50. The size of the image is 200-500K. Therefore, we can use the method of shrink image, first render a 3~ 5K size thumbnail, and then render the larger image when the user clicks on the image to see the details. In the case of thumbnail image, we use scheme 3 for optimization, and the performance can almost meet the needs of users in this scenario.

other

Of course, the above optimizations are only used by me in a particular project. We can still use methods such as progressive image enhancement, CDN caching, image compression, and setting up a separate resource server. Image loading optimization itself is also a front-end platitude, there are too many solutions in the industry. If you have a better idea, you can let me know in the comments below. Thanks for watching.