BigPipe 学习

bigpipe创新驱动力

过去十年,现代web站点变得更加动态和内容化,交互性也逐步增强,传统的页面处理的方式却没有保持一样的速度发展,越来越不能满足用户对极致性能的追求。

传统页面的交互模型

先来看一下页面传统的交互模型:

  • 浏览器发送HTTP请求给服务器
  • 服务器解析来自客户端的请求,从存储层(缓存、数据库等)获取到数据,生成HTML页面,给客户端发送HTTP响应。
  • 客户端解析响应,开始构建DOM tree,然后开始下载CSS和JavaScript。
  • CSS下载完毕,解析CSS并继续生成DOM tree。
  • JavaScript下载完毕,被浏览器解析并执行。

传统的页面交互模型按照一定的顺序来执行的,每一个过程都是不可重叠的,即每一个过程不能在同一时间被执行。当服务器端获取数据并生成页面的时候,客户端被闲置,等待服务器端生成数据;当客户端接收到服务前端返回的页面并开始下载资源,解析页面的时候,服务器又在等待来自客户端的下一次请求。空闲时间造成资源的浪费。

如果客户端能够在服务器生成页面的时候同时能够进行资源的下载和页面的解析,在页面进行资源下载和解析的过程服务器端也能够继续生成页面,那么整体的性能将会被提升。

BigPipe 的工作方式

为了能让一个页面能够同时被客户端和服务前端同时处理,首先我们需要将一个完成的页面划分为若干小块,这些小分块被称为 pagelets。 然后通过bigpipe技术,让页面以pagelet的形式在服务前端生成并 分块 发送给客户端。
BigPipe 让页面的生成步骤拆成成一下几个步骤:

1、服务前端接收来自客户端的HTTP请求
2、从存储层获取数据。
3、生成HTML,响应给客户端。
4、浏览器解析内容,开始下载CSS,浏览器生成DOM Tree,生成CSS Rule Tree,构造 Rendering Tree, 绘制和显示元素。
5、下载和执行JavaScript。

前面三个步骤在服务前端完成,后面三个在浏览器端执行。每一个pagelet都要执行以上的全部步骤,但是bigpipe 可以让这些pagelet并行的去完成这一些步骤。

首先客户端给浏览器发送一个HTTP请求给服务器。服务器首先会生成一段不闭合的HTML片段,包含了和不闭合的标签,在head里面包含了处理后续接收到的 pageletBigPipe 库,在这里是bigpipe.js,然后发送给客户端。

javascript


  
  
  
  
  BigPipe Test
  
  


这个时候服务器就继续去生成页面的 pagelets。而客户端已经开始下载CSS和其它资源了。当服务器端生成好一个pagelet 的时候,会立即 flush 到客户端,pagelet 的格式如下:


一个 pagelet 包含了 idHTML片段依赖的CSSJavaScript 资源

在客户端,当接收到一个pagelet(此时服务端还在继续生成其它pagelet) 的时候,马上回执行 onPageletArrive 的方法,BigPipe库会根据返回的pagelet信息 立即开始下载CSS资源,下载完之后会在页面显示pagelet片段。由于JavaScript的下载和执行会阻塞页面的渲染,所以,JavaScript 下载和执行的优先级会被降低,等待所有 pagelet 全部被展示完了,JavaScript资源才会被开始下载和执行。

重复上面的步骤,直到 pagelet 全部处理完毕,这个流程就结束了,pagelet 处理的过程服务器端和客户端一直保持 同步工作状态

BigPipe 是FaceBook 在性能优化探索的过程中结合自己的业务场景提出来的一个优化手段,并在FaceBook中取得了巨大的成就,在2009年的时候,他们使用BigPipe和其它一些优化手段,成功将网站的响应速度提高了到之前的两倍。

参考资料

  • BigPipe: Pipelining web pages for high performance
  • BigPipe学习研究
  • Facebook让网站速度提升一倍的BigPipe技术分析
  • 浏览器渲染原理

你可能感兴趣的:(bigpipe)