BigPipe 技术细节分析
2011-10-12 18:39
253 查看
所谓BigPipe,指的是Facebook开发的用来改善客户端响应速度的技术。本质上讲,其实它并不是新事物,原理上等同于Yahoo在Best Practices for Speeding Up Your Web Site里提出的Flush the Buffer Early,不过BigPipe的实现更灵活,所以有必要了解一二。我们平常浏览网页时的体验通常是串行的:浏览器发起请求,服务器收到后渲染页面,在此期间,浏览器除了等待别无选择,演示代码如下:
注:代码里用sleep模拟服务端耗时的操作。如果我们把串行改成并行的方式呢?每当服务器生成新的内容立刻发送给浏览器,浏览器立刻渲染,不必等到接收到全部数据再处理,毫无疑问会提升用户体验,代码如下:提醒一下,代码最后运行在Apache + Mod PHP环境,旧版本Apache可能需要关闭GZip。如果是Nginx + PHP FastCGI环境,因为fastcgi_buffers的存在,运行效果会非你所愿。
注:某些浏览器必须接收到一定长度的内容才开始渲染,所以代码里用到了str_pad。代码里用到ob_flush和flush把页面分块刷新缓存到浏览器,此时如果使用Firebug查看响应头的话,会发现:Transfer-Encoding=chunked,如此一来浏览器就可以分块渲染了。BigPipe在此基础上更进一步,演示代码如下:
使用BigPipe,先刷新布局(Layout),然后按块(header,content,footer)刷新相应的Javascript代码,从而实现页面内容的填充。BigPipe之所以使用Javascript渲染页面,是因为这样一来渲染页面的时候,就不会被块的位置束缚住,如果我们的服务器支持多线程,那么就可以同时处理多块内容,哪块先处理好就把哪块刷新到浏览器,即便不支持多线程,服务器也可以按照内容的重要程度分主次先后渲染,不必拘泥于HTML代码的物理顺序。此外还应注意一下BigPipe和Ajax二者的区别,对于一个分成若干个块的页面而言,如果使用Ajax的话,每一块都需要单独发送一个HTTP请求,而如果使用BigPipe的话,不管有多少块,都仅有一个HTTP请求。所以Ajax对服务器造成的压力会是BigPipe的若干倍。注:BigPipe不利于SEO,应用时可通过User Agent判断请求是人还是搜索引擎,如果是人的话,则应用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。如果是Nginx + PHP FastCGI环境,因为fastcgi_buffers的存在,运行效果会非你所愿。
<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_flush和flush把页面分块刷新缓存到浏览器,此时如果使用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渲染模式,如果是搜索引擎的话,则应用传统渲染模式。
相关文章推荐
- BigPipe 技术细节分析
- JavaSE学习随笔(一) Cloneable接口源码分析与技术细节
- Facebook让网站速度提升一倍的BigPipe技术分析
- 关于Euclideon的"无限细节"引擎的技术分析
- 勒索病毒WannaCry深度技术分析:详解传播、感染和危害细节
- 分布式文件快速搜索-技术细节分析(开源/并行)
- 从技术上分析汤唯遭遇电信诈骗的细节
- 从技术上分析汤唯遭遇电信诈骗的细节
- 针对蓝牙PIN码的最新攻击技术细节分析
- 勒索病毒WannaCry深度技术分析——详解传播、感染和危害细节
- 针对蓝牙PIN码的最新攻击技术细节分析
- 勒索病毒WannaCry深度技术分析——详解传播、感染和危害细节
- IIS日志分析辅助小工具--技术细节篇
- 51信用卡的日志分析变迁史和技术细节
- Android系统原理与源码分析(1):利用Java反射技术阻止通过按钮关闭对话框
- [转]SQL语句优化技术分析
- Asp.Net GridView技术细节整理
- macvlan 网络结构分析 - 每天5分钟玩转 Docker 容器技术(56)
- Android涂鸦技术及刮刮乐示例分析
- 测试数据创建管理及源代码分析技术研讨会