Qxf上的BigPipe的实现和优化原理
Qxf其实是express下的一堆中间件的集合,所以其实我在介绍express的BigPipe实现。
简单的来说,当一个html开始下载的同时浏览器就开始渲染html了(而不是等html下载完成再渲染)。 所以,返回给用户的页面可以一上一行地写出来(用我们学生时代老师的话来说就是挤牙膏)。
server => client (以前)
- 接到用户请求 => 白屏
- 请求接口,或者查数据库,处理数据,不拉不拉不拉 => 白屏
- 渲染出数据为state => 白屏
- 渲染模板为html => 白屏
- 返回html并结束请求 => 收到html并渲染,可能会下载css
- 空闲 => 下载js
- 空闲 => 渲染js,如果有ajax请求就请求
server => client (BigPipe)
- 接到用户请求 => 白屏
- 返回html的head => 收到head,下载css,核心js
- 请求接口,或者查数据库,处理数据 => 等待返回,如果有与UI无关的逻辑可以在下载完js后先执行
- 页面首部分的数据返回,生成state(组合成script标签) => 等待返回,如果有与UI无关的逻辑可以在下载完js后先执行
- 按照state生成模板一并返回,如果后面的接口也返回了数据重复3-5 => 渲染收到的html碎片
- 全部页面加载完成,结束请求 => 页面加载完成
但是实际上按照BigPipe的做法,屏幕上面依赖的请求会阻塞,所以我对这一方案做了修改
server => client (BigPipe+)
- 接到用户请求 => 白屏
- 返回html的head + 按照默认state渲染的页面 + 默认state拼成的script标签 => 渲染出页面,下载css、js,js下载完成后可以操作了
- 请求接口,或者查数据库,处理数据 => 等待返回,或者直接操作页面
- 如果有接口返回,渲染出state并以script标签返回 => 根据收到的state二次渲染已经在dom树的组件
- 全部接口返回,结束请求 => 页面加载完成