πŸ” static resource optimization of the overall train of thought of | πŸ”™ station and CSS

High-quality pictures can effectively attract users and give them a good experience. Therefore, with the development of the Internet, more and more products begin to use pictures to improve product experience. The size of the image relative to the rest of the page is important. The following figure shows the volume of various resources loaded on websites as of June 2019 at HTTP Archive[1] :

As you can see, the picture takes up half of the land. Similarly, in a 2018 article, it was also mentioned that the average proportion of images in the volume of a website has exceeded 50%[2]. However, as the average total number of bytes of loaded images increases, the number of image requests decreases, indicating that the quality and size of images used on websites is improving.

So, if you look at performance optimization purely in terms of the number of bytes loaded, there are a lot of times when optimizing images will yield much more traffic than optimizing JavaScript scripts and CSS style files. Let’s take a look at how to optimize image resources.

Optimize the number of requests

1.1. Sprite

Can images be merged? Of course. The most commonly used image combination scenario is Sprite [3].

There are often many small ICONS on the site. Without optimization, the most direct way is to save these small ICONS as a separate image file, and then set the background image of the corresponding element to the corresponding icon image through CSS. An important problem with this is that the page may load with many requests for small icon images at the same time, which is limited by the number of concurrent HTTP requests the browser can make. I’ve seen a page that didn’t use Sprite and had to send 20+ requests to load the icon when the front page loaded. Combining the ICONS into one big picture can achieve a huge reduction of “20+ β†’ 1”.

The core principle of Sprite image is to set different background offsets, roughly including two points:

  • The different icon elements will bebackground-urlSet to the URI of the merged Sprite image;
  • Different ICONS are set by correspondingbackground-positionTo show the corresponding icon part of the larger image.

You can make your own Sprite images using tools like Photoshop. Of course, it is recommended to integrate Sprite image generation into a front-end automation build tool, such as using Webpack-spritesmith in WebPack or gulp.spritesmith in gulp. Both are based on the Spritesmith library, which you can also integrate into your favorite build tools yourself.

1.2. Lazy loading

We know that when we visit a page, the entire page that the browser loads is actually much larger than the viewable area, which is why we came up with the concept of the “first screen”. This leads to the fact that many images are not in the first screen, so if we load them all, the user will not necessarily see the image. And the picture volume is generally not small, which is obviously a waste of flow. This is often the case with long lists of images or illustrated blogs.

The core idea of the solution is lazy image loading – try to load only the user is viewing or will view the image. The simplest implementation is to actually load the image by listening to the page scroll and judging whether the image comes into view:

function loadIfNeeded($img) {
    constbounding = $img.. getBoundingClientRect();if( getComputedStyle($img).display ! = ='none'
        && bounding.top <= window.innerHeight
        && bounding.bottom >= 0
    ) {
        $img.src = $img.dataset.src;
        $img.classList.remove('lazy'); }}// Throttle is being used here. You can throttle yourself or use Lodash
const lazy = throttle(function () {
    const $imgList = document.querySelectorAll('.lazy');
    if ($imgList.length === 0) {
        document.removeEventListener('scroll', lazy);
        window.removeEventListener('resize', lazy);
        window.removeEventListener('orientationchange', lazy);
        return;
    }
    $imgList.forEach(loadIfNeeded);
}, 200);

document.addEventListener('scroll', lazy);
window.addEventListener('resize', lazy);
window.addEventListener('orientationchange', lazy);
Copy the code

For elements on the page, just set the original SRC value to data-src, which can be set to a unified placeholder map. Note that since scrolling, zooming, and vertical (mobile) orientation of the page can change the viewable area, three listeners have been added.

Of course, this is the most traditional approach, and modern browsers provide a more advanced Intersection Observer API[4] for doing this, which allows a more efficient way to listen for elements to enter the viewport. For compatibility reasons, it is recommended to use the corresponding Polyfill in production environments.

If you want to use lazy loads, you can also use existing libraries such as aFarkas/ Lazysizes, Verlok/LazyLoad, Tuupola/LazyLoad, etc.

