Qxf上的BigPipe的实现和优化原理

Qxf其实是express下的一堆中间件的集合,所以其实我在介绍express的BigPipe实现。

简单的来说,当一个html开始下载的同时浏览器就开始渲染html了(而不是等html下载完成再渲染)。 所以,返回给用户的页面可以一上一行地写出来(用我们学生时代老师的话来说就是挤牙膏)。

server => client (以前)

  1. 接到用户请求 => 白屏
  2. 请求接口,或者查数据库,处理数据,不拉不拉不拉 => 白屏
  3. 渲染出数据为state => 白屏
  4. 渲染模板为html => 白屏
  5. 返回html并结束请求 => 收到html并渲染,可能会下载css
  6. 空闲 => 下载js
  7. 空闲 => 渲染js,如果有ajax请求就请求

server => client (BigPipe)

  1. 接到用户请求 => 白屏
  2. 返回html的head => 收到head,下载css,核心js
  3. 请求接口,或者查数据库,处理数据 => 等待返回,如果有与UI无关的逻辑可以在下载完js后先执行
  4. 页面首部分的数据返回,生成state(组合成script标签) => 等待返回,如果有与UI无关的逻辑可以在下载完js后先执行
  5. 按照state生成模板一并返回,如果后面的接口也返回了数据重复3-5 => 渲染收到的html碎片
  6. 全部页面加载完成,结束请求 => 页面加载完成

但是实际上按照BigPipe的做法,屏幕上面依赖的请求会阻塞,所以我对这一方案做了修改

server => client (BigPipe+)

  1. 接到用户请求 => 白屏
  2. 返回html的head + 按照默认state渲染的页面 + 默认state拼成的script标签 => 渲染出页面,下载css、js,js下载完成后可以操作了
  3. 请求接口,或者查数据库,处理数据 => 等待返回,或者直接操作页面
  4. 如果有接口返回,渲染出state并以script标签返回 => 根据收到的state二次渲染已经在dom树的组件
  5. 全部接口返回,结束请求 => 页面加载完成