今天刚好看到bigpipe的文章,写个demo试一下:
nodejs的实现:
var fs = require('fs'); module.exports = function(req , res){ //bigpipe测试 res.writeHead(200 , {'Content-Type': 'text/html;charset=utf-8'}); var html = fs.readFileSync(__dirname + "/head.html").toString(); var i = 0; res.write(html); setTimeout(function(){ //先加载js文件 res.write(fs.readFileSync(__dirname + "/script.html").toString()); //然后开始加载各个page的内容 flush(); },200); function flush(){ if(i >= 4){ res.end("</body></html>"); return; } setTimeout(function(){ res.write("<script class='element' data-id='dom"+i+"' type='text/template'>" + fs.readFileSync(__dirname + "/manyValue.html").toString()+"</script>"); i++; flush(); },1000) } }
上面的代码中,首次先输出head.html(第一次发送的html头,为了尽快加载完,所以里面只有一个样式表):
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="/public/bigpipe/bigpipe-test.css"/> </head> <body> <div class="view"> <div class="page" id="dom0"><div class="value">Loading...</div></div> <div class="page" id="dom1"><div class="value">Loading...</div></div> <div class="page" id="dom2"><div class="value">Loading...</div></div> <div class="page" id="dom3"><div class="value">Loading...</div></div> </div>
head.html的内容很少,所以很快就可以展示在用户面前,给人一种好像加载很快的感觉。然后再输出js逻辑:
<script src="/public/jquery-2.1.1.min.js"></script> <script src="/public/bigpipe/bigpipe-test.js"></script>
而bigpipe-test.js对每个page的数据处理为:
var now = 0; var loop = setInterval(function(){ var $els = $(".element"); $els.each(function(){ if($(this).html()){ var $eim = $("#" + $(this).attr("data-id")); $eim.find(".value").html($(this).html()); document.body.removeChild(this); now++; } }) if(now == $(".page").length){ clearInterval(loop); } },200);
因为后面传过来的真正数据格式为:<script class='element' data-id='dom"+i+"' type='text/template'> XXX </script>
所以bigpipe-test.js里仅需判断页面上的script标签有无改变即可,如有改变,则获取内容并且将内容放置该放置的地方。
Test : http://wanghx.cn:9030/bigpipe 页面和样式很快就加载出来了。
为了展示效果,所以上面的demo中特意做了延时,不过在平时项目中如果内容特别多,刚开始就一股脑把所有内容放在一个页面加载,用户打开网页的时候则可能会盯着白屏看一会才会load出来。bigpipe的好处就在于此,可以将大概模子先加载出来,然后更多的内容再慢慢一点load出来,而且又不需要另开http请求,一个请求就可以完成分段加载。
该方法对于移动端的单页多屏应用的用户体验提升益处很大,用户打开页面的时候可以先将首屏加载出来,然后再load其他屏。
新技能 get√