BigPipe(FaceBook使用的页面加载技术)
理论部分:用户输入域名发送请求到服务端,服务端组合出需要的业务数据返回给客户端,这一过程是现在网页请求最基本传统的方式了。
好处:只做了一次http请求,节省了http连接资源
坏处:如果一次请求数据量过大,会比较慢,并且如果整个业务逻辑部分有一处出问题,很可能导致请求错误返回,整个页面拿不到数据甚至瘫痪。
之后局部刷新技术ajax出现了:客户端可以根据需要去向服务端发不同的请求,加载自己所需要的数据资源,这样请求之间互不影响。
好处:独立请求,可以分开加载数据,是作为分离业务逻辑,模块化的加载的好方式。
坏处:分开加载无疑增加了http请求数,特别是模块分的较多,希望都非常独立的时候,这一样势必是在浪费连接资源;要知道在单次请求数据量很小的情况下,http连接资源可能是更昂贵的代价。
可能这个时候为了更加有效利用资源facebook的大牛们用了设计者Changhao Jiang (研究电子电路的博士)设计的技术bigpipe,并应用到实地场景中。
毫无疑问,无论是整个页面一次请求还是ajax都是不优雅的,没有有效利用前端和后端之间的时间差:
这种模式有个缺陷:流程中的操作有着严格的顺序,如果前面的一个操作没有执行结束,后面的操作就不能执行,即操作之间是不能重叠。这样就没有有效利用前后端资源:
服务器生成一个页面的内容时,浏览器是空闲的,显示空白内容;而当浏览器加载渲染页面内容时,服务器又是空闲的, 时间与性能的浪费由此产生。
为了在前后端空闲时,更能有效的并行处理自己要干的事情(前端通过数据渲染页面,后端包装数据传给前端),一个理想的方式就这样诞生了:
前端发了一个请求后,后端根据前端的需要分步拿不同模块的数据,拿好一个立即丢给前端去渲染,这个时候的优势就体现出来:前端渲染后端给的第一部分数据的同时,后端在组装第二部分数据,以此类推,这个并行工作就这样展开了,直到完成所有数据的组装和渲染。对于用户来讲看到的效果就是,打开页面立即就有可看到的内容,不会因为后端数据多大或是页面发出的请求过多,卡死页面的渲染。
实践demo部分:
在js群友的帮助下找到一个可参考的测试案例:
http://my.oschina.net/hanshubo/blog/130713
代码如下:在使用队列方面没有仔细斟酌,随便找一个过来,就用了。
注意一点,就是不要把 PrintWriter 的实例对象拿到多线程里去用,否则会出莫名其妙的异常。
import java.io.IOException;
这个案例的服务端是java实现的,有多线程就是有福,不过php也不是不可以,他的模块的扩展能辅助搞定这个问题。
简单讲一下基本做法:
后端创建一个线程池,去维护前端需要的模块数的线程(有几个模块就创建几个线程),然后每个线程response write之后立即flush,这样每个线程的操作就立即返给了前端,
由于http管道只有一个,后端多线程就无法做到多线程并发去flush了,需要堵塞一个个操作或者加锁。做个猜想:如果http管道中也能相应产生多个独立的位置让多线程并发去append到指定的位置,
这样是不是就做到了,多个部分数据可以同时丢给前端。(可能理解有误)
并在前端执行操作。由于不像ajax那样单个请求前后端逻辑完全独立,在bigpipe中,设定好每个模块的顺序就是必须的了。
成功案例部分:
新浪微博:http://blog.sina.com.cn/s/blog_482611850100xpb1.html
http://v.youku.com/v_show/id_XMzUyOTgyMDY4.html
简单介绍下:
新浪微博提到了用
HTTP协议的chunked编码的方式来处理多个部分
淘宝:
[浅析]淘宝详情页的BigRender优化的最佳方式
http://www.csdn.net/article/2011-09-27/304989
参考:http://www.cnblogs.com/mofish/archive/2011/11/03/2234858.html