基于Nodejs的BigPipe实现

简介

BigPipe是facebook推出的用于优化网页加载速度的技术,它突破了传统网页的加载方式,通过把网页内容进行分块,然后对这些块进行并行传输从,使得浏览器的渲染无需等到整个页面加载完毕,大大提升网页呈现速度。天猫上首页就有这种实现。

Bigpie适用于网页分块清晰,且规模达到一定程度。使用bigpipe要达到优化的效果才有意义。

实现原理


利用http1.1中的transfer-encoding:chunked头消息来进行分块传输,初始时只传输网页的骨架,待到具体分块到达后,利用js填充骨架,并加载块所需js、css等资源

已下是基于Nodejs的BigPipe的简单实现:

采用express框架,它默认发送transfer-encoding:chunked头消息

 1 var express = require('express');
 2 var app = express();
 3 
 4 app.get('/', function (req, res) {
 5     var down = 2;
 6     function end(){
 7         if(--down === 0){
 8             res.end('</body></html>');
 9         }
10     }
11 
12     //第一次输出,未闭合body标签,只引入必需的js和css等资源
13     res.write(
14         '<!doctype html>'+
15         '<html><head>' +
16         '<script>' +
17             //填充块内容并加载块所需的css,js等资源,这里只实现内容填充
18             'function onPageletLoaded(id, source){' +
19             'document.getElementById(id).innerHTML = source.content' +
20             '}' +
21         '</script>' +
22         '</head><body>' +
23             '<div id="pagelet1"></div>' +
24             '<div id="pagelet2"></div>'
25     );
26 
27     //模拟生成块所需要的时间 no.1
28     setTimeout(function(){
29         res.write('<script>onPageletLoaded("pagelet1", {content: "I am pagelet 1!", js: "", css: ""});</script>');
30         end();
31     }, 1000);
32 
33     //模拟生成块所需要的时间 no.2
34     setTimeout(function(){
35         res.write('<script>onPageletLoaded("pagelet2", {content: "I am pagelet 2!", js: "", css: ""});</script>');
36         end();
37     }, 3000);
38 });
39 
40 var server = app.listen(3000, function () {
41     var host = server.address().address;
42     var port = server.address().port;
43 
44     console.log('Example app listening at http://%s:%s', host, port);
45 });

参考

BigPipe: Pipelining web pages for high performance(out of the wall)

Using Streaming Chunked HTML to Get Node.js to Deliver More Data

原文地址:https://www.cnblogs.com/zechau/p/4680916.html