node网页分段渲染详解


Posted in Javascript onSeptember 05, 2016

页面渲染,通常来说分为前端渲染以及后端渲染。前端渲染指的是服务端返回html框架以及模版,前端通过ajax异步请求拉取数据渲染模版,并动态修改dom,形成最终页面。服务端渲染则是服务端通过在后端拉取数据以及后端模版渲完整页面,并返回到客户端。2种方法各有好处,后端渲染带来的则是首屏时间的提高,减少请求次数,利于SEO等好处。但是传统后端直出渲染需要等到整个网页渲染完成,才能返回到客户端。假如某个区块拉取数据比较慢,影响了渲染的速度,那对于用户来说,等待的时候也会跟着变长对于后端渲染能否跟前端ajax渲染一样,分块分区域传统的服务端直出渲染,下面将提供一种解决方案-网页分段渲染。

首先我们先看下传统的渲染方式:

const http = require("http");
const fs = require("fs");
var tpl1 = '<!DOCTYPE html><html><head><title>测试render</title></head><body>helloword<p>$data1</p>';
var tpl2 = '<p>$data2</p></body></html>';
var html = '';

var server = http.createServer((req, res)=>{
 if(req.url!=="/favicon.ico"){
   res.writeHead(200, {
     'Content-Type' : 'text/html'
   });
   getDataOne((data1) => {
     getDataTwo((data2) => {
       res.end(tpl1.replace(/\$data1/g, data1) + tpl2.replace(/\$data2/g, data2));
     })
   });
 }
 }).listen(3000, '127.0.0.1');


function getDataOne(fn){
  setTimeout(() => {
     fn('11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111');
  }, 5000);
 }

 function getDataTwo(fn){
   setTimeout(() => {
     fn('22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222');
   }, 5000);
 }

上面我们提供了一个简单的例子,通过访问http://127.0.0.1:3000 返回一个页面。其中渲染页面时,有2个耗时5秒的操作,可以假设为IO或者数据拉取。这个时候我们观察返回页面的时间是10秒,也就是说用户看到页面需要10秒钟。

node网页分段渲染详解

下面我们通过改造后端渲染方式,改为分段渲染。

const http = require("http");
const fs = require("fs");

var server = http.createServer((req, res)=>{
  if(req.url!=="/favicon.ico"){
    res.writeHead(200, {
      'Content-Type' : 'text/html',
      'Transfer-Encoding' : 'chunked'
    });

    getDataOne((data1) => {
      res.write('<!DOCTYPE html><html><head><title>测试render</title></head><body>helloword<p>$data1</p>'.replace(/\$data1/g, data1));
      getDataTwo((data2) => {
        res.end('<p>$data2</p></body></html>'.replace(/\$data2/g, data2));
      })
    });
 }
}).listen(3000, '127.0.0.1');

function getDataOne(fn1){
  setTimeout(() => {
   fn1('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111');
 }, 5000);
 }

function getDataTwo(fn2){
  setTimeout(() => {
    fn2('22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222');
  }, 5000);
}

通过设置http首部: Transfer-Encoding: chunked 即开启了分段传输的魔法。该编码方式存在http1.1中,一般在服务器生成HTTP回应是无法确定信息大小的,这时用Content-Length就无法事先写入长度,而需要实时生成消息长度,则服务器一般采用Chunked编码。

在进行Chunked编码传输时,在回复消息的头部有transfer-coding并定义为Chunked,表示将用Chunked编码传输内容。 下面我们看下修改后的效果:

node网页分段渲染详解

虽然总体的页面传输时间并没有变化,但是通过该方式,我们将响应时间缩短了一半,减少了用户等待的时间。在具体业务中,我们可以讲用户需要先看到的部分进行提前输出,将后端处理耗时较久的部分延迟输出,这就是分段传输渲染的优势。 注意如果服务器是nginx,有可能由于缓冲区的设置导致分段渲染无效,需要调整缓冲区大小。

