当前位置: 首页>大数据>正文

淘宝网性能优化之借鉴——webp及Bigpipe

前言

说到性能优化,我博客前面文章讲了不少,其实性能优化做的好坏,直接体现前端开发人员的水平。因此,很多面试中基本上都会提及这一点。今天主要借鉴淘宝网性能优化方式之一webp及Bigpipe 进行简单的讲解。

webp

打开淘宝网,假如你是chrome浏览器,你会发现,所有图片都是webp结尾的,淘宝网图片运用了webp。假如你是safari浏览器,看到图片就是jpg或者png了,淘宝网自动判断浏览器支持不支持webp,假如支持,则输出相应的图片格式!

看下图:


淘宝网性能优化之借鉴——webp及Bigpipe,第1张

淘宝网图片请求头。

淘宝网的流程应该也是如下的:

运用了bigpipe客户端服务器端同时渲染,图片全是异步请求。

1、判断浏览器是否支持webp

2、客户端发送请求头到服务器端,假如请求头带:

image/webp,

说明支持webp ,则服务器渲染webp格式图片,否则就是jpg或者png

如何检测平台是否支持webp格式

方法一:

function checkWebp() {    try{        return (document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0);    }catch(err) {        return  false;    }} console.log(checkWebp());   // true or false

方法二:自官网的。

// check_webp_feature://   'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.//   'callback(feature, result)' will be passed back the detection result (in an asynchronous way!)function check_webp_feature(feature, callback) {    var kTestImages = {        lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",        lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",        alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",        animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"    };    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];}

其实跟第一种方法差不多,这里提供了几种webp的图片模式,如果浏览器支持webp,那么图片的宽高会大于0,从而返回true,否则返回false.

使用方法:

第一个参数feature可以传 lossy,lossless,alpha,animation中的一个,第一个传个回调函数。获取他result。如果支持,返回ture,否则返回false。可以再谷歌和IE下试试,谷歌返回ture,IE返回false

check_webp_feature('lossless',function(feature,result){    alert(result); //true or false});

方法三:增加class

;(function(doc) {     // 给html根节点加上webps类名    function addRootTag() {        doc.documentElement.className += "webps";    }     // 判断是否有webps=A这个cookie    if (!/(^|;\s?)webps=A/.test(document.cookie)) {        var image = new Image();         // 图片加载完成时候的操作        image.onload = function() {             // 图片加载成功且宽度为1,那么就代表支持webp了,因为这张base64图是webp格式。如果不支持会触发image.error方法            if (image.width == 1) {                 // html根节点添加class,并且埋入cookie                addRootTag();                document.cookie = "webps=A; max-age=31536000; domain=haorooms.com";            }        };         // 一张支持alpha透明度的webp的图片,使用base64编码        image.src = 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==';    } else {        addRootTag();    }}(document));

原理也是一样的,不过这个比较贴近实战,就是加载一张webp图片,如果可以加载出来,那么就是支持webp,否则就是不支持。如果支持webp,那么给html加一个class 叫 webps。

方法四:

var isSupportWebp = !![].map && document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0;

一行代码就可以判断浏览器支持不支持webp。

用法:

console.log(isSupportWebp);   // true or false

webp格式纯前端应用

这种方式只是纯前端的一种尝试,还是推荐和后端配合使用。

纯前端使用的话,可以如下方式:

在页面加载css之前,加载检测是否支持webp的js。如果支持,则html节点上里面有一名为webps的class。

背景图的话,我们就用写两套。一套是没有用webp的css,一套是用了webp图片的背景图。

.haorooms{    background-image: url('../images/haorooms.jpg');} .webps .haorooms{    background-image: url('../images/haorooms.webp');}

img图片也是一样,用js输出相关路径。特别适用于异步加载。

Bigpipe 技术

也是比较早的前端渲染技术了,淘宝网用了,请看文章:http://taobaofed.org/blog/2016/03/25/seller-bigpipe-coding/

Bigpipe 技术是把网页分割成多个PageLet的小块,然后分段输出到浏览器,前后端并行处理。

BigPipe的原理

BigPipe的主要思想是实现浏览器和服务器的并发执行,实现页面的异步加载,从而提高页面的访问速度。 为了达到这个目的,它首先根据页面的功能或者位置,将页面分成若干个模块,这些模块的名字也被称为PageLet,并对这些分解的模块进行唯一的标识。然后通过Web服务器和浏览器之间建立管道,进行分段输出 (减少请求数)。

下面来看一个简单的例子:

我们来看下面的代码:layout.html

<!DOCTYPE html><html><head>  <script>    var BigPipe = {      view: function(selector,temp) {        document.querySelector(selector).innerHTML= temp;      }    }  </script></head><body>    <div id="moduleA"></div>    <div id="moduleB"></div>    <div id="moduleC"></div>

服务端代码,基于express

var express = require('express');var app = express();var fs = require('fs'); app.get('/', function (req, res) {  var layoutHtml = fs.readFileSync(__dirname + "/layout.html").toString();  res.write(layoutHtml);   // setTimeout只是模拟异步返回  setTimeout(function() {    res.write('<script>BigPipe.view("#moduleA","moduleA");</script>');  100);   setTimeout(function() {    res.write('<script>BigPipe.view("#moduleC","moduleC");</script>');  },200);   setTimeout(function() {    res.write('<script>BigPipe.view("#moduleB","moduleB");</script>');    res.write('</body></html>');  },300);   res.end();}); app.listen(3000);

关于Bigpipe,淘宝前端团队有2篇文章,讲的很细致,推荐大家一看:

1、http://taobaofed.org/blog/2016/03/25/seller-bigpipe-coding/

2、http://taobaofed.org/blog/2015/12/17/seller-bigpipe/


https://www.xamrdz.com/bigdata/7y41994734.html

相关文章: