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中:file选择器用法实例
Jan 04 Javascript
浅谈jQuery构造函数分析
May 11 Javascript
JS对字符串编码的几种方式使用指南
May 14 Javascript
关于session和cookie的简单理解
Jun 08 Javascript
Javascript 实现全屏滚动实例代码
Dec 31 Javascript
原生js仿淘宝网商品放大镜效果
Feb 28 Javascript
深入解析js轮播插件核心代码的实现过程
Apr 14 Javascript
Angular.js 4.x中表单Template-Driven Forms详解
Apr 25 Javascript
jQuery模拟爆炸倒计时功能实例代码
Aug 21 jQuery
JavaScript键盘事件响应顺序详解
Sep 30 Javascript
vue transition 在子组件中失效的解决
Nov 12 Javascript
js实现打字小游戏
Dec 17 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中的integer类型使用分析
2010/07/27 PHP
PHP循环结构实例讲解
2014/02/10 PHP
PHP判断是否有Get参数的方法
2014/05/05 PHP
PHP中遇到的时区问题解决方法
2015/07/23 PHP
jQuery each()方法的使用方法
2010/03/18 Javascript
深入讲解AngularJS中的自定义指令的使用
2015/06/18 Javascript
JavaScript数据结构之二叉树的删除算法示例
2017/04/13 Javascript
JS实现多张图片预览同步上传功能
2017/06/23 Javascript
Angular4编程之表单响应功能示例
2017/12/13 Javascript
vue中使用ueditor富文本编辑器
2018/02/08 Javascript
vue2配置scss的方法步骤
2019/06/06 Javascript
vue-父子组件和ref实例详解
2019/11/10 Javascript
[40:48]DOTA2上海特级锦标赛D组败者赛 Liquid VS COL第二局
2016/02/28 DOTA
Python内置函数之filter map reduce介绍
2014/11/30 Python
python模拟Django框架实例
2016/05/17 Python
Python MySQLdb 使用utf-8 编码插入中文数据问题
2018/03/13 Python
Python单元测试简单示例
2018/07/03 Python
python脚本监控Tomcat服务器的方法
2018/07/06 Python
解决python2 绘图title,xlabel,ylabel出现中文乱码的问题
2019/01/29 Python
Django框架模板语言实例小结【变量,标签,过滤器,继承,html转义】
2019/05/23 Python
python算法与数据结构之单链表的实现代码
2019/06/27 Python
Pytorch 使用CNN图像分类的实现
2020/06/16 Python
python+excel接口自动化获取token并作为请求参数进行传参操作
2020/11/10 Python
Pycharm-community-2020.2.3 社区版安装教程图文详解
2020/12/08 Python
用CSS3写的模仿iPhone中的返回按钮
2015/04/04 HTML / CSS
Airbnb爱彼迎官网:成为爱彼迎房东,赚取收入
2019/03/14 全球购物
英国领先的在线高尔夫商店:Scottsdale Golf
2019/08/26 全球购物
LN-CC英国:伦敦时尚生活的缩影
2019/09/01 全球购物
斯洛伐克最大的婴儿食品和用品网上商店:Feedo.sk
2020/12/21 全球购物
Linux操作面试题
2012/05/16 面试题
前台文员个人求职信范文
2014/01/05 职场文书
消防标语大全
2014/06/07 职场文书
党员群众路线对照检查材料
2014/08/31 职场文书
2015年迎新晚会策划书
2015/07/16 职场文书
python爬虫selenium模块详解
2021/03/30 Python
Windows 11要来了?微软文档揭示Win11太阳谷 / Win10有两个不同版本
2021/11/21 数码科技