What is WebP

WebP, an image format developed by Google to speed up image loading. Image compression volume is only about 2/3 of JPEG, and can save a lot of server broadband resources and data space.

Why use WebP

1. Reduce the size of image loading resources to save user traffic resources. 2

The compression ratio

As a result of image compression, the image resources after using webP image format are greatly reduced.

Iii. Webp compatibility

Results: Full Google support, android browser support starting in 4.2. There will be a significant decrease in the loading size of image resources for Android users in the page.

Four, webP in the use of major websites

Webp is widely used in Taobao.

CDN Major CDN also supports webP image output.

V. Practice in the project

In practice, webP image loading scheme is adopted for H5 active page. H5 page view address: webp.leewr.com

Overall implementation process

The technical details

How is WebP compatibility checked?

1. Determine whether webP is supported by THE JS browser

function check_webp_feature(feature, callback) {
    var kTestImages = {
        lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA".lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==".alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==".animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gc A"
    };
    var img = new Image();
    img.onload = function () {
        var result = (img.width > 0) && (img.height > 0);
        callback(feature, result);
    };
    img.onerror = function () {
        callback(feature, false);
    };
    img.src = "data:image/webp; base64," + kTestImages[feature];
}
Copy the code

2. When the browser sends a request to the server, the accept will carry image/ WebP information, and the server will determine whether webP is supported.

map $http_accept $webp_suffix {
        default   "";
        "~*webp"  ".webp";
}
Copy the code

Suffix ($webp_suffix =. Webp) in nginx This value is used to determine whether webP is supported. If cookies are supported, the front end determines whether to load webP images by detecting cookies. Set the cookie code in nginx

location / {
  if ($webp_suffix ~* webp) {
    add_header Set-Cookie 'webpAvaile=true; path= /; expires=3153600'; }}Copy the code

How is it used in development?

The root node WebPA class is used to handle image import in CSS.

(function () {
  function addRootTag() {
    var className = document.documentElement.className;
    var name = className ? ' webpa' : 'webpa';
    document.documentElement.className += name ;
  }
  if (/webpAvaile=true/.test(document.cookie)) {
    addRootTag();
    window.webpAvaile = true;
   }
})()
Copy the code

1. How does CSS background introduce images

Lees writing
.webpbg(@url) {
    background-image: url(@url);
    .webpa & {
        background-image: url('@{url}.webp'); }}Copy the code

Use it when you use it

.header{
    .webpbg('.. /image/header.jpg');
}
Copy the code
Sass writing
@mixin webpbg($url) {
    background-image: url($url);
    @at-root .webpa & {
        background-image: url($url+'.webp'); }}Copy the code

Used in SCSS files

@include webpbg('.. /image/header.jpg');
Copy the code

2. How to introduce images into HTML

HTML in the first image img

The process tells you that we wrote a cookie(webpAvaile = true) to the page. When loading the page, we obtain whether the cookie page has webpAvaile after the page header image, and set the image format through variables.

var headImg = docoment.getElementById('#headImg')
var srcUrl = headImg.getAttribute('data-url')
if ( /webpAvaile=availeable/.test(document.cookies)) {
    // Change the header address
    headImg.setAttribute('src',  srcUrl + '.webp')}else {
    headImg.setAttribute('src',  srcUrl)
}
Copy the code

So we have processed the image format of the first image SRC. However, the page may wobble because the parent elements and images are set to heights. So how to deal with it? Set the height of the image directly or the minimum height of the parent element, or a fixed height.

In HTML5, the picture tag can choose to load different pictures. Can we use the picture element to remove JS to select the format of pictures? Practice is possible. Picture compatibility in HTML5.

<picture class="img" >
    <source class="img" srcset="images/banner.jpg.webp" type="image/webp">
    <img class="img" id="headImg" src="images/banner.jpg"/>
</picture>
Copy the code
Lazy loading of images

