How to optimize image traffic on mobile devices

How to optimize image traffic on mobile devices

[[171480]]

In addition to script style files, most of the traffic consumed by refreshing a page is actually downloaded pictures. A picture can easily be dozens of KB, and the traffic optimized by optimizing style and script files is actually not as large as a picture.

This article introduces how to optimize image traffic from two perspectives. The premise of image traffic optimization in this article is for mobile terminals.

webp

First of all, let's start with the image format. Webp (Google's official website) is an image format launched by Google. Its advantage is that under the same image quality, its volume is more than 25% smaller than jpg and png. Take two jpg and png images as an example:

  1. JPG http://cdn1.showjoy.com/images/c9/c9c2221942774550ad53342da23774de.jpg
  2. PNG http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png
size JPG PNG
No compression 165kb 55kb
tinypng compression 75kb 20kb
webp conversion 54kb 6.1kb

From the table, we can see that converting the image to webp format makes the image smaller than the image after tinypng compression, and the image quality is even higher than tinypng compression.

Although webp images are smaller and higher quality than png and jpg, their compatibility is only around 70% globally. (caniuse as of 20160911)

According to caniuse, all mobile Android models above 4.4 support it, but iOS does not support it at all. Our users are 55% iOS and 55% Android. Supporting webp can provide a smaller image experience for at least half of our users. And it is said that the iOS 10 system will support webp, so our products will have a higher support for webp. iOS 10 is expected to support webp

Image server supports webp conversion

Our company originally had a picture thumbnail function based on nginx+lua+graphicsmagick, and the specific usage is similar to

http://cdn1.shwojoy.com/images/34/xxxxx.png

http://cdn1.shwojoy.com/images/34/xxxxx.png.300x300.png

In order to support webp conversion, the original lua script needs to be modified to add recognition of the .webp suffix, so that it can recognize and convert domain names such as xxxxx.png.300x300.png.webp or xxxxx.png.webp.

What the nginx+lua+graphicsmagick solution actually does is that nginx intercepts the domain name, and the lua script matches the domain name suffix rules, such as 300x300.png/.webp and similar suffixes. After the matching is completed, the graphicsmagick command is called in lua to perform some image conversion, cropping and other tasks.

lua script snippet

  1. if table .isLegal(size_list) and extend == "webp"   then  
  2. command = [[/usr/ local /GraphicsMagick-1.3.25/bin/gm convert -quality 75 -density 72 +profile "*" ]] .. ngx.var.image_root .. originalUri .. " -geometry " .. area .. " " .. ngx.var.file;
  3. os.execute (command);
  4. end  

It is worth noting that graphicsmagick version 1.3.20 and above only supports webp download

Graphicsmagick can convert webp, but you still need to download and compile libwebp. Graphicsmagick supports webp tutorial

Once the image server supports webp conversion, it can convert images in webp format in real time, providing technical support for subsequent webp compatible solutions.

  • http://cdn1.showjoy.com/images/c9/c9c2221942774550ad53342da23774de.jpg
  • http://cdn1.showjoy.com/images/c9/c9c2221942774550ad53342da23774de.jpg.webp

webp compatible solution

The current method for determining whether webp is supported on the browser side is the feature detection method. According to the detection result, the value of whether webp is supported is stored in a cookie for later use where webp compatibility needs to be determined.

Feature detection script: (reference)

  1. ;( function (doc) {
  2. // Add the webps class name to the html root node
  3. function addRootTag() {
  4. doc.documentElement.className += " webpa" ;
  5. }
  6.  
  7. // Check if there is a cookie called webp_showjoy=available
  8. if (!/webp_showjoy=available/.test(document.cookie)) {
  9. var image = new Image();
  10.  
  11. // Operations when the image is loaded
  12. image.onload = function () {
  13.  
  14. // If the image is loaded successfully and the width is 1, it means that webp is supported, because this base64 image is in webp format. If it is not supported, the image.error method will be triggered
  15. if (image.width == 1) {
  16.  
  17. // Add class to the root html node and embed cookies
  18. addRootTag();
  19. document.cookie = "webp_showjoy=available; max-age=31536000; domain=" ;
  20. }
  21. };
  22.  
  23. // A webp image that supports alpha transparency, encoded using base64
  24. image.src = 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==' ;
  25. } else {
  26. addRootTag();
  27. }
  28. }(document));

