Bigpipe学习笔记和java版实现

写在开头

--这篇bigpipe的笔记早在一年前就想写了,但是一直被耽搁了。终于今天再翻看旧ppt时才想起要补上这篇博客。

本文中关于bigpipe的介绍是根据网络上的资料整理出来的(图片均来源于网络),而实现部分是博主的亲身实践。

1.什么是bigpipe

搞互联网的同学也许都知道一个数字——4秒,有研究表明,如果一个网站没有在4秒之内加载完成,用户就会感到焦躁不愉快,并离开这个网站(数据来自性能测试网站http://gtmetrix.com/)。

2010 年初的时候,Facebook 的前端性能研究小组开始了他们的优化项目,经过了六个月的努力,成功的将个人空间主页面加载耗时由原来的5 秒减少为现在的2.5 秒。这是一个非常了不起的成就,也给用户来带来了很好的体验。在优化项目中,工程师提出了一种新的页面加载技术,称之为Bigpipe。

举个例子介绍bigpipe(借张图来解释):

在饭馆点菜吃的时候,如果点了四个菜,传统的网页加载模式是把所有菜都炒好了再上桌。当用户吃上菜的时候,已经是第5s了。而运用bigpipe输出页面,是炒一个就上一个菜,用户可以先吃着,厨师再炒第二个菜。甚至可以几个菜并发同时炒。所以用户吃上第一口菜的时间可以是第1s,比传统的提前了很多。

2.Bigpipe思想与原理

BigPipe提出分块的概念,即根据页面内容位置的不同,将整个页面分成不同的块儿– 称为pagelet。该技术的设计者Changhao Jiang 是研究电子电路的博士,可能从微机上得到了启发,将众多pagelet加载的不同阶段像流水线一样在浏览器和服务器上执行,这样就做到了浏览器和服务器的并行化,从而达到重叠服务器端运行时间和浏览器端运行时间的目的。使用BigPipe 不仅可以节省时间,使加载的时间缩短,而且可以同过pagelet的分步输出,使一部分的页面内容更快的输出,从而获得更好的用户体验。

FaceBook的页面被分成了很多不同的pagelets,如图:

页面加载时间消耗图:

bigpipe流水线式加载页面图:

3.Bigpipe与传统页面渲染、ajax区别

3.1 传统页面处理过程

3.2 Ajax模块化处理过程

3.3 Bigpipe处理过程

3.4 页面加载时间对比

传统模式(BP关闭):

流水线模式(BP开启):

页面等待服务器输出的时间从248ms 降到了 70 ms,也就是说最快70ms后就可以显示部分页面效果了。

4.Bigpipe优点和适用场景

Bigpipe好处

  • 使页面分段输出,加快了页面显示,改善用户体验
  • 使页面模块化,更加便于维护
  • 每个pagelet使相互独立的,单个pagelet加载失败不会影响整个页面的显示
  • Pagelet的输出顺序可以开发人员自由控制,可以尽早的输出用户关心的模块

Bigpipe适用场景

  • 第一个请求时间较长,后端程序需要多次查询数据
  • 页面上的动态内容可以划分在多个区块内显示

5.Bigpipe实现

(1)输出示例

传统模式:

<html>
	<div id="pl_main">主要内容</div>
</html>

Bigpipe模式:

<html>
	<script scr="bigpipe.js"/>
	<div id="bigpipe_15" pageletName="pl_main">待替换内容</div>
</html>

<script>bigpipe.onPageletArrive({
"dependScripts":[],
"dependStyles":[],
"pageletId":"15",
"pageletName":"pl_main",
"htmlContent":"主要内容"
});
</script>

(2)Bigpipe实现--前端任务

  • JS/CSS拆分
  • JS/CSS加载卸载

(3)Bigpipe实现--后端任务

3.1 管理和组织Pagelets--

利用配置表/数据库管理树状结构的Pagelet(一个页面可以由1个或多个pagelet树组合而成)

eg :新浪微博pagelets结构

3.2 管理Pagelet资源依赖

利用配置表/数据库管理依赖的js和css

3.3 设计一个action/controller/servlet,将url返回的html包装成脚本格式

eg:

原动态请求url: http://test.xxx.com/test/222.html

包装后的请求url: http://test.xxx.com/bigpipe/${pageletName}.pagelet , 新页面的返回如下:

<script>${param.bigpipeCallback}({
"dependScripts":[],
"dependStyles":[],
"pageletId":"15",
"pageletName":"pl_main",
"htmlContent":"${/test/222.html返回的html内容,注意需要对单/双引号做转义!}"
});
</script>

3.4 分段输出Pagelet

利用HTTP1.1特性,实现分段输出: Transger-Encoding:chunked

输出模式:

  • Traditional模式(传统模式,不分段,一次性输出整个页面)
  • Streamline模式(分段输出,先输出页面框架和pagelet占位div,然后根据树状结构,逐个输出脚本格式的pagelet)
  • SmartStreamline模式(优化过的Streamline模式,不同点是先输出页面框架和第一个pagelet)
  • AutoAgent模式(根据UserAgent的内容自动选择输出模式,可用来针对spider/robot选择传统模式输出)

3.5 自定义bigpipe标签

下面是一个使用自定义标签,将2个pagelet组织成一个jsp页面的例子:

<html>
	<script type="text/javascript" scr="bigpipe.js"/>
	<body>
		<bigpipe:page pageName="xxxx" renderMode="autoStreamline">
			<bigpipe:pagelet pageletName="pagelet1">
				<bigpipe:param name="userId">123</bigpipe:param>
			</bigpipe:pagelet>

			<bigpipe:pagelet pageletName="pagelet2">
				<bigpipe:param name="type">111</bigpipe:param>
			</bigpipe:pagelet>
		</bigpipe:page>
	</body>
</html>

6.引用与参考资料

1).新浪微博的BigPipe后端实现技术分享

