To find out how well our Web site is performing, we use Google’s PageSpeed Insights, where we may often see prompts like this:

At the same time, your grade will be lowered. How do you solve this problem?

Image formats

As we know, pictures generally have different formats, such as JPG and PNG, which are common to us, respectively belong to two different image formats. According to whether to compress pictures, we can divide them into:

  • No compression. Without image data compression processing, can accurately present the original picture. The BMP format is one of them.
  • Lossless compression. Compression algorithm for all the data of the image encoding compression, can ensure the quality of the picture while reducing the size of the picture. PNG is an example of this.
  • Lossy compression. The compression algorithm does not compress all the data of the image, but removes the details that the human eye cannot recognize during the compression. So lossy compression can greatly reduce the size of an image with the same image quality. The representation is JPG.

In addition to compression, there is another problem that you may often encounter — whether the image has a transparent layer. For example, the image in the previous “Build IPv6 AnyCast network behind Cloudflare” does not show a white background due to the change of background color when embedding my article. This is because images have “transparent channels (Alpha channels)”. Common image formats that support transparent channels include: PNG, PSD, JPEG XR and JPEG 2000, the latter two of which are Google’s recommended next-gen formats for images, and the most common one with no transparent channels is JPEG.

In addition to this, there is also WebP, a Google-led file format used in Telegram Stickers.

WebP

WebP’s lossy compression algorithm is based on VP8 video format’s in-frame encoding [17], and uses RIFF as a container format. [2] Therefore, it is a block-based conversion scheme for the luminance chromaticity model (YCbCr 4:2:0) with eight-bit color depth and chromaticity subsampling at a scale of 1:2. [18] Without content, the RIFF container requires only 20 bytes of overhead and can still hold additional metadata. [2] The edge length of WebP images is limited to 16,383 pixels.

On WebP’s official website, we can find that Google promotes WebP as follows:

WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller than comparable JPEG images at equivalent SSIM quality index.

To put it simply, the existence of WebP image format, so that we can show in WebP picture volume can be greatly reduced, also brought about the improvement of loading performance.

Generating a WebP image is as simple as downloading the CWebP tool provided by Google and using:

cwebp -q 70 picture_with_alpha.png -o picture_with_alpha.webp
Copy the code

The converted WebP image will be much smaller than the original image, but this is a single image, our goal is to make the site images can painlessly output in webP format, if our blog has 100+ image conversion how to operate? What if it’s more?

Smart people can figure it out — we could write a script to automate the conversion, or use some server plugin like mod_pagespeed (see the previous article: Using Nginx and mod_pagespeed to automatically convert images to WebP and output them), but these operations have their own specific limitations. Mod_pagespeed, for example, requires that images and site content be in the same directory, assuming you can compile/install/configure smoothly. And convert it by changing the URL. For example, your image address is:

<img src="picture_with_alpha.png">
Copy the code

Then the transformed picture may be:

<img src="picture_with_alpha.png.pagespeed.ic.uilK6vtMij.webp">
Copy the code

In this way, the image can be separated from the converted image, but this conversion cannot be completed on my personal blog. In order to facilitate configuration and prevent being tied to a blog platform, my blog pictures are uniformly placed on the https://blog-assets.nova.moe/ address. So mod_pagespeed doesn’t work.

Polish

In Cloudflare, Pro users can use a feature called Polish, which is described as follows:

Improve image load time by optimizing images hosted on your domain. Optionally, the WebP image codec can be used with supported clients for additional performance benefits.

When you select Serve WebP Image, the Cloudflare Image request is seamlessly converted into WebP output and has a cf-polished Header in the request Header to debug the conversion. For more information, check out Cloudflare’s post “Using Cloudflare Polish to Compress Images”.

This function of Cloudflare is very good. Because this conversion requires computing power, Polish is only available to Pro users. In order to use similar functions, I write a Server with NodeJS and name it WebP Server. Later, I rewrote it with Golang with Benny and named it WebP Server Go.

WebP Server Go

Because WebP Server and WebP Server Go function similar, and because mainly in the development of the latter, here directly introduces the Go version of WebP Server.

WebP Server Go is easy to use. Since it is written with Go, the user only needs to download a single file — webp_server, and create a config.json file, which looks like this:

{
	"HOST": "127.0.0.1"."PORT": "3333"."QUALITY": "80"."IMG_PATH": "/path/tohttps://blog-assets.nova.moe/pics"."ALLOWED_TYPES": ["jpg"."png"."jpeg"]}Copy the code

Json /path/to/config.json to run WebP Server, add Nginx reverse proxy to run WebP Server.

For example, there is a picture is https://image.nova.moe/tsuki/tsuki.jpg, the corresponding image on the server storage directory is/var/WWW/nova – image/tsuki/tsuki. JPG, then, The IMG_PATH in the config file is /var/www/nova-image, and the exported webp images are cached under exhaust/tsuki/tsuki.webp in the same directory as webp_server. Direct output for subsequent access.

One of the most important thing is – we access URL can change, no visitors access is https://image.nova.moe/tsuki/tsuki.jpg, but the image format is: image/webp, volume and reduce a lot.

In addition, for Safari users, WebP Server will choose to output the original image directly, in case the output WebP image is not displayed.

Effect

So how does this WebP Server work? Take an article called “Cars I Drove in Those Years (they)”, which contains quite a few pictures:

Before WebP Server

When the original image is output by default, the PageSpeed score is

The corresponding image request is:

After WebP Server

After using WebP Server:

It looks great, doesn’t it

Size comparison before and after conversion

10K-500K

