位置: 编程技术 - 正文

node.js实现BigPipe详解(nodejs bff)

编辑:rootadmin

推荐整理分享node.js实现BigPipe详解(nodejs bff),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:Node.js实现LDAP服务,nodejs fabric,node.js怎么用,Node.js实现LDAP服务,node.js怎么用,Node.js实现lua解释器,nodejs pipe,nodejs pipe,内容如对您有帮助,希望把文章链接给更多的朋友!

BigPipe 是 Facebook 开发的优化网页加载速度的技术。网上几乎没有用 node.js 实现的文章,实际上,不止于 node.js,BigPipe 用其他语言的实现在网上都很少见。以至于这技术出现很久以后,我还以为就是整个网页的框架先发送完毕后,用另一个或几个 ajax 请求再请求页面内的模块。直到不久前,我才了解到原来 BigPipe 的核心概念就是只用一个 HTTP 请求,只是页面元素不按顺序发送而已。

了解了这个核心概念就好办了,得益于 node.js 的异步特性,很容易就可以用 node.js 实现 BigPipe。本文会一步一步详尽地用例子来说明 BigPipe 技术的起因和一个基于 node.js 的简单实现。

我会用 express 来演示,简单起见,我们选用 jade 作为模版引擎,并且我们不使用引擎的子模版(partial)特性,而是以子模版渲染完成以后的 HTML 作为父模版的数据。

先建一个 nodejs-bigpipe 的文件夹,写一个 package.json 文件如下:

运行 npm install 安装这三个库,consolidate 是用来方便调用 jade 的。

先做个最简单的尝试,两个文件:

app.js:

views/layout.jade

效果如下:

接下来我们把两个 section 模版放到两个不同的模版文件里:

views/s1.jade:

views/s2.jade:

在 layout.jade 的 style 里增加一些样式

将 app.js 的 app.use() 部分更改为:

之前我们说“以子模版渲染完成以后的 HTML 作为父模版的数据”,指的就是这样,temp.s1 和 temp.s2 两个方法会生成 s1.jade 和 s2.jade 两个文件的 HTML 代码,然后把这两段代码作为 layout.jade 里面 s1、s2 两个变量的值。

现在页面看起来是这样子:

一般来说,两个 section 的数据是分别获取的——不管是通过查询数据库还是 RESTful 请求,我们用两个函数来模拟这样的异步操作。

这样一来,app.use() 里的逻辑就会比较复杂了,最简单的处理方式是:

这样也可以得到我们想要的结果,但是这样的话,要足足 8 秒才会返回。

其实实现逻辑可以看出 getData.d2 是在 getData.d1 的结果返回后才开始调用,而它们两者并没有这样的依赖关系。我们可以用如 async 之类的处理 JavaScript 异步调用的库来解决这样的问题,不过我们这里就简单手写吧:

node.js实现BigPipe详解(nodejs bff)

这样就只需 5 秒。

在接下来的优化之前,我们加入 jquery 库并把 css 样式放到外部文件,顺便,把之后我们会用到的浏览器端使用 jade 模板所需要的 runtime.js 文件也加入进来,在包含 app.js 的目录下运行:

并且把 layout.jade 中的 style 标签里的代码拿出来放到 static/style.css 里,然后把 head 标签改为:

