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 相关文章推荐
优化JavaScript脚本的性能的几个注意事项
Dec 22 Javascript
读jQuery之五(取DOM元素)
Jun 20 Javascript
基于jQuery实现左右div自适应高度完全相同的代码
Aug 09 Javascript
js获取当前页面的url网址信息
Jun 12 Javascript
使用jQuery设置disabled属性与移除disabled属性
Aug 21 Javascript
JQuery设置时间段下拉选择实例
Dec 30 Javascript
浅谈javascript实现八大排序
Apr 27 Javascript
JavaScript使用DeviceOne开发实战(一) 配置和起步
Dec 01 Javascript
JS基于HTML5的canvas标签实现炫目的色相球动画效果实例
Aug 24 Javascript
JavaScript数据结构中串的表示与应用实例
Apr 12 Javascript
jquery实现回车键触发事件(实例讲解)
Nov 21 jQuery
JavaScript函数定义方法实例详解
Mar 05 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
PHP中操作ini配置文件的方法
2013/04/25 PHP
关于PHP内存溢出问题的解决方法
2013/06/25 PHP
浅析php学习的路线图
2013/07/10 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
php代码检查代理ip的有效性
2016/08/19 PHP
php使用PDO事务配合表格读取大量数据插入操作实现方法
2017/02/16 PHP
PHP+iframe模拟Ajax上传文件功能示例
2019/07/02 PHP
JavaScript中this的使用详解
2013/11/08 Javascript
使用原生js实现页面蒙灰(mask)效果示例代码
2014/06/20 Javascript
NodeJs中的VM模块详解
2015/05/06 NodeJs
js获取css的各种样式并且设置他们的方法
2017/08/22 Javascript
解决vue组件中使用v-for出现告警问题及v for指令介绍
2017/11/11 Javascript
如何使用puppet替换文件中的string
2018/12/06 Javascript
原生JS实现的放大镜特效示例【测试可用】
2018/12/08 Javascript
如何给element添加一个抽屉组件的方法步骤
2019/07/14 Javascript
解决vue 子组件修改父组件传来的props值报错问题
2019/11/09 Javascript
Python多线程编程(六):可重入锁RLock
2015/04/05 Python
Python实现字符串逆序输出功能示例
2017/06/24 Python
python+matplotlib绘制简单的海豚(顶点和节点的操作)
2018/01/02 Python
对python list 遍历删除的正确方法详解
2018/06/29 Python
基于python实现聊天室程序
2018/07/27 Python
Python 多维List创建的问题小结
2019/01/18 Python
pandas.read_csv参数详解(小结)
2019/06/21 Python
python画双y轴图像的示例代码
2019/07/07 Python
pd.DataFrame统计各列数值多少的实例
2019/12/05 Python
解决pytorch报错:AssertionError: Invalid device id的问题
2020/01/10 Python
快速查找Python安装路径方法
2020/02/06 Python
pycharm 复制代码出现空格的解决方式
2021/01/15 Python
美国在线面料商店:Online Fabric Store
2018/07/26 全球购物
Lookfantastic希腊官网:英国知名美妆购物网站
2018/09/15 全球购物
应聘美工求职信
2013/11/07 职场文书
市场营销调查计划书
2014/05/02 职场文书
完美的中文自荐信
2014/05/24 职场文书
商场周年庆活动方案
2014/08/19 职场文书
2016年党员读书月活动总结
2016/04/06 职场文书
送给火锅店的创意营销方案!
2019/07/08 职场文书