图图 2. 普通实现的加载时间普通实现的加载时间
可以看到,该页面的加载时间是 21.02 秒,试问有哪个用户会忍受这么长时间的页面空白呢?
该实现方式的效果也在预料之内,表格按照文档流的顺序进行加载,也就是按照单元格的编号顺序逐个加载,直到页面全部加
载完才一口气写回到浏览器,这样用户必须等待较长的时间。
单线程方式
普通方式的用户体验很差,要想增强用户体验就可以用到单线程 BigPipe 技术。单线程的实现方式,本质上与普通方式一样,
但是不一样的是它可以将优先级高的区域提前加载,并且可以先将网页结构写回客户端,然后再显示内容,增强用户体验。本
文的单线程示例程序,单元格内容的加载顺序是可以编程设置的,不一定需要按照文档流的顺序。由于增加了客户端的
JavaScript 处理,在总时间上会略微多于普通方式,但是在用户体验效果却远远优于普通方式。当我们编程设置单元格显示顺
序按照 1-6 显示时(后半部分为展示如何设置顺序),打开 http://localhost:{your port}/BigPipeImpl/single.action,效果如图 3
所示。
图图 3. 单元格单元格 1-6 顺序的单线程加载结果顺序的单线程加载结果
可以看到,打开不久,表格的框架就显示了出来,接下来,就会逐个的显示单元格的内容,其他的单元格则显示加载状态,等
到他加载完毕,我们再通过 Firebug 查看它的加载时间,如图 4 所示。
图图 4. 单元格单元格 1-6 顺序的单线程加载时间顺序的单线程加载时间
可以看到,网页的加载时间与普通实现方式一样,但是却带来了普通实现方式不可比拟的用户体验,有时候用户只希望网页及
时的给他回馈,让用户充满希望。有人说,这用 Ajax 一样可以实现,但是请再看图 4,我们看到,浏览器发出的请求只有一
个 single.action,再没有别的请求,这大大减轻了服务器端的压力。又有人说,可以在每加载一个内容完毕的时候,执行
flush 操作。的确,这样可以实现图 3 的效果,但是,如果我想实现 6-1 的显示顺序呢,flush 就无能为力了,而用单线程
BigPipe,却可以通过简单的调整代码顺序,来改变加载顺序,6-1 顺序的显示结果如图 5 所示。
图图 5. 单元格单元格 6-1 顺序的单线程加载结果顺序的单线程加载结果
从上图我们看到,这次的加载顺序,是按照 6-1 的显示顺序,总时间不变。这个功能很重要,有时候,重要的内容在文档流的
后方,而我们想让它显示的优先级变高,那么单线程的实现方式将非常实用。
多线程方式
不管是单线程还是普通实现方式,它们加载页面所需的总时间没有减少,对于非常大的页面,缩短加载时间才是最重要的,那
么就可以使用本文介绍的多线程 BigPipe 技术了。多线程实现方式与 Facebook 的实现方式基本一致,在本文的例子中,将每
个单元格视为一个 PageLet,每个 PageLet 的内容交给单独的线程进行生成和处理,也就是说,六个 PageLet 的内容并行处
理,无需按照文档流顺序进行处理。我们打开 http://localhost:{your port}/BigPipeImpl/multi.action, 我们再次查看页面的内容加