There are also some caveats when using lazy loading:

  • Lazy loading is not required for the first screen, and lazy loading will delay the display of images on the first screen.
  • Set a reasonable placeholder map to avoid the page “shake” after image loading.
  • Although JavaScript is not currently disabled for almost all users, it is recommended to do some backup when JavaScript is not available.

You can add a little bit more to the placeholder. For a better user experience, we can use a small, low-resolution image based on the original image as a placeholder. In this way, the volume will not increase too much, and secondly, there will be a good user experience. LQIP (Low Quality Image Placeholder)[5] is this technology. There are also automation tools for LQIP and SQIP(SVG-based LQIP) that can be used directly.

If you want to learn more about lazy image loading, here is a more detailed guide to lazy image loading [6].

1.3. Lazy loading of images in CSS

In addition to loading images of elements, images used in CSS can also be loaded lazily. The most common scenario is background-URL.

.login {
    background-url: url(/static/img/login.png);
}
Copy the code

For the style rule above, if it is not applied to a specific element, the browser will not download the image. So you can switch the className and feel free to load images lazily in CSS.

1.4. The inline base64

Another way is to turn the image into a Base64 string and return it inline to the page, replacing the value of the original URL with base64. This way, when the browser parses to this image URL, instead of requesting and downloading the image, it simply parses the Base64 string.

One drawback is that the same image becomes base64 33% larger than it would be if it were binary. Inlining the entire page also means that images that might otherwise be loaded in parallel are placed in the page request (as if they were serialized). This approach also discourages reuse of separate file caches. So using Base64 is a trade-off, often used to load CRP or small ICONS on a skeleton diagram on the front screen.

2. Reduce the image size

2.1. Use appropriate image formats

Using the right image format will not only help you reduce unnecessary traffic, but may also provide a better image experience.

Image format is a big topic, and choosing the right format [7] is good for performance optimization. So let’s summarize a little bit here.

1) Use WebP:

Consider using the WebP format on your website [8]. It outperforms traditional (JPEG/PNG) formats in both lossy and lossless compression. WebP lossless compression is 26% smaller than PNG, and WebP lossy compression is 25-34% smaller than JPEG of the same quality. WebP also supports transparency. One of the more compatible approaches is provided below.

<picture>
    <source type="image/webp" srcset="/static/img/perf.webp">
    <source type="image/jpeg" srcset="/static/img/perf.jpg">
    <img src="/static/img/perf.jpg">
</picture>
Copy the code

2) Use SVG for vector graphics scenarios:

Vector graphics like SVG are great for scaling and high fidelity situations, or for ICONS. Sometimes using SVG is smaller than using the same PNG or JPEG format.

3) Use video instead of GIF:

Video can be used when giFs are desired, with muted video replacing GIfs, where compatibility permits. Gifs are 5 to 20 times larger than video (MPEG-4) for the same effect. Smashing Magazine has an article [9] detailing how to use it.

4) Progressive JPEG:

The baseline JPEG is rendered progressively from top to bottom, like the following:

The other progressive JPEG [10] goes from fuzzy to gradually clear, making people feel smoother.

However, progressive JPEG decoding is slower than baseline JPEG, so you still need to consider CPU, network, and so on, and make trade-offs over the actual user experience.

2.2. Trade-offs of picture quality

Image compression can be generally divided into lossy compression (LOssy compression) and lossless compression. As the name implies, lossless compression will lose some image quality, lossless compression can ensure the quality of the picture under the premise of compression data size. However, lossless compression generally leads to more substantial volume reduction. When using lossy compression, we can generally specify a compression quality of 0-100. In most cases, a mass factor of 80 ~ 85 can reduce the size by 30 ~ 40% compared to a compression factor of 100. At the same time, the image effect is less affected, that is, the human eye can not distinguish the difference in quality effect.

Image compression can be handled using tools such as Imagemin, or further integrated into automated tools such as Webpack, Gulp, and Grunt.

2.3. Use appropriate size and resolution

