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程序来实现动画功能
Mar 06 Javascript
firefox下frameset取不到值的解决方法
Sep 06 Javascript
jquery 笔记 事件
Nov 02 Javascript
分享jQuery封装好的一些常用操作
Jul 28 Javascript
Bootstrap 3的box-sizing样式导致UEditor控件的图片无法正常缩放的解决方案
Sep 15 Javascript
原生js封装的一些jquery方法(详解)
Sep 20 Javascript
纯js实现手风琴效果代码
Apr 17 Javascript
javascript实现无法关闭的弹框
Nov 27 Javascript
Vue动态组件和异步组件原理详解
May 06 Javascript
Vue(定时器)解决mounted不能获取到data中的数据问题
Jul 30 Javascript
Antd表格滚动 宽度自适应 不换行的实例
Oct 27 Javascript
JS常用跨域方法实现原理解析
Dec 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
PHP编写daemon process 实例详解
2016/11/13 PHP
PHP递归遍历指定文件夹内的文件实现方法
2016/11/15 PHP
PHP的curl函数的用法总结
2019/02/14 PHP
在 Laravel 中动态隐藏 API 字段的方法
2019/10/25 PHP
JQuery 确定css方框模型(盒模型Box Model)
2010/01/22 Javascript
使用隐藏的new来创建对象
2011/03/29 Javascript
jquery实现商品拖动选择效果代码(自写)
2013/05/28 Javascript
js 获取后台的字段 改变 checkbox的被选中的状态 代码
2013/06/05 Javascript
javascript字符串替换及字符串分割示例代码
2013/12/12 Javascript
jQuery实现的淡入淡出二级菜单效果代码
2015/09/15 Javascript
JS折半插入排序算法实例
2015/12/02 Javascript
详解一个基于react+webpack的多页面应用配置
2019/01/21 Javascript
Vue项目接入Paypal实现示例详解
2020/06/04 Javascript
js实现星星海特效的示例
2020/09/28 Javascript
ES6学习教程之Promise用法详解
2020/11/22 Javascript
在Django的上下文中设置变量的方法
2015/07/20 Python
Python实现的简单dns查询功能示例
2017/05/24 Python
Python使用装饰器进行django开发实例代码
2018/02/06 Python
python调用百度语音识别实现大音频文件语音识别功能
2018/08/30 Python
python3.x提取中文的正则表达式示例代码
2019/07/23 Python
Python中利用LSTM模型进行时间序列预测分析的实现
2019/07/26 Python
Django 多表关联 存储 使用方法详解 ManyToManyField save
2019/08/09 Python
用python生成与调用cntk模型代码演示方法
2019/08/26 Python
python smtplib发送多个email联系人的实现
2020/10/09 Python
python反爬虫方法的优缺点分析
2020/11/25 Python
Python获取指定网段正在使用的IP
2020/12/14 Python
技校教师求职简历的自我评价
2013/10/20 职场文书
2014年党员承诺书范文
2014/05/20 职场文书
小学优秀班干部事迹材料
2014/05/25 职场文书
餐饮服务食品安全承诺书
2015/04/29 职场文书
2015年党风廉政建设个人总结
2015/08/18 职场文书
重温经典:乔布斯在斯坦福大学的毕业演讲(双语)
2019/08/26 职场文书
初中生入团申请书范文(五篇)
2019/10/16 职场文书
SqlServer 垂直分表(减少程序改动)
2021/04/16 SQL Server
WebWorker 封装 JavaScript 沙箱详情
2021/11/02 Javascript
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
2022/06/21 Golang