基于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