/ webp-server-jobs 8-config config.json -prefetch 905.41s user 9.55s system 875% CPU 1:44.49 total SRC Dist num PNG 495K 40K 40881097. JPG 495K 118K 21045662.jpg 495K 94K 67888534.png 495K 73K 50136421.jpg 495K 62K 72636668.png 495K 113K 55156014.jpg 495K 78K 76671894.png 495K 59K 64709121.png 495K 67K 78336881.jpg 495K 77K 57090512.png 494K 35K 72153105.jpg 494K 64K 62457185.png 494K 39K 44892218.png 494K 96K 39599640.jpg 494K 39K 21428544.jpg 493K 76K 65293876.jpg 493K 68K 76098632.png 493K 80K 65418239.jpg 493K 119K 17900553.jpg 493K 51K 61511853.jpg 493K 123K 77984504.png 493K 56K 54667116.jpg 493K 56K 75357235.jpg 493K 67K 21085426.jpg 492K 55KCopy the code

500K-1M

14.68%

Json -prefetch 1092.50s user 7.98s system 881% CPU 2:04.81 Total SRC Dist Num 2.4g./ webp-server-jobs 8-config config.json -prefetch 1092.50s user 7.98s system 881% CPU 2:04.81 Total SRC Dist Num 2.4g 361M 3500 44937735.png 974K 74K 56343106.png 974K 49K 51320479.png 974K 73K 68346957.jpg 974K 112K 74882964.png 974K 150K 76640395.jpg 974K 75K 62034004.jpg 974K 110K 59897148.jpg 974K 147K 46287856.jpg 973K 68K 54674488.jpg 973K 111K 42265521.png 973K 51K 40261146.jpg 973K 135K 76815098.png 973K 77K 57095484.png 973K 99K 65354070.jpg 973K 206K 24130390.jpg 973K 121K 73753170.jpg 972K 106K 64066680.jpg 972K 92K 72175991.png 972K 49K 53402985.png 972K 114K 70710923.png 971K 63K 76242996.png 971K 63K 65736419.jpg 971K 728K 70095856.png 971K 91K 64284761.png 971K 53K 73907152.jpg 971K 101K 62120962.png 970K 85K 22003560.png 970K 76K 77293789.jpg 970K 116K 68647243.png 970K 46K 54618347.png 970K 59K 79602155.jpg 969K 120K 55491641.jpg 968K 119K 53473372.png 968K 45K 77569729.jpg 968K 69K 57420240.png 968K 61K 69798500.png 968K 74K 63487148.png 968K 47K 79687107.jpg 967K 164K 70081772.jpg 966K 129K 79623240.jpg 966K 133K 72535236.jpg 966K 160K 47680545.png 966K 162KCopy the code

1M-4M

9.3%

/ webp-server-jobs 8-config config.json -prefetch 1345.73s user 10.84s system 888% CPU 2:32.64 Total SRC Dist Num 3.8g PNG 4.1m 293K 66504933. PNG 4.1m 107K 78316050. PNG 4.1m 319K 74264931 PNG 4.0m 191K 71330750. PNG 4.0m 199K 78361206.png 4.0m 153K PNG 4.0M 282K 67767752. PNG 4.0M 203K PNG 4.0M 726K 77033762. PNG 4.0M 261K 73436647.jpg 4.0M 514K PNG 4.0M 202K 74379006. PNG 4.0M 300K 79274246. PNG 4.0M 191K 69701132 PNG 3.9m 298K 73117385.png 3.9m 258K 70281950.png 3.9m 314K PNG 3.9m 203K 70159814. PNG 3.9m 156K 70764048.jpg 3.9m 437KCopy the code

4M-32M

6.7%

/ webp-server-jobs 8-config config.json -prefetch 916.91s user 12.03s system 888% CPU 1:44.53 Total SRC Dist Num 3.8g PNG 32M 74975502. PNG 32M 3.0m 74902740. PNG 31M 2.6m 77032574 PNG 30M 2.3m 77298781. PNG 29M 1.4m 77959551. PNG 27M 1.5m 69987155 PNG 24M 1.6m 72379562. PNG 22M 251K 77559996. PNG 22M 1.9m 71522636 78236671.png 21M 1.7m 78033540. JPG 20M 2.7m 70906047. PNG 19M 882K 7397764.png 19M 523K PNG 17M 1.2m 71504158. PNG 17M 1.2m 76969768. PNG 17M 1.4m PNG 17M 1.4m 69821163. PNG 16M 1.1m 70050613.png 16M 1.1m 76559411.png 15M 1.7m PNG 15M 1.4m 78188732. PNG 15M 1.4m 73355141. PNG 15M 589K 75977096. PNG 15M 1.4m PNG 14M 1.2m 79663534. PNG 13M 1.2m 76539246.png 13M 1.2m 70598104.png 13M 840K 78348611.jpg 13M 2.7mCopy the code

In other words, the compression ratio of most images will remain below 20%, and the larger the original image, the smaller the converted file will be. In other words, it used to take 10 seconds to download a 10 Megabyte image. With WebP Server Go, it only takes 1 second because the image is only about 1 Megabyte.

Official website with download

  • Official website: webp.sh
  • Open source address: WebP Server Go
  • GitHub Release

Refer to the reading

  • Make site images load faster – introduce WebP Server to seamlessly convert images to WebP
  • Remember an “unprovoked” memory change under Golang
  • WebP Server in Rust
  • Personal sites seamlessly switch images to WebP
  • Halo gracefully supports WebP image output
  • Make the pictures fly oh-my-webp.sh!