Thanks to mobile, screen sizes are becoming more diverse. The same set of designs may need pictures of different pixel sizes on screens with different sizes and pixel ratios to ensure a good display effect; In addition, responsive design has different requirements for the optimal image size on different screens.

In the past we might have used a 400px image on a 1280px screen and a 640px screen, but it’s likely that we’ll only need a 200px image on a 640px screen. On the other hand, the popular “2x” and “3x” screens also require resources of different pixel sizes.

Fortunately, HTML5 provides srcset and Sizes attributes on the element, which let the browser select the image to display based on the screen information.

<img srcset="small.jpg 480w, large.jpg 1080w" sizes="50w" src="large.jpg" >
Copy the code

See this article [11] for specific usage.

2.4. Delete redundant image information

You may not know that many images contain non-visual metadata that can cause bulk and security risks [12]. Meta information, including the image’s DPI, camera brand, GPS at the time of shooting, etc., can result in a 15% increase in JPEG image size. At the same time, some of the privacy information may also bring security risks.

So if you don’t need it, you can use a tool like imageOptim to remove private and non-critical meta information.

2.5 SVG compression

As mentioned in 2.1., SVG can be used in appropriate scenarios. We can also do some compression for SVG. Compression involves two aspects:

First, unlike images, which are binary files, SVG is an XML text that is also suitable for gZIP compression.

Secondly, the information and data in SVG itself can be compressed. For example, using < Ellipse > saves text length compared to drawing an ellipse with . There are more points about the “compression” of information that can be optimized [13]. SVGGO is a NodeJS tool that can be integrated into our build flow to help optimize SVG. Of course, you can also use the Web services it provides.

3. The cache

Like other static resources, various caching strategies can still be used to speed up resource loading.


As an important part of modern Web application, images can not be ignored in resource occupation. You can see that the optimization measures mentioned above are accompanied by corresponding tools or libraries. Usually, we mainly focus on the optimization of CSS and JavaScript, so the concept of image optimization may be weak and the degree of automation is low. It is highly recommended to incorporate automation tools into the build process if you want to better implement image optimizations.

In addition to some of the tools above, here are two very useful automation tools for image processing: Sharp and Jimp.

Well, this is the end of our picture optimization journey, and here are the font resources.

If you like, please follow my blog or subscribe to RSS feed.


“Performance Tuning” series

  1. Bring you a full grasp of front-end performance optimization πŸš€
  2. How can caching be used to reduce remote requests?
  3. How can I speed up requests?
  4. How to speed up page parsing and processing?
  5. What is the general idea of static resource optimization?
    1. How to optimize performance for JavaScript?
    2. How to optimize the PERFORMANCE of the CSS?
    3. Graphics are good, but they can cause performance problems (this article)
    4. Do πŸ”œ fonts also need performance optimization?
    5. How to optimize performance for video?
  6. How can you avoid performance problems at run time?
  7. How can preloading improve performance?
  8. The end of the

At present, all the content has been updated to ✨ fe-performance-Journey ✨ warehouse, and the content will be synchronized to the nuggets one after another. If you want to read the content as soon as possible, you can also go directly to the repository.


The resources

  1. HTTP Archive: Page Weight Report
  2. State of the Web: Top Image Optimization Strategies
  3. CSS Sprites: What They Are, Why They’re Cool, and How To Use Them
  4. IntersectionObserver ‘s “Coming into View
  5. Mr Product, LQIP — Low Quality Image Placeholder
  6. The Complete Guide to Lazy Loading Images
  7. What Is the Right Image Format for Your Website?
  8. Using WebP Images
  9. Improve Animated GIF Performance With HTML5 Video
  10. Progressive JPEG images and related
  11. Srcset New definition of SIZES property W descriptor
  12. An Overview of Image Metadata – How It Affects Web Performance and Security
  13. Understanding and Manually Improving SVG Optimization
  14. Essential Image Optimization Guide
  15. Google Photos: A Journey to Web UI perfection
  16. Automating image optimization
  17. Lazy loading images using Intersection Observer
  18. Trust is Good, Observation is Better — Intersection Observer V2
  19. Image policies for fast load times and more