nodejs-bigpipe

    • 存在很久的一种技术
    • Facebook首创
    • 首屏快速加载的的异步加载页面方案
    • 前端性能优化的一个方向
    • 适合比较大型的,需要大量服务器运算的站点
    • 有效减少HTTP请求
    • 兼容多浏览器

    与传统Ajax比较

    • 减少HTTP请求数:多个模块更新合成一个请求
    • 请求数减少:多个chunk合成一个请求
    • 降低管理成本:模块更新由后端程序控制
    • URL优雅降级:页面链接使用真实地址
    • 代码一致性:页面加载不劢态刷新模块代码相同

    能解决的问题

    • 下载阻塞
    • 服务器与浏览器算力浪费

    一句话:分块加载技术

    不利于SEO搜索引擎(这个说的不太对,可以采用其他手动弥补的)

    实现方式

    HTTP 1.1引入分块传输编码

    Nodejs自动开启 chunked encoding

    除非通过sendHeader()设置Content-Length头。

    Node.js bigpipe实现

    关键字

    1. res.write('xxxx');
    2. res.write('xxxx');
    3. res.write('xxxx');
    4. res.end('xxxx');

    关键字

    因为res.send包括了res.write()和res.end()

    Koa里没有提供对bigpipe的支持,ctx.body赋值做了很多约定。可以说是不太容易控制。

    • http模块是基于stream的,所以方案1是通过require(‘stream’).Readable来处理,这种是非常容易理解,但要求大家对stream有一个比较好的理解。
    • 方案2,反正Koa和express都是基于http模块的,那么为什么不用http模块的方法呢?

    在Koa里有2个概念非常容易混,req和request,res和response,我们经常在express里用req和res,但在Koa里它们指的是http启动server时传入的req和res参数

    1. var http = require("http");
    2. http.createServer((req, res) => {
    3. res.writeHead(200, {
    4. "Content-Type": "text/plain"
    5. });
    6. res.write("Hello World");
    7. }).listen(8888);

    Koa 1.x

    Koa 2.x

    1. const Koa = require('koa')
    2. const app = new Koa()
    3. const sleep = ms => new Promise(r => setTimeout(r, ms))
    4. app.use(require('koa-bigpipe'))
    5. // response
    6. app.use(ctx => {
    7. // ctx.body = 'Hello Koa'
    8. ctx.write('loading...<br>')
    9. return sleep(2000).then(function(){
    10. ctx.write(`timer: 2000ms<br>`)
    11. return sleep(5000)
    12. }).then(function(){
    13. ctx.write(`timer: 5000ms<br>`)
    14. }).then(function(){
    15. ctx.end()
    16. })
    17. })
    18. app.listen(3000)

    为什么是按照顺序加载的,怎么能并发加载呢?

    • 这就需要用到promise了 自行领悟

    @上面特殊情况的论证项目地址

    • 模块解耦
    • 前端优化,参考微博的方式
    • 性能改进
      • req.js,有http改成rpc
      • 缓存模板
      • 缓存编译结果
    • BigPipe的三种模式:
      • 一次渲染模式:即普通模式,支持搜索引擎,用来支持那些不支持JS的客户端。
      • 管线模式:即并行模式,并行请求,并即时渲染。(已实现)

    参考