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 相关文章推荐
JS Replace()的高级使用方法介绍
Jun 29 Javascript
JQuery筛选器全系列介绍
Aug 27 Javascript
js对象转json数组的简单实现案例
Feb 28 Javascript
用Jquery选择器计算table中的某一列某一行的合计
Aug 13 Javascript
jQuery老黄历完整实现方法
Jan 16 Javascript
angularJS 中input示例分享
Feb 09 Javascript
javascript时间排序算法实现活动秒杀倒计时效果
Jan 28 Javascript
jquery实现左右滑动式轮播图
Mar 02 Javascript
bootstrap模态框关闭后清除模态框的数据方法
Aug 10 Javascript
解决betterScroll在vue中存在图片时,出现拉不动的问题
Sep 27 Javascript
element上传组件循环引用及简单时间倒计时的实现
Oct 01 Javascript
微信小程序实现页面跳转传递参数(实体,对象)
Aug 12 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 可阅读随机字符串代码
2010/05/26 PHP
php入门学习知识点七 PHP函数的基本应用
2011/07/14 PHP
解析php中static,const与define的使用区别
2013/06/18 PHP
PHP中nowdoc和heredoc使用需要注意的一点
2014/03/21 PHP
php判断当前用户已在别处登录的方法
2015/01/06 PHP
php微信公众平台开发之获取用户基本信息
2015/08/17 PHP
PDO实现学生管理系统
2020/03/21 PHP
js RuntimeObject() 获取ie里面自定义函数或者属性的集合
2010/11/23 Javascript
如何在一个页面显示多个百度地图
2013/04/07 Javascript
jQuery中detach()方法用法实例
2014/12/25 Javascript
jQuery中parents()方法用法实例
2015/01/07 Javascript
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例
2015/03/04 Javascript
jQuery图片轮播滚动切换代码分享
2020/04/20 Javascript
原生js页面滚动延迟加载图片
2015/12/20 Javascript
CKEditor无法验证的解决方案(js验证+jQuery Validate验证)
2016/05/09 Javascript
JavaScript读二进制文件并用ajax传输二进制流的方法
2016/07/18 Javascript
javascript基本数据类型及类型检测常用方法小结
2016/12/14 Javascript
web前端vue实现插值文本和输出原始html
2018/01/19 Javascript
vue点击input弹出带搜索键盘并监听该元素的方法
2018/08/25 Javascript
Element InputNumber 计数器的实现示例
2020/08/03 Javascript
Python操作RabbitMQ服务器实现消息队列的路由功能
2016/06/29 Python
python使用matplotlib绘制折线图教程
2017/02/08 Python
Python Process多进程实现过程
2019/10/22 Python
Python列表操作方法详解
2020/02/09 Python
如何将Pycharm中调整字体大小的方式设置为&quot;ctrl+鼠标滚轮上下滑&quot;
2020/11/17 Python
基于pycharm 项目和项目文件命名规则的介绍
2021/01/15 Python
美国全球旅游运营商:Pacific Holidays
2018/06/18 全球购物
Boom手表官网:瑞典手表品牌,设计你的手表
2019/03/11 全球购物
设计师大码女装:11 Honoré
2020/05/03 全球购物
九年级科学教学反思
2014/01/29 职场文书
房屋买卖委托公证书
2014/04/08 职场文书
公司辞职信模板
2015/05/13 职场文书
go语言map与string的相互转换的实现
2021/04/07 Golang
apache基于端口创建虚拟主机的示例
2021/04/22 Servers
Go语言特点及基本数据类型使用详解
2022/03/21 Golang
SQL Server中的逻辑函数介绍
2022/05/25 SQL Server