nodejs简易实现一下bigpipe

    今天刚好看到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://node-tester-171479.nitrousapp.com:9030/bigpipe   页面和样式很快就加载出来了。

    为了展示效果,所以上面的demo中特意做了延时,不过在平时项目中如果内容特别多,刚开始就一股脑把所有内容放在一个页面加载,用户打开网页的时候则可能会盯着白屏看一会才会load出来。bigpipe的好处就在于此,可以将大概模子先加载出来,然后更多的内容再慢慢一点load出来,而且又不需要另开http请求,一个请求就可以完成分段加载。

      该方法对于移动端的单页多屏应用的用户体验提升益处很大,用户打开页面的时候可以先将首屏加载出来,然后再load其他屏。

  新技能 get√

posted @ 2015-03-26 17:38 W·Axes 阅读(...) 评论(...) 编辑 收藏