If the browser supports webp format images, set the flag in the cookie and set webpaclassName on the html tag. The purpose of this classname is to be compatible with webp images in less files.

webp compatibility in less files

  1. .webpbg(@url) {
  2. background-image: url(@url);
  3. .webpa & {
  4. background-image: url( '@{url}.webp' );
  5. }
  6. }

This less code replaces the original code describing the background image in the less file.

For example, the original definition of the background image

  1. div {
  2. background-image: url(xx);
  3. }

Now the compatible solution is:

  1. div {
  2. webpbg(xxx);
  3. }

Webp images in HTML files are compatible

Our company currently uses Java's velocity to write the HTML part, and the webp images that are synchronously delivered to the page will be compatible in the following way.

  1. <img class= "slider-img" src= "$!{banner.recordMap.get('Image address').value}.750x448.jpg$!{isWebp}" >

The $!{isWebp} variable is used by the backend to determine whether the previously defined webp_showjoy=available is in the cookie requested by the browser. If yes, it returns the .webp suffix, otherwise it returns nothing.

The problem with this is that when a user browses the product page for the first time, the background judgment cookie is always false, so it is impossible for the user to return a picture with the .webp suffix when browsing for the first time.

Another situation is that when images are used in large quantities, we will use lazy loading to delay the loading of images. At this time, we can modify the lazy loading plug-in and dynamically make it compatible with webp images in the plug-in.

  1. /* Returns the address of the image based on the cookie to see if it is a webp address */
  2. function getwebpsrc (imgsrc) {
  3. var needwebp = false ,
  4. src = '' ;
  5. if (/webp_showjoy=available/.test(document.cookie)) {
  6. needwebp = true ;
  7. }
  8. src = needwebp ? imgsrc + '.webp' : imgsrc;
  9. return src;
  10. }

This completes the support of webp format images on mobile terminals. This is also one of the solutions for optimizing image traffic.

Retina compatible image flow optimization

Front-end developers should all know that images with a magnification of @2x or @3x should be used on retina screens to ensure image clarity. However, for the convenience of image cutting, some companies will uniformly cut out @2x images during the image cutting stage, regardless of whether the browsing device is a retina screen or a normal screen, @2x images will be used. There are two disadvantages to this. First, @2x images will be downsampled on non-retina screens. Although this will not affect the clarity, it will lack some sharpness. Second, compared with @1x images, @2x images are larger in size, which results in a waste of traffic and affects page opening performance.

Therefore, the correct approach is to use different sizes of images for retina screens. Image cropping has been implemented on the image server. When considering retina, webp compatibility is also required. The two together will greatly reduce the size of the image.

  1. @2x http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png.300x300.png.webp
  2. @1x http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png.150x150.png.webp

less file compatible with retina

  1. .retinabg(@file-2x; @reg-2x; @reg-1x; @type) when (isstring(@reg-2x)) {
  2.  
  3. background-image: url( "@{file-2x}.@{reg-1x}.@{type}" );
  4. .webpa & {
  5. background-image: url( '@{file-2x}.@{reg-1x}.@{type}.webp' );
  6. }
  7. @media
  8. only screen and (-webkit- min -device-pixel-ratio: 2),
  9. only screen and ( min --moz-device-pixel-ratio: 2),  
  10. only screen and (-o- min -device-pixel-ratio: 2/1),
  11. only screen and ( min -device-pixel-ratio: 2),
  12. only screen and ( min -resolution: 192dpi),
  13. only screen and ( min -resolution: 2dppx) {
  14. background-image: url( "@{file-2x}.@{reg-2x}.@{type}" );
  15. .webpa & {
  16. background-image: url( '@{file-2x}.@{reg-2x}.@{type}.webp' );
  17. }
  18. }
  19. }