2).使用BigPipe提升浏览速度—— 流水线技术在新浪微博的实践

3).从新浪微博改版谈网页重构——bigpipe中的页面构建优化

4).Facebook创新之BigPipe:优化页面加载时间 http://www.infoq.com/cn/news/2010/08/bigpipe-facebook-optimize

5).淘宝 BigPipe学习研究:http://www.searchtb.com/2011/04/an-introduction-to-bigpipe.html

6).bigpipe的java实现:http://codemonkeyism.com/facebook-bigpipe-java/

时间: 2024-10-21 08:35:10

Bigpipe学习笔记和java版实现的相关文章

学习笔记之Java程序设计实用教程

Java程序设计实用教程 by 朱战立 & 沈伟 学习笔记之JAVA多线程(http://www.cnblogs.com/pegasus923/p/3995855.html) 国庆休假前学习了多线程,休假花了两天时间把整本书学完了.

java学习笔记3——java关键字

java学习笔记3——java关键字 虽然老师说不用刻意的去记忆,但是我还是在网上找到了非常详细的注解,再次收藏 关键字的类型表: 各个关键字的详细注解和实例,按首字母排序: 1.abstract abstract 关键字可以修改类或方法. abstract 类可以扩展(增加子类),但不能直接实例化. abstract 方法不在声明它的类中实现,但必须在某个子类中重写. -示例- public abstract class MyClass{ } public abstract String my

OpenCV学习笔记[3]Java Demo人脸识别

OpenCV学习笔记:Java Demo人脸识别 [简介] 我记得在很久以前,CSDN似乎搞过一个活动,给一个橘子林的照片,让程序计算相片里有多少个橘子.之所以对这个问题记忆犹新,是因为在专业学习初期,相比于排序遍历搜索等简单算法而言,"图像识别"算法一直是难以理解的东西,而我偏偏又痴迷于此,不管自己多么无知,对于令我迷惑的问题总是充满着解决的渴望. 通过对OpenCV的初步了解,我发现图像识别的很多问题都可以用它方便的解决,本次将是一个来自官方的人脸识别的实例,我们提供图像,使用内置

Java学习笔记(Java语言规范,API,JDK,IDE)

Java语言规范:java.sun.com/docs/books/jls 三个版本的API:J2SE J2EE J2ME 1. J2SE 客户端独立应用程序或者applet 2. J2EE 服务端应用程序 [Java Servlets&JavaServer Page] 3. J2ME 移动设备变成 JDK为Java开发提供一个开发环境(IDE) Java学习笔记(Java语言规范,API,JDK,IDE)

Jquery的DataTable插件 AJAX 服务器分页的的学习心得(java版)

首先得先引入对应的js 1.jquery.min.js  首先导入 2. File:        jquery.dataTables.min.js Version:     1.9.4     这是我使用的版本 这是  jsp 页面 关键的table  代码 <table id="fuck" class="table table-bordered data-table"> <thead> <tr> <span style=

学习笔记之Java Annotation学习总结 [ 光影人像 东海陈光剑 的博客 ]

?? 按照自己定的学习计划,今天是该写点什么了. ? 在上篇文章里提到的是JUnit的学习,其中就涉及到了一些内置的annotation,如@Test.@Ignore等.现在我就结合个人的理解谈下如何自定义自己的annotation. ? annotation能被用来为某个程序元素(类.方法.成员变量等)关联任何的信息,但annotaion不能影响程序代码的执行,无论增加.删除annotation,代码都始终如一的执行.另外,尽管一些annotation通过java的反射api方法在运行时被访问

Android学习笔记(43):Java开发SQLite程序

正如前面一文说的,SQLite多用于嵌入式开发中,但有时为了更方便的编辑数据库文件,我们也常常需要开发在电脑上运行的SQLite程序.这种情况是经常发生的,比如在我们需要把一大批的txt文件中的数据插入到一个数据库中的时候. 还好这是很简单的,所以本文我们来学习如何用Java开发SQLite程序. (1)准备工作 下载sqlite-jdbc-版本号.jar文件,放到jre\lib\ext文件夹.如我的路径是C:\Program Files\Java\jre1.8.0_77\lib\ext. (2

算法(第四版)学习笔记之java实现栈和队列(链表实现)

下压堆栈(链表实现): import java.util.Iterator; public class LinkedStack<Item> implements Iterable<Item> { public class Node { Item item; Node next; } private Node frist; private int N = 0; public boolean isEmpty() { return N == 0; } public int size()

算法(第四版)学习笔记之java实现选择排序

选择排序步骤: 1.找到数组中参与遍历比较的所有元素中的最小元素的下标: 2.将最小元素与数组中参与遍历比较的第一个元素进行交换(如果第一个元素就是最小元素的话,那么也会进行一次交换): 3.若数组中还有需要参与遍历比较的元素,则跳转到步骤1:否则排序结束. 在算法第四版中给出的所有排序均是适用于任意实现了Comparable接口的数据类型,若要将数字作为测试用例,请勿使用基本数据类型,改用Integer等实现了Comparable接口的对象. 选择排序代码如下: /** * * @author