过去十年,现代web站点变得更加动态和内容化,交互性也逐步加强,传统的页面处理的方式却没有保持同样的速度发展,愈来愈不能知足用户对极致性能的追求。javascript
先来看一下页面传统的交互模型:css
传统的页面交互模型按照必定的顺序来执行的,每个过程都是不可重叠的,即每个过程不能在同一时间被执行。当服务器端获取数据并生成页面的时候,客户端被闲置,等待服务器端生成数据;当客户端接收到服务前端返回的页面并开始下载资源,解析页面的时候,服务器又在等待来自客户端的下一次请求。空闲时间形成资源的浪费。html
若是客户端可以在服务器生成页面的时候同时可以进行资源的下载和页面的解析,在页面进行资源下载和解析的过程服务器端也可以继续生成页面,那么总体的性能将会被提高。前端
为了能让一个页面可以同时被客户端和服务前端同时处理,首先咱们须要将一个完成的页面划分为若干小块,这些小分块被称为 pagelets
。 而后经过bigpipe技术,让页面以pagelet
的形式在服务前端生成并 分块
发送给客户端。
BigPipe 让页面的生成步骤拆成成一下几个步骤:java
一、服务前端接收来自客户端的HTTP请求
二、从存储层获取数据。
三、生成HTML,响应给客户端。
四、浏览器解析内容,开始下载CSS,浏览器生成DOM Tree,生成CSS Rule Tree,构造 Rendering Tree, 绘制和显示元素。
五、下载和执行JavaScript。web
前面三个步骤在服务前端完成,后面三个在浏览器端执行。每个pagelet都要执行以上的所有步骤,可是bigpipe 可让这些pagelet并行的去完成这一些步骤。shell
首先客户端给浏览器发送一个HTTP请求给服务器。服务器首先会生成一段不闭合的HTML片断,包含了<head>和不闭合的<body>标签,在head里面包含了处理后续接收到的 pagelet
的 BigPipe
库,在这里是bigpipe.js
,而后发送给客户端。数据库
javascript<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="HandheldFriendly" content="true"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0"> <meta name="apple-mobile-web-app-capable" content="yes"> <title>BigPipe Test</title> <link rel="stylesheet" href="bigpipe.styl"> <script src="bigpipe.js"></script> </head> <body>
这个时候服务器就继续去生成页面的 pagelets
。而客户端已经开始下载CSS和其它资源了。当服务器端生成好一个pagelet 的时候,会当即 flush
到客户端,pagelet 的格式以下:浏览器
<script type="text/javascript"> big_pipe.onPageletArrive({id: “pagelet_composer”, content=<HTML>, css=[..], js=[..], …}) </script>
一个 pagelet
包含了 id
、 HTML片断
、 依赖的CSS
、JavaScript 资源
。缓存
在客户端,当接收到一个pagelet(此时服务端还在继续生成其它pagelet) 的时候,立刻回执行 onPageletArrive
的方法,BigPipe库会根据返回的pagelet信息 当即开始下载CSS资源,下载完以后会在页面显示pagelet片断。因为JavaScript的下载和执行会阻塞页面的渲染,因此,JavaScript 下载和执行的优先级会被下降,等待全部 pagelet
所有被展现完了,JavaScript资源才会被开始下载和执行。
重复上面的步骤,直到 pagelet
所有处理完毕,这个流程就结束了,pagelet
处理的过程服务器端和客户端一直保持 同步工做状态
。
BigPipe 是FaceBook 在性能优化探索的过程当中结合本身的业务场景提出来的一个优化手段,并在FaceBook中取得了巨大的成就,在2009年的时候,他们使用BigPipe和其它一些优化手段,成功将网站的响应速度提升了到以前的两倍。