To replace the original background-image: url(), you can write it as follows:

  1. .retinabg(http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png; 300x300; 150x150; png)

HTML files are retina compatible

In HTML, this solution intends to use the HTML5 feature srcset attribute.

The purpose of the secset attribute is to allow developers to specify a set of sources for an image attribute, where the sources of these images are set based on the pixel resolution of the client display.

For example, define image resources in the volecity template:

  1. <img class= "pic" src= "$!{newProduct.image}.300x300.png$!{isWebp}" srcset= "$!{newProduct.image}.150x150.png$!{isWebp} 1x, $!{newProduct.image}.300x300.png$!{isWebp} 2x" >

This image definition specifies that a 300x300 image source should be used on retina (2x) screens, and a 150x150 image source should be used on non-retina (1x) screens.

Lazy loading images in html

Since the lazy loaded images will have their src assigned in the plugin, the image URL can be modified directly in the lazy loaded plugin based on window.devicePixelRatio.

  1. /* Returns the address of the image based on the cookie to see if it is a webp address */
  2. /* Return images of different sizes based on dpr */
  3. function getwebpsrc (imgsrc) {
  4. var areaInfo = '' ;
  5. if (window.devicePixelRatio && window.devicePixelRatio <= 1) {
  6. var area = imgsrc.match(/[0-9]+x[0-9]+/);
  7. if (area) {
  8. var areaSplit = area[0].split( 'x' );
  9. areaInfo = areaSplit[0] /2 + 'x' + areaSplit[1] /2;
  10. imgsrc = imgsrc.replace (/[0-9]+x[0-9]+/, areaInfo)
  11. }
  12. }
  13. var needwebp = false ,
  14. src = '' ;
  15. if (/webp_showjoy=available/.test(document.cookie)) {
  16. needwebp = true ;
  17. }
  18. src = needwebp ? imgsrc + '.webp' : imgsrc;
  19. return src;
  20. }

Under this solution, all images must be edited with a size suffix (_num_x_num_). With the support of our image server, there is a special benefit: the image server will crop the image with the size suffix and compress it at the same time. If a browser does not support the webp format, the image will be compressed to reduce the image size as much as possible.

The srcset attribute currently has very good compatibility on mobile devices, but is not supported by Android 4.x.

Summarize

There are two solutions for image traffic optimization, one for webp image format and the other for retina. ***The following are the scenarios for writing image code:

  1. HTML synchronous image editing
    1. <img class= "pic" src= "$!{newProduct.image}.300x300.png$!{isWebp}" srcset= "$!{newProduct.image}.150x150.png$!{isWebp} 1x, $!{newProduct.image}.300x300.png$!{isWebp} 2x" >
  2. Lazy loading image writing
    1. <img class= "goods-pic j_Lazyload" data-original= "{{$value.image}}.300x300.png" src= "http://cdn1.showjoy.com/images/a5/a560e106324d4670acd11b69aee0f11f.png" >
  3. less
    1. .retinabg(http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png; 300x300; 150x150; png)
    2.  
    3. webpbg(http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png);

If you have any questions or comments about my understanding above, please feel free to chat with me privately~ Weibo-Siamese who writes front-end

<<:  Summary of Android memory leaks (with memory detection tools)

>>:  The new version of iMessage is an invisible browser in iOS 10

Recommend

E-commerce agent operation: Do you want to find an agent to operate?

1. Think outside the box of operations and look a...

Where has the coronavirus gone? Will it disappear? Experts respond

Recently, the question of "where has the new...

We are fighting a tough battle with the "alien biological army"...

Fifty years ago, in 1972, the United Nations held...

When humans were no longer apes, upright walking left behind "aftereffects"!

What are the main differences between humans and ...

The paints are not only colorful, but some are also very "heavy"

Did you know that some paints are not as glamorou...

2019 Internet Marketing Promotion Tips!

With the gradual improvement of current Internet ...

Unbelievable! First discovery of Antarctic snow…

Researchers have discovered microplastics for the...

How would life change if the Earth was flat?

A flat Earth would look very different from space...