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 验证表单(form)中的单选(radio)值
Sep 08 Javascript
js png图片(有含有透明)在IE6中为什么不透明了
Feb 07 Javascript
js 获取Listbox选择的值的代码
Apr 15 Javascript
JS实现可改变列宽的table实例
Jul 02 Javascript
json数据的列循环示例
Sep 06 Javascript
javascript中局部变量和全局变量的区别详解
Feb 27 Javascript
JS实现FLASH幻灯片图片切换效果的方法
Mar 04 Javascript
js实现鼠标经过表格行变色的方法
May 12 Javascript
详解vue.js组件化开发实践
Dec 14 Javascript
node.js基于mongodb的搜索分页示例
Jan 22 Javascript
bootstrap自定义样式之bootstrap实现侧边导航栏功能
Sep 10 Javascript
Vue解析剪切板图片并实现发送功能
Feb 04 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
str_replace只替换一次字符串的方法
2013/04/09 PHP
PHP弹出提示框并跳转到新页面即重定向到新页面
2014/01/24 PHP
百度实时推送api接口应用示例
2014/10/21 PHP
PHP实现二维数组按某列进行排序的方法
2016/11/18 PHP
jQuery EasyUI API 中文文档 - PropertyGrid属性表格
2011/11/18 Javascript
IE中jquery.form中ajax提交没反应解决方法分享
2012/09/11 Javascript
jquery给图片添加鼠标经过时的边框效果
2013/11/12 Javascript
弹出窗口并且此窗口带有半透明的遮罩层效果
2014/03/13 Javascript
运行Node.js的IIS扩展iisnode安装配置笔记
2015/03/02 Javascript
js匿名函数作为函数参数详解
2016/06/01 Javascript
JS基于面向对象实现的拖拽功能示例
2016/12/20 Javascript
VUE利用vuex模拟实现新闻点赞功能实例
2017/06/28 Javascript
jQuery实现动态控制页面元素的方法分析
2017/12/20 jQuery
vue拦截器实现统一token,并兼容IE9验证功能
2018/04/26 Javascript
Vue组件之极简的地址选择器的实现
2018/05/31 Javascript
Vue实现todolist删除功能
2018/06/26 Javascript
vue-cli项目代理proxyTable配置exclude的方法
2018/09/20 Javascript
Vue传参一箩筐(页面、组件)
2019/04/04 Javascript
Vue+ElementUI使用vue-pdf实现预览功能
2019/11/26 Javascript
JavaScript基于SVG的图片切换效果实例代码
2020/12/15 Javascript
Python实现对比不同字体中的同一字符的显示效果
2015/04/23 Python
python开发之thread线程基础实例入门
2015/11/11 Python
Python的爬虫包Beautiful Soup中用正则表达式来搜索
2016/01/20 Python
python递归删除指定目录及其所有内容的方法
2017/01/13 Python
理论讲解python多进程并发编程
2018/02/09 Python
Python3.6简单反射操作示例
2018/06/14 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
django 通过url实现简单的权限控制的例子
2019/08/16 Python
python3-flask-3将信息写入日志的实操方法
2019/11/12 Python
联想阿根廷官方网站:Lenovo Argentina
2019/10/14 全球购物
演讲稿格式范文
2014/05/19 职场文书
五一劳动节演讲稿
2014/09/12 职场文书
如何写好开幕词?
2019/06/24 职场文书
写作技巧:如何撰写商业计划书
2019/08/08 职场文书
你真的了解PHP中的引用符号(&)吗
2021/05/12 PHP
Python实现查询剪贴板自动匹配信息的思路详解
2021/07/09 Python