var res = this
res.render(view, options, function (err, str) {
if (err) return res.req.next(err)
res.pipe(‘#’+res.pipeMap[name], str, true)
–res.pipeCount || res.end()
})
}
app.get(‘/’, function (req, res) {
res.pipeLayout(‘layout’, {
s1: res.pipeName(‘s1name’)
, s2: res.pipeName(‘s2name’)
})
getData.d1(function (err, s1data) {
res.pipePartial(‘s1name’, ‘s1’, s1data)
})
getData.d2(function (err, s2data) {
res.pipePartial(‘s2name’, ‘s2’, s2data)
})
})
还要在 layout.jade 把两个 section 添加回来:
section#s1!=s1
section#s2!=s2
这里的思路是,需要 pipe 的内容先用一个 span 标签占位,异步获取数据并渲染完成相应的 HTML 代码后再输出给浏览器,用 jQuery 的 replaceWith 方法把占位的 span 元素替换掉。
本文的代码在 https://github.com/undozen/bigpipe-on-node ,我把每一步做成一个 commit 了,希望你 clone 到本地实际运行并 hack 一下看看。因为后面几步涉及到加载顺序了,确实要自己打开浏览器才能体验到而无法从截图上看到(其实应该可以用 gif 动画实现,但是我懒得做了)。
关于 BigPipe 的实践还有很大的优化空间,比如说,要 pipe 的内容最好设置一个触发的时间值,如果异步调用的数据很快返回,就不需要用 BigPipe,直接生成网页送出即可,可以等到数据请求超过一定时间才用 BigPipe。使用 BigPipe 相比 ajax 既节省了浏览器到 node.js 服务器的请求数,又节省了 node.js 服务器到数据源的请求数。不过具体的优化和实践方法,等到雪球网用上 BigPipe 以后再分享吧。









