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中使用replace结合正则实现replaceAll的效果
Jun 04 Javascript
jquery二级导航内容均分的原理及实现
Aug 13 Javascript
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例
Mar 04 Javascript
《JavaScript函数式编程》读后感
Aug 07 Javascript
jQuery实现的多级下拉菜单效果代码
Aug 24 Javascript
AngularJS使用ngOption实现下拉列表的实例代码
Jan 23 Javascript
AngularJS 依赖注入详解和简单实例
Jul 28 Javascript
ionic实现滑动的三种方式
Aug 27 Javascript
AngularJS基于ui-route实现深层路由的方法【路由嵌套】
Dec 14 Javascript
jquery.masonry瀑布流效果
May 25 jQuery
使用vuex缓存数据并优化自己的vuex-cache
May 30 Javascript
antd的select下拉框因为数据量太大造成卡顿的解决方式
Oct 31 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的计数器程序
2006/10/09 PHP
PHP 导出数据到淘宝助手CSV的方法分享
2010/02/27 PHP
基于php split()函数的用法详解
2013/06/05 PHP
修改php.ini不生效问题解决方法(上传大于8M的文件)
2013/06/14 PHP
PHP5.5和之前的版本empty函数的不同之处
2014/06/13 PHP
PHP的Yii框架入门使用教程
2016/02/15 PHP
破除网页鼠标右键被禁用的绝招大全
2006/12/27 Javascript
JS URL传中文参数引发的乱码问题
2009/09/02 Javascript
jquery ajax执行后台方法
2010/03/18 Javascript
SWFObject 2.1以上版本语法介绍
2010/07/10 Javascript
jQuery编辑器KindEditor4.1.4代码高亮显示设置教程
2013/03/01 Javascript
javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】
2016/12/15 Javascript
webpack配置的最佳实践分享
2017/04/21 Javascript
Vue实战之vue登录验证的实现代码
2017/10/31 Javascript
web前端vue之vuex单独一文件使用方式实例详解
2018/01/11 Javascript
详解js的作用域、预解析机制
2018/02/05 Javascript
angularJS开发注意事项
2018/05/26 Javascript
微信小程序使用wx.request请求服务器json数据并渲染到页面操作示例
2019/03/30 Javascript
从0到1搭建Element的后台框架的方法步骤
2019/04/10 Javascript
解决layui富文本编辑器图片上传无法回显的问题
2019/09/18 Javascript
详解Vue后台管理系统开发日常总结(组件PageHeader)
2019/11/01 Javascript
微信小程序使用 vant Dialog组件的正确方式
2020/02/21 Javascript
[02:49:21]2019完美盛典全程录像
2019/12/08 DOTA
python利用beautifulSoup实现爬虫
2014/09/29 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
2017/12/25 Python
Python实现插入排序和选择排序的方法
2019/05/12 Python
通过实例了解python property属性
2019/11/01 Python
Python 余弦相似度与皮尔逊相关系数 计算实例
2019/12/23 Python
Python异步编程之协程任务的调度操作实例分析
2020/02/01 Python
python 使用OpenCV进行简单的人像分割与合成
2021/02/02 Python
工商管理应届生求职信
2013/10/07 职场文书
区域销售经理岗位职责
2013/12/10 职场文书
餐饮管理自我介绍信
2014/01/15 职场文书
公司捐书倡议书
2015/04/27 职场文书
小学语文国培研修日志
2015/11/13 职场文书
openstack云计算keystone组件工作介绍
2022/04/20 Servers