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 相关文章推荐
ExtJS DOM元素操作经验分享
Aug 28 Javascript
jQuery删除节点的三个方法即remove()detach()和empty()
Dec 27 Javascript
javascript中Function类型详解
Apr 28 Javascript
微信小程序 底部导航栏目开发资料
Dec 05 Javascript
Angular directive递归实现目录树结构代码实例
May 05 Javascript
React Native 图片查看组件的方法
Mar 01 Javascript
为vue-router懒加载时下载js的过程中添加loading提示避免无响应问题
Apr 03 Javascript
浅谈redux以及react-redux简单实现
Aug 28 Javascript
js隐式转换的知识实例讲解
Sep 28 Javascript
vue使用video.js进行视频播放功能
Jul 18 Javascript
vue element-ui table组件动态生成表头和数据并修改单元格格式 父子组件通信
Aug 15 Javascript
vue-router重写push方法,解决相同路径跳转报错问题
Aug 07 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
深入理解用mysql_fetch_row()以数组的形式返回查询结果
2013/06/05 PHP
PHP的变量类型和作用域详解
2014/03/12 PHP
PHP中的替代语法介绍
2015/01/09 PHP
利用PHP获取访客IP、地区位置、浏览器及来源页面等信息
2017/06/27 PHP
PHP实现获取文件mime类型多种方法解析
2020/05/28 PHP
用IE重起计算机或者关机的示例代码
2014/03/10 Javascript
javascript实现节点(div)名称编辑
2014/12/17 Javascript
使用Node.js处理前端代码文件的编码问题
2016/02/16 Javascript
JS实现把鼠标放到链接上出现滚动文字的方法
2016/04/06 Javascript
javascript学习笔记_浅谈基础语法,类型,变量
2016/09/19 Javascript
Angular 4 指令快速入门教程
2017/06/07 Javascript
详解用vue编写弹出框组件
2017/07/04 Javascript
react开发教程之React 组件之间的通信方式
2017/08/12 Javascript
详解Vue双向数据绑定原理解析
2017/09/11 Javascript
Vue使用json-server进行后端数据模拟功能
2018/04/17 Javascript
vue嵌套路由与404重定向实现方法分析
2018/05/04 Javascript
JS二级菜单不同实现方法分析【4种方法】
2018/12/21 Javascript
JavaScript 闭包的使用场景
2020/09/17 Javascript
video.js添加自定义组件的方法
2020/12/09 Javascript
Python设计模式之MVC模式简单示例
2018/01/10 Python
Python3获取拉勾网招聘信息的方法实例
2019/04/03 Python
Python基于机器学习方法实现的电影推荐系统实例详解
2019/06/25 Python
python3射线法判断点是否在多边形内
2019/06/28 Python
超简单的Python HTTP服务
2019/07/22 Python
通过python 执行 nohup 不生效的解决
2020/04/16 Python
GE设备配件:GE Appliance Parts(家电零件、配件和滤水器)
2018/11/28 全球购物
小学教师办公室制度
2014/02/03 职场文书
商务英语专业毕业生求职信
2014/07/06 职场文书
目标责任书格式
2014/07/28 职场文书
中国文明网向国旗敬礼活动精彩寄语2014
2014/09/27 职场文书
秦兵马俑导游词
2015/02/02 职场文书
2015人事行政工作总结范文
2015/05/21 职场文书
小孩不笨观后感
2015/06/03 职场文书
医生行业员工的辞职信
2019/06/24 职场文书
2019年共青团工作条例最新版
2019/11/12 职场文书
python opencv常用图形绘制方法(线段、矩形、圆形、椭圆、文本)
2021/04/12 Python