什么是Bigview

Bigview是一个 node编写的 实现了bigpipe的 高度模块化的框架。


产生背景

Bigview 是在做机票国内tts详情页改版时编写的,下面简述下业务特点、遇到的问题以及框架期望达到的目标。

页面结构

页面由几个独立的模块组成,导航中只有实际展示的模块的链接。如下图:

深入浅出Bigview_java

业务特点

独立:模块的内容是独立的,各个模块之间没有数据、逻辑的交叉。

可选:模块根据用户订单的实际情况展示或隐藏,如:用户没有购买保险,则保险模块不展示,导航不提供到保险模块的链接。

容错:非主要信息的模块出错,不应该影响其他模块的展示。比如用户只是想在详情页查看自己的航班信息和动态,不关注其他信息。如果这时候提供保险信息的接口出现异常,没有获取到保险数据,那么会跳到错误提示页,即使我们已经取到了航班信息和动态,用户也看不到。但我们更希望,只要航班信息拿到了,就展示给用户,不要受其他不关联的模块的影响。

先到先展示:还是上面那个想查看航班信息的用户,这一次获取保险信息的接口没有异常,但是特别慢,用户就要一直看loading图标转圈,转到保险信息回来了,才能把整个页面展示出来,然后查看航班信息。如果能够在拿到航班信息的时候就直接展示给用户,就可以省掉用户等待不关注的信息返回的时间。

深入浅出Bigview_java_02

遇到问题

问题一:因为详情页面需要从多个接口获取数据,部分接口返回慢的时候,会拖慢整个页面显示的速度。

问题二:老工程的代码结构不是很清晰,不了解的人接手会很困难,修改难度大。可能只有0.5pd的工作量,理清代码结构要花上一天。

框架目标

能够提高首屏加载速度。模块之间解耦,代码结构清晰,从而提高开发效率,降低维护难度。

主要功能

提供五种渲染模式

  • 1、parallel.js 并行模式:先写布局,并行请求,但在获得所有请求的结果后再渲染。

  • 2、pipeline.js (默认)管线模式:即并行模式,先写布局,并行请求,并即时渲染。

  • 3、reduce.js 顺序模式:先写布局,按照pagelet加入顺序,依次执行,写入。

  • 4、reducerender.js:先写布局,然后顺序执行,在获得所有请求的结果后再渲染。

  • 5、render.js 一次渲染模式:即普通模式,不写入布局,所有pagelet执行完成,一次写入到浏览器。支持搜索引擎,用来支持那些不支持JS的客户端。


支持子pagelet,无线级嵌套

如:A B C D 模块无关联,A中有 a, b , c 三个部分,需要按照 a -> b -> c 的顺序执行加载,那么可以将a b c作为A的子pagelet,使用reduce模式,ABCD使用pipeline模式,解决期望多种模式混合使用的场景。

深入浅出Bigview_java_03

pagelet提供完整的生命周期

  • before

  • fetch 请求接口获取数据

  • parse 处理模块数据

  • render 组装 tpl + data

  • end


浏览器端配套bigview.js

  • 生命周期 ready , end , on pagelet arrive , on error

  • 事件 on , off , trigger

深入浅出Bigview_java_04


核心技术

Bigpipe


BigPipe是Facebook的创新研究之一,是一个重新设计的基础动态网页服务体系。大体思路是,分解网页成叫做Pagelets的小块,然后通过Web服务器和浏览器建立管道并管理他们在不同阶段的运行。

简单说,就是服务端可以把客户端的一次请求的结果 分成多次返回。

通常服务端的应答消息是整个发送的,因为消息头的Content-Length字段要标示数据的长度,客户端由此知道应答消息再哪里结束。对于动态生成的内容,在生成完全部内容前,Content-Length是未知的。

所以,传统的打开一个页面的步骤是:

  1. 浏览器发送一个HTTP请求。

  2. 服务器收到请求后解析请求,从存储层取到数据,拼合成HTML,返回响应。

  3. 响应通过网络传输到浏览器。

  4. 浏览器解析服务器返回的响应,构造DOM树,开始下载CSS和JavaScript。

  5. 浏览器解析下载好的CSS,渲染页面。

  6. 浏览器解析并执行下载的JavaScript。

而HTTP 1.1引入了分块传输编码,如果一个HTTP消息的消息头Transfer-Encoding 的值为 chunked,消息体可以由未知数量的块组成,以最后一个大小为0的块结束。所以 Bigpipe 技术的使用范围很广,应用 HTTP 1.1 协议的浏览器都可以,包括IE~

Bigpipe的思路是把一个页面分解成N个模块,为每一个模块执行下面的流程,但是多个模块可以同步处理:

  1. Request parsing:服务器解析请求。

  2. Data fetching:服务器从存储层拉取数据。

  3. Markup generation:拼合HTML。

  4. Network transport:网络传输相应。

  5. CSS downloading:浏览器下载CSS。

  6. DOM tree construction and CSS styling:浏览器构建DOM树,使用CSS。

  7. JavaScript downloading:浏览器下载引用的JavaScript。

  8. JavaScript execution:浏览器执行JavaScript。

和传统方式的比较:

深入浅出Bigview_java_05

Lerna

首先,Bigview 框架是由三个模块 bigview, biglet, bigview-cli组成的。

管理这三个模块,一种方法是分别给这三个模块建repository,带来的问题就是,当其中一个模块改动更新时,其他模块要维护版本,分别重新测试。

使用Lerna就解决了这个问题,三个模块都放在一个repository里,由Lerna组织。当其中一个模块升级时,因为其他模块引用的是这个模块最新的代码,在这个工程里集中测试一遍就可以了,也不需要维护依赖版本。全部测试ok之后,这个模块可以单独发布。

# 目录结构

├── LICENSE

├── README.md

├── lerna.json ------> 这里是lerna的配置 ├──

├── package.json

├── packages --------> 这里放模块 │    ├──

│    ├── biglet

│    ├── bigview

│    └── bigview-cli

└── test ---------> 只需要一个test

   ├── basic    └── test.js

# lerna.json 配置文件


{

  "lerna": "2.0.0-beta.36",

  "packages": [

     "packages/*"

  ],

  "version": "1.3.14",

  "commands": {

      "publishConfig": {

          "ignore": [

              "example/**",

                 "test/**"

          ]

       }

   }

}

Promise

主要用于流程控制,实现五种渲染模式

如:并行执行

深入浅出Bigview_java_06


顺序执行

深入浅出Bigview_java_07

使用简介

总入口,控制渲染模式、组织模块

深入浅出Bigview_java_08

pagelet入口

深入浅出Bigview_java_09

更多详细用法、demo可移步github查看~