`
limu
  • 浏览: 322302 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Facebook让网站速度提升一倍的BigPipe技术分析

阅读更多
             近来Facebook高调宣布将网站性能提高一倍,平均访问时间从5s降至2.5s,公布了名为BigPipe的优化技术的一些概况.性能提升一倍这个结果无疑是极其诱人的,如果各个网站都能应用这种技术拿到这样的结果,那BigPipe很有可能会成为匹敌Ajax的技术革新.它究竟是怎样的?会给你的应用带来这样的提升么?
             先来摘要:
             BigPipe原理:再简单不过了,这就像在餐馆吃饭,先选好桌子点好菜(确定用户布局和要展现的模块),单子下到厨房后,多个大厨就可以同时上阵(服务端并发),做好一样端上来一样吃一样(客户端并发).
             BigPipe不具备普适性:网站性能优化再发展下去也不会增加一条类似"尽量减少http数","将CSS放在页面上部"这样不加任何说明和限制的优化准则---"使用Bigpipe提高网站速度",也就是说它不可能为所有应用都带来提升,或者说bigpipe可能给你的应用带来提升,但不会像Facebook那么大.
             BigPipe适用的场合:首先,网页第一个请求时间较长( >500ms? ),在整个网页展现过程中不再是前端性能优化常说的可以忽略的10-20%.其次页面上的动态内容可以划分在多个区块内显示,且各个区块之间的关系不大,因为只是客户端和服务端并发是不够的,服务端各个数据中心也要能够并发才能最好的发挥bigpipe,各个区块的动态数据在服务端也能够通过url或cookie中的key并发获得(在facebook,整个key为userid).除了SNS外,大概搜索结果页可能可以用上,比如淘宝搜索结果页的主搜索,类目导航,相关推荐和广告可以使用BigPipe技术,不过回过头看第一个限制,如果搜索页本身很快,那带来的改进不会如Facebook明显.
             BigPipe的启示:通过上面的这些限制看到Bigpipe是Facebook量身定做的优化方案,带来的一点提示是大家可以根据自己的应用为自己的应用定制优化方案,flush,ajax,静态资源combo,动态数据combo都是性能优化的手段,如何选择要看实际情况.
             详细分析:
             之前的一篇文章"在Yslow 34 Rules之后 -- 网站性能优化思路和进展"中提到网站性能优化进入精耕细作阶段,尽可能的满足各种Rules可以保证你能获得一个性能不错网站,而更进一步的优化则需要理清优化思路,结合具体应用的实际下功夫.Facebook的BigPipe技术就是这样发展出来的一种高度契合SNS类应用的优化技术.可以这么说,网站性能优化再发展下去也不会增加一条类似"尽量减少http数","将CSS放在页面上部"这样不加任何说明和限制的优化准则---"使用Bigpipe提高网站速度",也就是说它不可能为所有应用都带来提升.我们通过分析这种技术的产生过程,分析SNS类网站页面的特点,看看和你的应用有没有匹配的地方,来确定你的应用是否应该选用这种技术.另外也可以学习Facebook性能优化的套路,仔细考虑下自己应用的特点,是不是也能爆出让人眼前一亮的方案.
             下面就开始分析Facebook网页的特点,网站性能优化的任何资料都经常见到"网页展现过程百分之八十至九十的时间消耗在了前端"这样的话,这种断言主要来自这类最常见的HTTP瀑布图,如下:

             在网页的生命周期中,到达动态服务器的数据请求往往只是第一个HTML文本请求.相对于这个HTML到达浏览器之后再引入的一系列脚本,图片等等请求以及后续的渲染过程,第一个请求所占时间相当少.所以一般而言,再怎么做服务端的优化,对于整个展现过程的加快的帮助微小.但Facebook不同,下面是我的Facebook的个人主页的首个HTTP请求时间:

             长达3.173s,刨除网络响应因素,仅接收数据阶段,时间也达到了1.65s.Facebook有慢的理由,因为SNS网站的页面是高度定制化的,每个区块的数据都需要大量的计算得来.所以对于Facebook来说,要提升整体页面响应时间,服务端的时间不得不考虑进去.如何优化?YSlow优化规则中"提早Flush"给了很好的提示."提早Flush"规则建议在</head><body>之间调用flush(),让这部分内容先输出给浏览器端,这样浏览器端可以在服务端还在生成主体HTML的同时先显示标题,同时下载<head>中的css和js文件,说到底是服务端和浏览器端并发处理页面展现.但Facebook如果仅做到这样的"提早flush",对性能的提升不会很明显.因为大量的时间消耗在<body>主体内容的生成时段.所以很自然想到需要分块flush,分块渲染.而Facebook页面恰恰可以分块:

             我们看到Facebook分块后还有一个特点,就是各个区块的信息都是动态的,而动态信息都是根据userid查询得来,各个区块之间并没有关联,"好友动态"和"书签"完全没有关系.这样的特性可以带来另一个好处,就是服务端并发,Facebook首先取到当前用户的页面定制信息,生成布局,flush出去,然后在服务端就可以根据取到的用户已定制展现模块列表,并发请求各个数据中心,这样在后台各类应用可以按照统一接口,以区块划分,去除了各系统间的耦合.
             原理再简单不过了,这就像在餐馆吃饭,先选好桌子点好菜(确定用户布局和要展现的模块),然后单子下到厨房后,多个大厨就可以同时上阵(服务端并发),做好一样端上来一样吃一样(客户端并发).这样从浏览器端到服务端,在接收数据的这1.5s左右时间之内,真正成了一个流水线.同样的那些限制条件也很好解释,吃快餐就完全没必要一盘菜取一次,每盘菜之间没什么关系.好处也显而易见,每个大厨做自己最擅长的,效率效果都会最优.
             Bigpipe作为完整技术方案的若干技术细节:
             我想任何了解flush(),chunked http,Javascript的开发者都能快速开发出Bigpipe的Demo.先输出布局HTML,包含若干pagelet(Facebook称页面区块为pagelet)的容器div.动态数据到达后输出一段inline script,里面包含响应的html串和一些配置信息等等,调用onPageletArrived()方法将html片段插入pagelet容器中.上段代码意思下:
<body>
  <div id="layout">
    <div id="mod_profile"></div>
    <div id="mod_photo"></div>
    <div id="mod_friend"></div>
  </div>
  <?php flush();?><!--首先Flush页面布局-->
  <script>
    //html string for mod_photo
  </script>
  <?php flush();?><!--Flush #mod_photo的内容-->
  <script>
    //html string for mod_profile
  </script>
  <?php flush();?><!--Flush #mod_profile的内容-->
  <script>
    //html string for mod_friend
  </script>
</body>

             这里想讨论的是,使用这种方案会引入哪些其他问题,Facebook又是如何解决的.
             脚本阻滞:
             我们知道直接在html中引入外部脚本会造成页面阻滞,即使使用无阻脚本下载的一系列方法引入外部js,但因为JS单线程,当这些脚本load进来之后运行时也会发生阻滞.因为Facebook页面多样,依赖脚本大小不一,这些阻滞会对页面的快速展现造成影响.
             Facebook做法是在ondomready之前只在头部输出一个很小的外部脚本,作为bigpipe的支撑.其余所有模块如果依赖外部脚本(比如某一模块需要日历控件支持),都会在domready事件之后加载.这样做即保证了所有页面所有模块都能在domready前快速形成展现,又可以保证无脚本阻滞的快速的domready时间.
             最快可交互时间:
             domready再快也至少是在页面第一个使用bigpipe输出的chunked的http请求完成之后,对于Facebook来说,这很可能是2秒之后了.那在这2s期间,如果只是页面展现了而不能交互(点击日历无反应),那方案依然不够完美.
             Facebook的做法是,在domready后所依赖脚本已被加载之前,点击行为将会生成一个额外的脚本请求,只将这个点击所依赖的脚步预先load进来.这样保证了最快的可交互时间.Facebook在另一篇文章中对这个技术进行了详细的描述.
             Bigpipe原理简单,实现不复杂,但Facebook却用了1年的时间才形成完备的解决方案.生成方案需要时间,而解决随之而来的脚本阻滞,保障最快交互时间等等问题也会消耗大量时间.
             总结一下:
             Bigpipe在Facebook获得巨大成功,我想在于对细节的深度挖掘.如果第一个请求时间不用那么长,那相当于去吃麦当劳还分两次拿薯条和汉堡.如果服务端不能并发,那肯定达不到如此好的优化效果.如果不排除外联脚本的下载和运行阻滞带来的不确定性,也得不到如此高的展现速度.同时如果不对domready前的click按需加载处理,可交互性会大打折扣.当然Facebook可能还有更多我们不知道的类似的技术细节,所有这些细节联合起来,才能得到这样漂亮的结果.
             系统优化是个浩大的工程,在Yslow Rules这类规则默认遵守之后,要想再获得突破,那只能从自身的应用出发做选最合适的方案.同时Bigpipe出现不意味着Ajax过时了落伍了.页面的动态数据来自多个数据中心,那么用Bigpipe吧.如果一个页面上的动态数据可以用一个Ajax请求获得,那完全没必要用它.大多数应用第一个http请求的时间依然只用了很短的时间,所以Ajax还是主流.
  • 大小: 24.4 KB
  • 大小: 21.7 KB
  • 大小: 40.9 KB
18
0
分享到:
评论
10 楼 vvian00 2014-10-29  
  淘宝那个 bigpipe 研究的文章写的实在是模棱两可,还是楼主这篇实在。一下子全看懂了,而且毫无含糊不清和让人费解的地方。感谢!!
9 楼 静心听那雨 2014-08-24  
谢谢,很好的文章
8 楼 letch 2012-08-03  
httpwatch
7 楼 limu 2012-07-05  
mozart_cai 写道
请教博主一个问题,您文章中分析http请求的分析工具软件是什么呢?谢谢呢!

httpwatch
6 楼 mozart_cai 2012-07-04  
请教博主一个问题,您文章中分析http请求的分析工具软件是什么呢?谢谢呢!
5 楼 limu 2012-05-15  
挑灯论剑 写道
"比如淘宝搜索结果页的主搜索,类目导航,相关推荐和广告可以使用BigPipe技术"
请问楼主 类目导航是和主搜索结果息息相关的,类目导航的信息为什么不和主搜索list信息一起取出来,而要再去取一次呢?

首先不是类似ajax的异步再取一次,是一个http请求的不同chunk输出的.
另外类目导航信息和主搜索确实是相关的,但是他们都是靠用户输入的搜索词检索的.
也就是说搜iphone,是通过这个词分别检索出list和类目.
所以这样就可以把list和类目分开存储在不同信息节点上(不同的集群)
这样在各自不同的信息节点上方便针对list和类目两种数据的特点分别进行各自的优化处理.
4 楼 挑灯论剑 2012-05-14  
"比如淘宝搜索结果页的主搜索,类目导航,相关推荐和广告可以使用BigPipe技术"
请问楼主 类目导航是和主搜索结果息息相关的,类目导航的信息为什么不和主搜索list信息一起取出来,而要再去取一次呢?
3 楼 ystring 2011-10-18  
请问楼主,可以提供下PPT嘛,您提供的下载地址,我下载总断。charyong@qq.com
2 楼 limu 2011-08-25  
daur 写道
感谢楼主的分享,受用了,有没有其他网站可以看到原文呢,大大的UP一下

要看什么原文?
1 楼 daur 2011-08-25  
感谢楼主的分享,受用了,有没有其他网站可以看到原文呢,大大的UP一下

相关推荐

    BigPipe技术java源代码

    BigPipe是由Facebook开发的一种页面加载优化技术,它的主要目的是为了提高网页的加载速度,提升用户体验。在传统的网页加载过程中,浏览器会一次性下载整个页面的所有资源,这往往导致用户需要等待较长的时间才能...

    facebook bigpipe Java版本实现

    Facebook的BigPipe是一种高效网页加载技术,旨在提升用户体验,通过分块加载页面内容来显著减少网页的加载时间。它最初由Facebook开发,并已开源。在这个Java版本的实现中,我们有机会深入理解BigPipe如何在非PHP...

    bigPipe Net

    BIGPIPE 是一种页面渲染优化技术,通过分块加载(Pagelet)和异步执行,显著提升了页面的响应速度,尤其在高并发访问的场景下效果显著。 在压缩包内的文件"BigPipe_Net"和"BigPipe"可能包含了以下内容: 1. ...

    java实现bigpipe(上)

    在 Web 应用开发中,为了提高页面加载速度和用户体验,BigPipe 技术应运而生。它最初由 Facebook 提出,目的是将一个大页面拆分成多个小的部分(称为“管道”或“页面片段”),然后逐个异步加载这些部分,从而实现...

    基于Struts2标签的BigPipe技术实现

    Facebook介绍了一个名为BigPipe的技术,这项技术可使Facebook站点的访问速度提升一倍。目前,也有一小部分文章介绍了该技术在JSP中的实现,但是这些文章只是基于Servlet的理论实现,对于JavaWeb开发者来说并不存在...

    bigpipe 基于struts2标签实现

    `BigPipe`是一种技术,最初由Facebook提出,用于提高网页加载效率,通过分割页面为多个部分并异步加载,达到类似流式传输的效果。它使得用户可以更快地看到页面的部分内容,而无需等待整个页面完全加载。在Java Web...

    BigPipe技术后端实现分享 新浪微博新版中的Bigpipe Server端的php实现 共39页.ppt

    BigPipe技术是一种优化网页加载速度的方法,最初由Facebook提出,其核心思想是将一个完整的网页分割成多个小的、独立的模块,称为Pagelet,然后逐个加载这些模块,就像流水线作业一样,从而显著减少用户等待整个页面...

    net bigPipe

    总结来说,net bigPipe 是一种强大的性能优化技术,通过分块加载和异步处理,极大地提高了网页加载速度,提升了用户体验。在实际应用中,开发者需要充分理解和掌握其原理,以便在.NET环境中有效地实现和优化。

    Asp.net MVC2.0 BigPipe假想

    ASP.NET MVC 2.0 BigPipe 假想是一种优化Web应用性能的技术,灵感来源于Facebook的BigPipe。BigPipe的主要思想是将页面加载分为多个独立的部分,这些部分可以并行加载,从而显著提高页面渲染速度,提升用户体验。在...

    NET BIGPIPE vs2010

    此技术灵感来源于Facebook的BigPipe,旨在改善用户在浏览网页时的感知速度。在.NET中实现BigPipe,主要是通过将一个大的页面响应分解为多个小的部分(称为"管道"),然后逐个发送给客户端,而不是等待所有内容准备好...

    高性能页面加载技术--BigPipe设计原理及Java简单实现

    BigPipe是一种由Facebook提出的高效页面加载策略,它通过将一个页面拆分成多个部分(或称为“管道”),并逐个异步加载这些部分,来显著加快网页的初始展现速度。在本文中,我们将探讨BigPipe的设计原理以及如何使用...

    C#实现仿新浪微博BigPipe

    BigPipe是Facebook提出的一种页面加载技术,它通过将一个网页拆分成多个小的部分或模块,然后并行加载,显著提升了用户体验,尤其是在网络带宽有限或者用户设备性能较低的情况下。 在传统的网页加载方式中,浏览器...

    webx之bigpipe

    Webx之BigPipe技术是一种优化Web页面加载性能的方法,它借鉴了Facebook的BigPipe理念,旨在提高用户体验,尤其是在处理大量动态内容的Web应用中。Webx是一个基于Java的开源Web框架,而BigPipe则是Webx框架中的一个...

    bigpipe-demo1:简单的 bigpipe 演示

    通过研究这个项目,开发者可以学习到如何在实际项目中应用BigPipe技术,提升网站的加载速度和用户体验。同时,这也是对JavaScript异步编程和DOM操作的一个很好的实践案例。对于希望优化Web应用性能的开发者来说,这...

    Facebook早期架构设计以及缓存系统

    4. **BigPipe**:为了解决页面加载速度问题,Facebook推出了BigPipe技术,它将网页分割成多个小部分并异步加载,显著提高了用户体验。 5. **数据库优化**:Facebook早期使用MySQL,但随着数据量的增长,他们引入了...

    著名网站架构设计(包括Facebook Google Amazon

    随着时间的发展,Facebook引入了“BigPipe”技术,它将网页加载分成了多个小部分,实现了按需加载,显著提高了页面加载速度。此外,Facebook还广泛使用了分布式缓存系统Memcached和NoSQL数据库HBase,以及图数据库...

    node.js实现BigPipe详解

    BigPipe是由Facebook开发的一种网页加载优化技术,旨在显著提升用户在浏览网页时的加载速度。它通过将页面分割为多个独立的部分(称为Pagelets),并利用HTTP的流式传输特性,允许浏览器逐步接收和渲染页面内容,而...

Global site tag (gtag.js) - Google Analytics