在 app.js 里,我们把它们两者的下载速度都模拟为两秒,在app.use(function (req, res) {之前加入:

受外部静态文件的影响,我们的页面现在的加载时间为 7 秒左右。

如果我们一收到 HTTP 请求就把 head 部分返回,然后两个 section 等到异步操作结束后再返回,这是利用了 HTTP 的分块传输编码机制。在 node.js 里面只要使用 res.write() 方法就会自动加上 Transfer-Encoding: chunked 这个 header 了。这样就能在浏览器加载静态文件的同时,node 服务器这边等待异步调用的结果了,我们先删除 layout.jade 中的这 section 这两行:

因此我们在 res.render() 里也不用给 { s1: …, s2: … } 这个对象,并且因为 res.render() 默认会调用 res.end(),我们需要手动设置 render 完成后的回调函数,在里面用 res.write() 方法。layout.jade 的内容也不必在 writeResult() 这个回调函数里面,我们可以在收到这个请求时就返回,注意我们手动添加了 content-type 这个 header:

现在最终加载速度又回到大概 5 秒左右了。实际运行中浏览器先收到 head 部分代码,就去加载三个静态文件,这需要两秒时间,然后到第三秒,出现 Partial 1 部分,第 5 秒出现 Partial 2 部分,网页加载结束。就不给截图了,截图效果和前面 5 秒的截图一样。

但是要注意能实现这个效果是因为 getData.d1 比 getData.d2 快,也就是说,先返回网页中的哪个区块取决于背后的接口异步调用结果谁先返回,如果我们把 getData.d1 改成 8 秒返回,那就会先返回 Partial 2 部分,s1 和 s2 的顺序对调,最终网页的结果就和我们的预期不符了。

这个问题最终将我们引导到 BigPipe 上来,BigPipe 就是能让网页各部分的显示顺序与数据的传输顺序解耦的技术。

其基本思路就是,首先传输整个网页大体的框架,需要稍后传输的部分用空 div(或其他标签)表示:

然后将返回的数据用 JavaScript 写入

s2 的处理与此类似。这时你会看到,请求网页的第二秒,出现两个空白虚线框,第五秒,出现 Partial 2 部分,第八秒,出现 Partial 1 部分,网页请求完成。

至此,我们就完成了一个最简单的 BigPipe 技术实现的网页。

需要注意的是,要写入的网页片段有 script 标签的情况,如将 s1.jade 改为:

然后刷新网页,会发现这句 alert 没有执行,而且网页会有错误。查看源代码,知道是因为 <script> 里面的字符串出现 </script> 而导致的错误,只要将其替换为 </script> 即可

以上我们便说明了 BigPipe 的原理和用 node.js 实现 BigPipe 的基本方法。而在实际中应该怎样运用呢?下面提供一个简单的方法,仅供抛砖引玉,代码如下:

还要在 layout.jade 把两个 section 添加回来:

这里的思路是,需要 pipe 的内容先用一个 span 标签占位,异步获取数据并渲染完成相应的 HTML 代码后再输出给浏览器,用 jQuery 的 replaceWith 方法把占位的 span 元素替换掉。

本文的代码在 ,我把每一步做成一个 commit 了,希望你 clone 到本地实际运行并 hack 一下看看。因为后面几步涉及到加载顺序了,确实要自己打开浏览器才能体验到而无法从截图上看到(其实应该可以用 gif 动画实现,但是我懒得做了)。

关于 BigPipe 的实践还有很大的优化空间,比如说,要 pipe 的内容最好设置一个触发的时间值,如果异步调用的数据很快返回,就不需要用 BigPipe,直接生成网页送出即可,可以等到数据请求超过一定时间才用 BigPipe。使用 BigPipe 相比 ajax 既节省了浏览器到 node.js 服务器的请求数,又节省了 node.js 服务器到数据源的请求数。不过具体的优化和实践方法,等到雪球网用上 BigPipe 以后再分享吧。

node.js中实现同步操作的3种实现方法 众所周知,异步是得天独厚的特点和优势,但同时在程序中同步的需求(比如控制程序的执行顺序为:func1-func2-func3)也是很常见的。本文就是对这个问

node.js中RPC(远程过程调用)的实现原理介绍 刚接触到RPC(远程过程调用),就是可以在本地调用远程机子上的程序的方法,看到一个简单的nodejs实现,用来学习RPC的原理很不错:nodejslight_rpc使用

nodejs实现的一个简单聊天室功能分享 今天我来实现一个简单的聊天室,后台用nodejs,客户端与服务端通信用socket.io,这是一个比较成熟的websocket框架.初始工作1.安装express,用这个来托管socket.io,

标签: nodejs bff

本文链接地址:https://www.jiuchutong.com/biancheng/374266.html 转载请保留说明!

上一篇:Node.js实现的简易网页抓取功能示例(node.js怎么样)

下一篇:node.js中实现同步操作的3种实现方法

  • 一般纳税人和小规模纳税人哪个合适
  • 生育津贴是否需要纳税
  • 允许抵扣的进项税额分为哪几种情况
  • 增值税减免附加税怎么申报
  • 培训费计入办公会计科目吗?
  • 现代服务包含哪些服务
  • 专用发票压线了可以拒收吗
  • 对方只能开普票怎么办
  • 收据可以盖发票专用章吗有效吗
  • 个税生产经营申报流程
  • 预付租金就要交增值税吗
  • 城建税及教育附加税怎么算
  • 银行本票支付货款,余额退回
  • 开给天猫的服务费分录如何做
  • 公司增资麻烦吗?
  • 资本公积与实收资本和盈余公积有什么区别?
  • 小微企业减免的税金怎么做账
  • 非居民企业从居民企业取得分红
  • 参加展会的住宿费计入什么科目
  • 个人交汽车购置税流程
  • 开发票回款是什么意思
  • 企业取得代扣代缴个税手续费分录
  • 简易计税开票开成了一般计税的税率会比对不通过吗
  • 不动产进项抵扣新政策2022
  • 预付账款属于资产类
  • 公司收回货款会计分录
  • window10最新20h2
  • 外包社保会计分录
  • 银行存款调账怎么调
  • PHP:mb_stristr()的用法_mbstring函数
  • PHP:Memcached::replaceByKey()的用法_Memcached类
  • 贷款损失会计处理
  • 父子之间房屋赠与费用
  • 辛华达瀑布,加拿大贾斯珀国家公园 (© Schroptschop/Getty Images)
  • 如何用php制作网页
  • php运算符号
  • 前端解决跨域问题的代理
  • wordpress all in one
  • 未记账凭证怎么变成已记账凭证
  • 企业对外担保能收担保费吗
  • 含消费税的商品开成了不含消费税怎么办
  • 固定资产的财务业绩是什么意思啊
  • 固定资产加速折旧最新税收政策2023
  • 不动产销售额是否为免税
  • 商业承兑汇票在网银上怎么查询
  • 二手车的范围
  • 企业短期借款的会计分录
  • mysqld-nt: Out of memory (Needed 1677720 bytes)解决方法
  • 教育培训机构的老师可以评职称吗
  • 税务局退回水利基金账务怎么处理
  • 事业单位之间
  • 固定资产报废电费怎么算
  • 企业主要的工会是什么
  • 外汇申报材料
  • mysql常见语句总结
  • xp系统cmd怎么打开
  • mysql数据库去重
  • quicklook预览word
  • macpro删除文件
  • win10玩游戏遇到问题需要重新启动
  • msng.exe是什么
  • 双系统怎么转移文件
  • [置顶]游戏名:chivalry2
  • jquery自定义
  • 批处理常用命令总结
  • jquery添加删除属性
  • 'tools.jar' seems to be not in Android Studio classpath. Please ensure JAVA_HOME points to JDK rathe
  • easyui表格
  • 置顶朋友圈所有人能看到吗
  • python 类的用法
  • 深入理解中国式现代化
  • 举例说明jquery的功能
  • js按下回车键时提交
  • 增值税发票打印时号码不一致怎么办
  • 法律服务所与律师事务所区别
  • 施工企业建筑机械管理机构主要职责是负责建筑机械的
  • 个人所得税自行纳税申报表(A表)怎么填写
  • 税纳税申报表
  • 河南省土地使用税税率
  • 建筑企业所交的税项有多少
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设