本文作者:IMWeb moonye 原文出处:IMWeb社区 未经同意,禁止转载
背景
当前网速越来越快,但是随着网页内容越来越丰富,其实我们打开网页的速度并未得到什么提升,相反,过多的内容会导致网页打开速度变慢。于是,出现了一些性能优化的方法。 1.合并文件,如css,js等 2.将js文件放在文档的底部 3.将服务器部署到离用户近的地方,如cdn技术 4.缓存技术 5.负载均衡 6.文档直出 等等
有这么多通用的方式能够适用于我们的产品中,每一种实现的技术难度不大,当我们都应用了这些技术,发现网站性能依然不那么乐观的时候,会考虑到一些非常规、适用于某些特定场景的优化技术
另一种思路
Facebook的研究科学家changhao jiang提出了一个优化方案,名字叫做bigpipe,应用了此项技术的facebook首页,访问速度提升一倍。它极大的提升了fackebook的性能。它是怎么做到的。
传统的一个打开页面的步骤
- 浏览器发送HTTP请求
- 服务器接收到HTTP请求,解析请求,从存储层拉取数据,拼接HTML,发回一个HTTP响应
- 这个请求通过网络传输到浏览器
- 浏览器解析接收到的数据,构造DOM树,下载CSS和JavaScript
- 浏览器下载了CSS之后,开始解析CSS,渲染页面
- 下载JavaScript之后,开始解析JavaScript,执行JavaScript
Bigpipe的思路
- Request parsing:服务器解析和检查http request
- Datafetching:服务器从存储层获取数据
- Markup generation:服务器生成html 标记
- Network transport : 网络传输response
- CSS downloading:浏览器下载CSS
- DOM tree construction and CSS styling:浏览器生成DOM 树,并且使用CSS
- JavaScript downloading: 浏览器下载页面引用的JS 文件
- JavaScript execution: 浏览器执行页面JS代码
看着bigpipe的步骤和普通的方式没什么区别,其实,它只是其中一个模块(pagelet)的流程而已。而一个页面是可以分解成N个模块,多个模块以流水线式的方式运行
demo
一个node实现的demo,实现基本的分块的思想 模拟服务器部分
代码语言:javascript复制http.createServer(function(request, response) {
// Write the document response.writeHead(200, {"Content-Type" : "text/html"});
response.write('<!DOCTYPE html>');
response.write('<head><script type="text/javascript">function arrived(id,text) { var b=document.getElementById(id); b = text; }</script>');
response.write("</head><body><div>Progressive Loading");
for(var i = 0; i < 6; i ) {
response.write("<div id='" i "'>" i "</div>");
}
response.write("</div>");
var down = 6;
for (i = 0; i < 6; i ) {
http.get("http://localhost:2000/?id=" i, function(res) {
res.on('data', function(chunk) {
response.write(chunk, 'binary');
});
res.on('end', function() {
console.log("down" down)
if((--down )== 0) {
response.end();
}
})
});
}
response.write("</body></html>");
}).listen(8080);
模拟请求的代码:
代码语言:javascript复制http.createServer(function(request, response) {
// Some delay upto upto 2 seconds
var delay = Math.round(Math.random() * 2000);
setTimeout(function() {
var params = url.parse(request.url, true);
var id = params.query.id;
response.writeHead(200, {"Content-Type" : "text/html"});
var content = "<span>Content of Module " id "</span>";
response.write("<script>"
"arrived('" id "', '" content "');"
"</script>");
response.end();
}, delay);
}).listen(2000);
一个框架
https://github.com/bigpipe/bigpipe
BigPipe is a radical new web framework for Node.JS. The general idea is to decompose web pages into small re-usable chunks of functionality called Pagelets and pipeline them through several execution stages inside web servers and browsers. This allows progressive rendering at the front-end and results in exceptional front-end performance.
框架会有些重,小型开发场景下可以考虑自己实现
存在的问题
1.seo 设置useagent,爬虫来的时候给完整页面(有淘宝同学说这里存在seo问题,是否有seo问题还待确认,因为本身页面是在一个请求内完成)