Javascript 相关文章推荐
jquery last-child 列表最后一项的样式
Jan 22 Javascript
JSQL SQLProxy 的 php 版本代码
May 05 Javascript
浏览器脚本兼容 文本框中,回车键触发事件的兼容
Jun 21 Javascript
30个精美的jQuery幻灯片效果插件和教程
Aug 23 Javascript
基于mootools插件实现遮罩层新手引导
May 24 Javascript
JS动态增加删除UL节点LI及相关内容示例
May 21 Javascript
Bootstrap每天必学之弹出框(Popover)插件
Apr 25 Javascript
jQuery实现文字自动横移
Jan 08 Javascript
angularjs中使用ng-bind-html和ng-include的实例
Apr 28 Javascript
JS实现简单的天数计算器完整实例
Apr 28 Javascript
使用Vue构建可重用的分页组件
Mar 26 Javascript
js实现无缝轮播图
Mar 09 Javascript
js对象浅拷贝和深拷贝详解
Sep 05 #Javascript
JS实现隐藏同级元素后只显示JS文件内容的方法
Sep 04 #Javascript
jQuery实现智能判断固定导航条或侧边栏的方法
Sep 04 #Javascript
angularjs实现文字上下无缝滚动特效代码
Sep 04 #Javascript
jQuery实现为LI列表前3行设置样式的方法【2种方法】
Sep 04 #Javascript
JS实现屏蔽网页右键复制及ctrl+c复制的方法【2种方法】
Sep 04 #Javascript
jQuery实现的自动加载页面功能示例
Sep 04 #Javascript
You might like
在Laravel 的 Blade 模版中实现定义变量
2019/10/14 PHP
Dom加载让图片加载完再执行的脚本代码
2008/05/15 Javascript
JQuery打造PHP的AJAX表单提交实例
2009/11/03 Javascript
用JQuery调用Session的实现代码
2010/10/29 Javascript
Chrome中JSON.parse的特殊实现
2011/01/12 Javascript
js字符串截取函数substr substring slice使用对比
2013/11/27 Javascript
Dojo Javascript 编程规范 规范自己的JavaScript书写
2014/10/26 Javascript
node.js中RPC(远程过程调用)的实现原理介绍
2014/12/05 Javascript
jQuery Mobile框架中的表单组件基础使用教程
2016/05/17 Javascript
AngularJS  $modal弹出框实例代码
2016/08/24 Javascript
jQuery实现的右下角广告窗体跟随效果示例
2016/09/16 Javascript
jQuery ajax MD5实现用户注册即时验证功能
2016/10/11 Javascript
微信小程序 action-sheet底部菜单详解
2016/10/27 Javascript
基于jQuery实现Tabs选项卡自定义插件
2016/11/21 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
2017/01/13 Javascript
jquery实现自适应banner焦点图
2017/02/16 Javascript
jQuery Ajax实现Select多级关联动态绑定数据的实例代码
2018/10/26 jQuery
[48:00]完美世界DOTA2联赛循环赛 Forest vs Inki BO2第二场 11.04
2020/11/04 DOTA
Python入门_浅谈字符串的分片与索引、字符串的方法
2017/05/16 Python
python使用knn实现特征向量分类
2018/12/26 Python
Python多进程fork()函数详解
2019/02/22 Python
基于Django的乐观锁与悲观锁解决订单并发问题详解
2019/07/31 Python
基于Python数据结构之递归与回溯搜索
2020/02/26 Python
Python多线程threading join和守护线程setDeamon原理详解
2020/03/18 Python
TensorFlow的reshape操作 tf.reshape的实现
2020/04/19 Python
Django-imagekit的使用详解
2020/07/06 Python
芬兰攀岩、山地运动和户外活动用品购物网站:Bergfreunde
2016/10/06 全球购物
美国户外生活方式品牌:Eddie Bauer
2016/12/28 全球购物
Jabra捷波朗美国官网:用于办公、车载和运动的无线蓝牙耳麦
2017/02/01 全球购物
KARATOV珠宝在线商店:俄罗斯珠宝品牌
2019/03/13 全球购物
体育口号大全
2014/06/18 职场文书
大学感恩节活动总结
2015/05/05 职场文书
教师节主持词开场白
2015/05/29 职场文书
表扬稿表扬信的格式及范文
2019/06/24 职场文书
手把手教你怎么用Python实现zip文件密码的破解
2021/05/27 Python
总结高并发下Nginx性能如何优化
2021/11/01 Servers