使用 HTTP/2 服务端推送技术加速 Node.js 应用

Posted Linux开源社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 HTTP/2 服务端推送技术加速 Node.js 应用相关的知识,希望对你有一定的参考价值。

四月份,我们宣布了对 HTTP/2 服务端推送技术的支持,我们是通过 HTTP 的 Link 头部[1]来实现这项支持的。我的同事 John 曾经通过一个例子演示了php 里支持服务端推送功能[2]是多么的简单。

我们想让现今使用 Node.js 构建的网站能够更加轻松的获得性能提升。为此,我们开发了 netjet[3] 中间件,它可以解析应用生成的 html 并自动添加 Link 头部。当在一个示例的 Express 应用中使用这个中间件时,我们可以看到应用程序的输出多了如下 HTTP 头:

使用 HTTP/2 服务端推送技术加速 Node.js 应用

本博客[4]是使用 Ghost[5](LCTT 译注:一个博客发布平台)进行发布的,因此如果你的浏览器支持 HTTP/2,你已经在不知不觉中享受了服务端推送技术带来的好处了。接下来,我们将进行更详细的说明。

netjet 使用了带有定制插件的 PostHTML 来解析 HTML。目前,netjet 用它来查找图片、脚本和外部 CSS 样式表。你也可以用其它的技术来实现这个。

在响应过程中增加 HTML 解析器有个明显的缺点:这将增加页面加载的延时(到加载第一个字节所花的时间)。大多数情况下,所新增的延时被应用里的其他耗时掩盖掉了,比如数据库访问。为了解决这个问题,netjet 包含了一个可调节的 LRU 缓存,该缓存以 HTTP 的 ETag 头部作为索引,这使得 netjet 可以非常快的为已经解析过的页面插入 Link 头部。

不过,如果我们现在从头设计一款全新的应用,我们就应该考虑把页面内容和页面中的元数据分开存放,从而整体地减少 HTML 解析和其它可能增加的延时了。

任意的 Node.js HTML 框架,只要它支持类似 Express 这样的中间件,netjet 都是能够兼容的。只要把 netjet 像下面这样加到中间件加载链里就可以了。

 
   
   
 
  1. var express = require('express');

  2. var netjet = require('netjet');

  3. var root = '/path/to/static/folder';

  4. express()

  5.  .use(netjet({

  6.    cache: {

  7.      max: 100

  8.    }

  9.  }))

  10.  .use(express.static(root))

  11.  .listen(1337);

稍微加点代码,netjet 也可以摆脱 HTML 框架,独立工作:

 
   
   
 
  1. var http = require('http');

  2. var netjet = require('netjet');

  3. var port = 1337;

  4. var hostname = 'localhost';

  5. var preload = netjet({

  6.  cache: {

  7.    max: 100

  8.  }

  9. });

  10. var server = http.createServer(function (req, res) {

  11.  preload(req, res, function () {

  12.      res.statusCode = 200;

  13.      res.setHeader('Content-Type', 'text/html');

  14.      res.end('<!doctype html><h1>Hello World</h1>');

  15.  });

  16. });

  17. server.listen(port, hostname, function () {

  18.  console.log('Server running at http://' + hostname + ':' + port+ '/');

  19. });

netjet 文档里[6]有更多选项的信息。

查看推送了什么数据

访问本文[7]时,通过 Chrome 的开发者工具,我们可以轻松的验证网站是否正在使用服务器推送技术(LCTT 译注: Chrome 版本至少为 53)。在“Network”选项卡中,我们可以看到有些资源的“Initiator”这一列中包含了Push字样,这些资源就是服务器端推送的。

不过,目前 Firefox 的开发者工具还不能直观的展示被推送的资源。不过我们可以通过页面响应头部里的cf-h2-pushed头部看到一个列表,这个列表包含了本页面主动推送给浏览器的资源。

希望大家能够踊跃为 netjet 添砖加瓦,我也乐于看到有人正在使用 netjet。

Ghost 和服务端推送技术

Ghost 真是包罗万象。在 Ghost 团队的帮助下,我把 netjet 也集成到里面了,而且作为测试版内容可以在 Ghost 的 0.8.0 版本中用上它。

如果你正在使用 Ghost,你可以通过修改 config.js、并在production配置块中增加 preloadHeaders 选项来启用服务端推送。

 
   
   
 
  1. production: {

  2.  url: 'https://my-ghost-blog.com',

  3.  preloadHeaders: 100,

  4.  // ...

  5. }

Ghost 已经为其用户整理了一篇支持文档[8]

总结

使用 netjet,你的 Node.js 应用也可以使用浏览器预加载技术。并且 CloudFlare[9] 已经使用它在提供了 HTTP/2 服务端推送了。


via: https://blog.cloudflare.com/accelerating-node-js-applications-with-http-2-server-push/

本文由 LCTT 原创编译,Linux中国 荣誉推出


[1]: https://www.w3.org/wiki/LinkHeader
[2]: https://blog.cloudflare.com/using-http-2-server-push-with-php/
[3]: https://www.npmjs.com/package/netjet
[4]: https://blog.cloudflare.com/accelerating-node-js-applications-with-http-2-server-push/
[5]: https://ghost.org/
[6]: https://www.npmjs.com/package/netjet
[7]: https://blog.cloudflare.com/accelerating-node-js-applications-with-http-2-server-push/
[8]: http://support.ghost.org/preload-headers/
[9]: https://blog.cloudflare.com/accelerating-node-js-applications-with-http-2-server-push/
[10]: https://blog.cloudflare.com/author/terin-stock/

推荐文章

输入文章 ID 直达该文章

1211 是时候将Linux一分为二了吗?

3416 Ruby on Rails 发明人的告白:当我变成百万富翁的那天,我得到了什么呢?

3477 451:对不起,从法律上说,它不存在

将文章分享给朋友是对我们最好的赞赏!


以上是关于使用 HTTP/2 服务端推送技术加速 Node.js 应用的主要内容,如果未能解决你的问题,请参考以下文章

使用 socket.io 技术实现消息实时推送

Node.js之HTTP/2服务器推送

基于 Node.js 搭建 HTTP/2服务

HTTP/2 协议-服务端主动推送消息

Node构建WebSocket服务

利用 socket.io 实现消息实时推送