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;

import java.io.PrintWriter;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class BigPipeServlet extends HttpServlet {
 
    private static ExecutorService executor = Executors.newFixedThreadPool(50);
 
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        final ArrayBlockingQueue<String> q = new ArrayBlockingQueue<String>(6);
 
        for (int i = 0; i < 6; i++) {
            final int id = i + 1;
 
            executor.execute(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep((int) (Math.random() * 10000));
                        q.put(pagelet("content" + id, "Wohooo" + id));
                    } catch (InterruptedException e) {
                    }
                }
            });
        }
 
        response.setContentType("text/html;charset=gb2312");
        PrintWriter out = response.getWriter();
        out
                .println("<html><head>"
                        + "<script type=\"text/javascript\">function arrived(id,text) { var b=document.getElementById(id); b.innerHTML = text; }</script>"
                        + "</head><body>" + "<div>Progressive Loading");
        content(out, "content1", "content2", "content3", "content4", "content5", "content6");
        out.println("</div>");
 
        for (int i = 0; i < 6; i++) {
            try {
                out.println(q.take());
                out.flush();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
 
        out.println("</body></html>");
    }
 
    private void content(PrintWriter writer, String... contentIds) {
        for (String id : contentIds) {
            writer.println("<div id=\"" + id + "\">-</div>");
        }
    }
 
    private String pagelet(String id, String content) {
        return "<script>" + "arrived(\"" + id + "\", \"" + content + "\");" + "</script>";
    }
}

这个案例的服务端是java实现的,有多线程就是有福,不过php也不是不可以,他的模块的扩展能辅助搞定这个问题。

简单讲一下基本做法:

后端创建一个线程池,去维护前端需要的模块数的线程(有几个模块就创建几个线程),然后每个线程response write之后立即flush,这样每个线程的操作就立即返给了前端,

由于http管道只有一个,后端多线程就无法做到多线程并发去flush了,需要堵塞一个个操作或者加锁。做个猜想:如果http管道中也能相应产生多个独立的位置让多线程并发去append到指定的位置,

这样是不是就做到了,多个部分数据可以同时丢给前端。(可能理解有误)

并在前端执行操作。由于不像ajax那样单个请求前后端逻辑完全独立,在bigpipe中,设定好每个模块的顺序就是必须的了。

struts2 自定义标签实现的
https://www.ibm.com/developerworks/cn/java/j-lo-bigpipe/
注:nginx gzip打开时,out.flush无效,怀疑是数据量没达到nginx默认缓存,不会输出,只等到所有数据一起输出,
这样就达不到bipipe的目的了。

成功案例部分:

新浪微博: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

转载于:https://www.cnblogs.com/loveluluxiu/p/3403572.html

Bigpipe---FaceBook使用的页面加载技术相关推荐

  1. java bigpipe_BigPipe(FaceBook使用的页面加载技术) JAVA实现代码示例

    代码如下:在使用队列方面没有仔细斟酌,随便找一个过来,就用了. 注意一点,就是不要把 PrintWriter 的实例对象拿到多线程里去用,否则会出莫名其妙的异常. import java.io.IOE ...

  2. ios 微信浏览器 预加载_小程序页面预加载技术

    lightning-load-project 集成方式 看不效果览图的话,请看博客 https://blog.csdn.net/sinat_27612147/article/details/80802 ...

  3. img 加载 svg占位符_如何使用SVG作为占位符以及其他图像加载技术

    img 加载 svg占位符 by José M. Pérez 由JoséM.Pérez 如何使用SVG作为占位符以及其他图像加载技术 (How to use SVG as a Placeholder, ...

  4. 真是好东西!一组动感的页面加载动画效果

    如果您曾经访问过 Nicolas Zezuka 和 Active Theory 的出色的设计网站,你可能已经注意到在显示新内容之前动感的页面加载动画了.这种风格的动画效果最近非常流行,因此这篇文章想给 ...

  5. 在一个html加载多个echarts,Echarts一个页面加载多个图表及图表自适应

    Echarts一个页面加载多个图表及图表自适应 模块化加载 //入口 require.config({ paths: { echarts: 'http://echarts.baidu.com/buil ...

  6. 页面加载速度优化的12个建议

    1.合并Js文件和CSS 将JS代码和CSS样式分别合并到一个共享的文件,这样不仅能简化代码,而且在执行JS文件的时候,如果JS文件比较多,就需要进行多次"Get"请求,延长加载速 ...

  7. “懒”的妙用——浅析图片懒加载技术

    1.定义 图片懒加载是一种网页优化技术.图片作为一种网络资源,在被请求时也与普通静态资源一样,将占用网络资源,而一次性将整个页面的所有图片加载完,将大大增加页面的首屏加载时间.为了解决这种问题,通过前 ...

  8. 从输入 URL 到页面加载完的过程中都发生了什么事情 —— 网络优化篇

     转自从输入 URL 到页面加载完的过程中都发生了什么事情 -- 网络优化篇 想到这不就是我这两年来研究的东西么,于是就接受一下挑战.网上已经有很多版本的答案了.这道题可以从浏览器端,网络传输和服 ...

  9. asp.net使用httphandler打包多CSS或JS文件以加快页面加载速度

    介绍 使用许多小得JS.CSS文件代替一个庞大的JS或CSS文件来让代码获得更好的可维护性,这是一个很好的实践.但这样做反过来却损失了网站的性能.虽然你应该将你的Javascript代码写在小文件中并 ...

最新文章

  1. Angular Http
  2. 怎么更进一步学python_【百尺竿头,更进一步学Python】Python进阶课程——进程,线程和协程的区别...
  3. springMVC请求发生重复路径
  4. MFC 常用系统函数
  5. 命令行运行vbs脚本并传参数给vbs中的变量简单示例
  6. “References to generic type List should be parameterized”
  7. Linux LED驱动开发实验(直接操作寄存器 -- 实际开发很少这样做)
  8. 【数据库原理及应用】经典题库附答案(14章全)——第四章:关系系统及其优化
  9. 阿里云 AI 编辑部获 CCBN 创新奖,传媒行业解决方案背后的黑科技
  10. 【Java】数组的注意事项
  11. JVM性能分析与定位
  12. java代码实现导出Excel表格、工具ssm框架、maven、idea
  13. python测试c语言代码_numpy C语言源代码调试(一)
  14. Mac SavePanel 保存文件的GUI代码
  15. python求角度公式_Python 计算任意两向量之间的夹角方法
  16. 最近在做的一个项目,利用FFMpeg合并视频时发现的问题及解决方法
  17. 海量数据处理分析经验和技巧
  18. 论剑大数据技术,效率为王!天善智能掘金数据技术沙龙【上海站 12.09】
  19. C#中取得日期的英文缩写
  20. mysql去掉两个最高分_excel去掉两个(多个)最低分、最高分,求总(平均)分...

热门文章

  1. c语言自动按键脚本,C语言键盘控制走迷宫小游戏
  2. 表白代码c语言_这段代码怎么啦?居然瞬间引起了所有程序员网友的注意!
  3. 实现tinyc语言的扫描程序_适合编程小白的C语言设计习题,实现自动发牌程序!源码分享!...
  4. 【三分钟讲清区块链/比特币】之一:区块链入门教程
  5. 关于 命令行参数 main(int argc,char** argv)
  6. 记录sqlserver中使用变量
  7. 贝叶斯优化神经网络参数_贝叶斯超参数优化:神经网络,TensorFlow,相预测示例
  8. 得意而忘乎形:谈葛水平的水墨画
  9. 占空比50%的奇数分频
  10. MATLAB数据分析3