白话BigPipe

标签: Technical Performance | 发表时间:2011-06-26 21:51 | 作者:老王 Sean Lee
出处:http://huoding.com

所谓BigPipe,指的是Facebook开发的用来改善客户端响应速度的技术。本质上讲,其实它并不是新事物,原理上等同于Yahoo在Best Practices for Speeding Up Your Web Site里提出的Flush the Buffer Early,不过BigPipe的实现更灵活,所以有必要了解一二。

我们平常浏览网页时的体验通常是串行的:浏览器发起请求,服务器收到后渲染页面,在此期间,浏览器除了等待别无选择,演示代码如下:

<?php
sleep(1);
$header = 'header';

sleep(1);
$content = 'content';

sleep(1);
$footer = 'footer';
?>
<html>
<head>
<title>test</title>
</head>
<body>

<div id="header"><?php echo $header; ?></div>

<div id="content"><?php echo $content; ?></div>

<div id="footer"><?php echo $footer; ?></div>

</body>
</html>

注:代码里用sleep模拟服务端耗时的操作。

如果我们把串行改成并行的方式呢?每当服务器生成新的内容立刻发送给浏览器,浏览器立刻渲染,不必等到接收到全部数据再处理,毫无疑问会提升用户体验,代码如下:

需要说明的是代码仅运行于Apache + Mod PHP环境,旧版本Apache可能需要关闭GZip。

<html>
<head>
<title>test</title>
</head>
<body>

<?php sleep(1); ?>
<div id="header"><?php echo str_pad('header', 1024); ?></div>
<?php ob_flush(); flush(); ?>

<?php sleep(1); ?>
<div id="content"><?php echo str_pad('content', 1024); ?></div>
<?php ob_flush(); flush(); ?>

<?php sleep(1); ?>
<div id="footer"><?php echo str_pad('footer', 1024); ?></div>
<?php ob_flush(); flush(); ?>

</body>
</html>

注:某些浏览器必须接收到一定长度的内容才开始渲染,所以代码里用到了str_pad

代码里用到ob_flushflush把页面分块刷新缓存到浏览器,此时如果使用Firebug查看响应头的话,会发现:Transfer-Encoding=chunked,如此一来浏览器就可以分块渲染了。

BigPipe在此基础上更进一步,演示代码如下:

<html>
<head>
<title>test</title>
</head>
<body>

<div id="header"></div>

<div id="content"></div>

<div id="footer"></div>

<?php ob_flush(); flush(); ?>

<?php sleep(1); $header = str_pad('header', 1024); ?>
<script>
document.getElementById("header").innerHTML = "<?php echo $header; ?>";
</script>
<?php ob_flush(); flush(); ?>

<?php sleep(1); $content = str_pad('content', 1024); ?>
<script>
document.getElementById("content").innerHTML = "<?php echo $content; ?>";
</script>
<?php ob_flush(); flush(); ?>

<?php sleep(1); $footer = str_pad('footer', 1024); ?>
<script>
document.getElementById("footer").innerHTML = "<?php echo $footer; ?>";
</script>
<?php ob_flush(); flush(); ?>

</body>
</html>

使用BigPipe,先刷新布局(Layout),然后按块(header,content,footer)刷新相应的Javascript代码,从而实现页面内容的填充。

BigPipe之所以使用Javascript渲染页面,是因为这样一来渲染页面的时候,就不会被块的位置束缚住,如果我们的服务器支持多线程,那么就可以同时处理多块内容,哪块先处理好就把哪块刷新到浏览器,即便不支持多线程,服务器也可以按照内容的重要程度分主次先后渲染,不必拘泥于HTML代码的物理顺序。此外还应注意一下BigPipe和Ajax二者的区别,对于一个分成若干个块的页面而言,如果使用Ajax的话,每一块都需要单独发送一个HTTP请求,而如果使用BigPipe的话,不管有多少块,都仅有一个HTTP请求。所以Ajax对服务器造成的压力会是BigPipe的若干倍。

提醒:BigPipe不利于SEO,应用时可通过User Agent判断请求是人还是搜索引擎,如果是人的话,则应用BigPipe渲染模式,如果是搜索引擎的话,则应用传统渲染模式。