In lazy loading, the value stored in data-URL is also changed to whether the webP format image needs to be loaded.

$('[data-url]').each(function(item, index){
    var ext = window.webpAvaile ? '.webp' : ' '
    $(this).attr('src', $(this).attr('data-url') + ext)
})
Copy the code
3. Used in page templates

Page templates may be handled differently by backend PHP, Java, Node, etc., but the idea remains the same. Check whether there is image/webp in Accept through the back end. If there is, add. Webp after the suffix of the original image format.

Velocity templates
! [] ($! {banner.recordMap.get('Picture address').value}750.x448.jpg$! {isWebp})Copy the code

How to generate webP image resources for project online?

Nginx + Lua + imageMagic create WebP images

The node implementation:
Gulp generates webP images when packaged

Through the gulP task, the image transformation library is called to generate the corresponding WebP image. In this way, the generated WebP image resources are uploaded to the server when the upload resources are packaged. Here we use a webp-Batch-convert library, the core of which is to use CwebP-bin to convert images to WebP.

var gulp = require('gulp');
var convert = require('webp-batch-convert');
gulp.task('webp'.function () {
	var res = convert.cwebp('./images'.'./images', {
		q: 80.quiet: true
	})
	console.log('total is: ' + res)
})
Copy the code
Webpack packaging uses loaders to generate WebP image resources.

A little.

Nginx technology implementation:

Implement the procedure to set cookies for WebP-enabled requests. Use Nginx to detect whether the image request exists, if not through Lua call imageMagic create webP image and return. It is important to note that nginx requires lua-supported modules to be installed. What is Lua refer here.

user  root; You need read and write permissions to run the lua create image command
#...
http {
    include       mime.types;
    server {
        listen       80;
        server_name  webp.leewr.com;
        root         /home/leewr/mono/app/public/december;
        location / {
            if ($webp_suffix ~* webp) {
                add_header Set-Cookie 'webpAvaile=true; path= /; ';
            }
        }
        location ~* ^(.+\.(jpg|png|jpeg|gif))(.webp)$ { # rematch image request in paHT /name.jpg. Webp format
            if (!-f $request_filename) { # If the image does not exist
                access_log /usr/local/nginx/logs/december.log main; Set up the log file
                set $request_filepath /home/leewr/mono/app/public/december/The $1; # Image real path variable
                set $ext $3; # set the image extension variable $ext
                content_by_lua_file lua/webp.lua; # call webp.lua in nginx/lua directory}}}}Copy the code

Now lua, the code in Lua is very simple. Execute (command) execute the convert image conversion command. Convert is the ImageMagic command. . String concatenation in Lua. Ngx.var. ext is a variable defined in nginx.

local command
command = "convert " ..ngx.var.request_filepath.. "". ngx.var.request_filepath.. ngx.var.extos.execute(command)
ngx.exec(ngx.var.request_uri)
Copy the code

See another article for more details. Nginx + Lua + ImageMagic implements WebP image clipping.

Summary: WebP images can be generated by webpack and gulp at the time of front-end packaging, and images can be automatically converted by nginx layer. Both serve the purpose. Creating images through the Nginx layer is a more systematic approach. Because when processing pictures, we may need more than simple picture format conversion. When we need to call different image sizes, different image formats in different situations, this time the front end is powerless, such as the need to support 90×90.jpg. Webp image. Webp format support is only a minor requirement for resource management. For more complex scenarios, nginx is a better choice for image conversion.

To sum up:

Flow 1. Nginx checks webP support. 3. The front-end detects the cookie to decide whether to load the WebP image. Development 1. Add WebPA support to HTML root node. 2. Lazy load image manual judgment select load WebP image format. 3. CSS uses the class of the root node to write styles. .webpbg(‘url’) or @include webpbg(‘url’)

Finally, attach all code addresses in the project github, H5 address: webp.leewr.com

Finally recommend another article, no perception upgrade support webP picture system