补充:在Nginx + PHP FastCGI环境运行文中的代码,会发现无效,这是缓存造成的。在Nginx FastCGI环境下,如果数据小于fastcgi_buffers,会缓存到内存中,否则如果数据小于fastcgi_max_temp_file_size,会缓存到硬盘上。因为flush是Apache环境下才有效的函数,不适用于Nginx环境,所以唯一的出路就是想办法关闭缓存,可通过实验发现即便把fastcgi_buffers和fastcgi_max_temp_file_size都禁止了,还是没有用,所以说截至目前为止,Nginx + PHP FastCG无法实现BigPipe,相对可行的方法是通过Apache + Mod PHP实现BigPipe,而Nginx则作为代理服务器,并使用proxy_buffering关闭代理缓存。

参考:Facebook网站的Ajax化、缓存和流水线(PDF)。

相关 [白话 bigpipe] 推荐:

白话BigPipe

- Sean Lee - 火丁笔记
所谓BigPipe,指的是Facebook开发的用来改善客户端响应速度的技术. 本质上讲,其实它并不是新事物,原理上等同于Yahoo在Best Practices for Speeding Up Your Web Site里提出的Flush the Buffer Early,不过BigPipe的实现更灵活,所以有必要了解一二.

BigPipe学习研究

- maxiyun - 搜索技术博客-淘宝
技术背景 FaceBook页面加载技术. 试想这样一个场景,一个经常访问的网站,每次打开它的页面都要要花费6 秒;同时另外一个网站提供了相似的服务,但响应时间只需3 秒,那么你会如何选择呢. 数据表明,如果用户打开一个网站,等待3~4 秒还没有任何反应,他们会变得急躁,焦虑,抱怨,甚至关闭网页并且不再访问,这是非常糟糕的情况.

[译]BigPipe:高性能的“流水线技术”网页

- 小和尚 - ISD Webteam
原文地址:http://www.facebook.com/note.php?note_id=389414033919. 译文地址:http://isd.tencent.com/?p=2419. Facebook的网站速度做为最关键的公司任务之一. 在2009年,我们成功地实现了Facebook网站速度提升两倍.

基于 Struts2 标签的 BigPipe 技术实现

- bill - IBM developerWorks 中国 : 文档库
Facebook 介绍了一个名为 BigPipe 的技术,这项技术可使 Facebook 站点的访问速度提升一倍. 目前,也有一小部分文章介绍了该技术在 JSP 中的实现,但是这些文章只是基于 Servlet 的理论实现,对于 Java Web 开发者来说并不存在实际意义. 本文基于 BigPipe 的思想,开发了 BigPipe 的 JSP 实现,该技术可以实现 JSP 页面的快速加载,增强用户体验,读者不仅可以从本文了解 BigPipe 原理,还可以使用开发的 Struts2 标签进行实际的开发,相信对读者的学习和开发有很大的好处.

[译]BigPipe:高性能的“流水线技术”网页

- ~Wing~ - 互联网的那点事
原文地址:http://www.facebook.com/note.php?note_id=389414033919. 译文地址:http://isd.tencent.com/?p=2419. Facebook的网站速度做为最关键的公司任务之一. 在2009年,我们成功地实现了Facebook网站速度提升两倍.

从微博的改版谈网页重构——bigpipe中的页面构建优化

- Johnny - 互联网的那点事
题记:搞互联网的同学也许都知道一个数字——4秒,有研究表明,如果一个网站没有在4秒之内加载完成,用户就会感到焦躁不愉快,并离开这个网站(数据来自性能测试网站http://gtmetrix.com/). 网站的内容、SEO优化、用户体验. 在速度面前,也许这些都相对更次要. 所以提高网页效率,是我们在新版微博的第一目标.

白话MongoDB(一)

- Ease - 江边潮未尽,枫红一季秋
按照官方的说法,MongoDB是一种可扩展的高性能的开源的面向文档(document-oriented )的数据库,采用C++开发. 注意mongo不是mango(芒果),这个词是从humongous中截取出来的,其野心不言而明,直指海量数据存储. 和其他很多NoSQL不太一样,MongoDB背后有一个专门的商业公司在提供支持和推广,有点类似MySQL AB的模式.

白话Block Formatting Context

- MArCoRQ - UED TEAM,用户体验设计,web前端开发
一,啥是Block Formatting Context. 当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局. 一个环境中的元素不会影响到其它环境中的布局. 为了让我们有个感性的认识,举个不太合适的例子. 你可以把一个页面想象成大的集装箱,这个集装箱里装的货物就是HTML元素.