使用 HTTP2 服务端加速 Node.js应用方法

我们的目的是让优化 Node.js 网站变得更容易。我们开发了 netjet 中间件来解析 HTML 并自动插入 Link 头。在这个 Express 的例子中,可以看见增加的头部:

我们使用 Ghost 来增强本博客的性能,如果你的浏览器支持 HTTP2,你已经在不知不觉中受益于服务端推送了(请见博客原文——译者注)。下面还有更多。

在 netjet 中,我们使用 PostHTML 项目与一个普通插件一起解析 HTML。现在它查找的是图片、脚本和外链样式表。你也可以在其它环境中实现同样的技术。

在 HTTP 的响应中解析 HTML 有一个缺点:增加加载延迟(或者“首字节到达时间”)。大多数情况下,增加的延迟会被其它环节掩盖,如数据库访问。然而,netjet 包含了一个可伸缩的由 ETag 头实现的 LRU 缓存,允许对于了已经解析过页面快速插入 Link 头。

如果你在设计一个很有野心的应用,你应该在内容中嵌入资源上考虑存储源信息,移除 HTML 的解析过程,以及可能的延迟增加。

Netjet 与任何支持像 Express 中间件一样的 Node.js 框架兼容。入门就如把 netjet 加入中间件链一样简单。

var express = require('express'); 
var netjet = require('netjet'); 
var root = '/path/to/static/folder';

express() 
  .use(netjet({
    cache: {
      max: 100
    }
  }))
  .use(express.static(root))
  .listen(1337);
在没有任何框架的情况下使用 netjet,只需要一点点额外的工作。

var http = require('http');
var netjet = require('netjet');

var port = 1337;
var hostname = 'localhost';
var preload = netjet({
  cache: {
    max: 100
  }
});

var server = http.createServer(function (req, res) {
  preload(req, res, function () {
      res.statusCode = 200;
      res.setHeader('Content-Type', 'text/html');
      res.end('<!doctype html><h1>Hello World</h1>');
  });
});

server.listen(port, hostname, function () {
  console.log('Server running at http://' + hostname + ':' + port+ '/');
});
关于被支持的选项,请查阅 netjet 文档。

查看推送的资源

Chrome 的开发者工具使得鉴别网站是否使用服务端推送变得很简单。网络选项卡在 initiator 列的开头以 “push” 来标记被推送的资源。

不幸的是,Firefox 的开发者工具没有直接指明资源是否是被推送的。但是你可以查看页面响应头的 cf-h2-pushed 值,它包含了 CloudFlare 推送给浏览器的资源列表。

欢迎为 netjet 及其文档贡献力量。我很愿意听说有人在用 netjet。

Ghost 和服务端推送
Ghost(指 https://ghost.org/ —— 译者注) 是一个令人兴奋的整合平台。在 Ghost 团队的帮助下,我已经把 netjet 整合了进去,在 0.8.0 版本后已经可以作为一个可选的配置。

如果你在运行一个 Ghost 实例,你可以通过修改 config.js 文件、在 production 配置块中增加 preloadHeaders 选项的方式开启服务端推送。

production: { 
  url: 'https://my-ghost-blog.com',
  preloadHeaders: 100,
  // ...
}
Ghost 为用户提供了一个帮助文档 。

补充一下其它加还node.js的方法

异步

根据设计 Node.js 是单线程的。基于这点,同步代码会堵塞整个应用。比如说,多数的文件系统 API 都有它们的同步版本。下面代码演示了文件读取的同步和异步两种操作:

// Asynchronous
fs.readFile('file.txt', function(err, buffer) {
  var content = buffer.toString();
});

// Synchronous
var content = fs.readFileSync('file.txt').toString();
不过要是你执行那种长时间的阻塞操作,主线程就会被阻塞到这些操作完成为止。这大大降低你应用的性能。所以,最好确保你的代码里用的都是异步版本 API,最起码你应该在性能节点异步。而且,你在选用第三方模块的时候也要很小心。因为当你想方设法把同步操作从你代码中剔除之后,一个外部库的同步调用会让你前功尽弃,降低你的应用性能。

缓存

如果你用到一些不经常变化的数据,你应该把它们缓存起来,改善性能。比如说,下面的代码是获取最新帖子并显示的例子:

var router = express.Router();
 
router.route('/latestPosts').get(function(req, res) {
  Post.getLatest(function(err, posts) {
    if (err) {
      throw err;
    }
 
    res.render('posts', { posts: posts });
  });
});

如果你不经常发贴的话,你可以把帖子列表缓存起来,然后一段时间之后再把它们清理掉。比如,我们可以用 Redis 模块来达到这个目的。当然,你必须在你的服务器上装 Redis。然后你可以用叫做 node_redis 的客户端来保存键/值对。下面的例子演示我们怎么缓存帖子:

var redis = require('redis'),
    client = redis.createClient(null, null, { detect_buffers: true }),
    router = express.Router();
 
router.route('/latestPosts').get(function(req,res){
  client.get('posts', function (err, posts) {
    if (posts) {
      return res.render('posts', { posts: JSON.parse(posts) });
    }
 
    Post.getLatest(function(err, posts) {
      if (err) {
        throw err;
      }
 
      client.set('posts', JSON.stringify(posts));   
      res.render('posts', { posts: posts });
    });
  });
});
看到了吧,我们首先检查 Redis 缓存,看看是否有帖子。如果有,我们从缓存中拿这些帖子列表。否则我们就检索数据库内容,然后把结果缓存。此外,一定时间之后,我们可以清理 Redis 缓存,这样就可以更新内容了。

gzip 压缩

开启 gzip 压缩对你的 Web 应用会产生巨大影响。当一个 gzip 压缩浏览器请求某些资源的时候,服务器会在响应返回给浏览器之前进行压缩。如果你不用 gzip 压缩你的静态资源,浏览器拿到它们可能会花费更长时间。
在 Express 应用中,我们可以用内建 express.static() 中间件来处理静态内容。此外,还可以用 compression 中间件压缩和处理静态内容。下面是使用例:

var compression = require('compression');
 
app.use(compression()); //use compression
app.use(express.static(path.join(__dirname, 'public')));

总结

使用 netjet 后,你的 Node.js 应用可以开发使用浏览器预加载,在 CloudFlare 中,HTTP2 的服务端推送可以被开启。

时间: 2024-10-24 20:30:21

使用 HTTP2 服务端加速 Node.js应用方法的相关文章

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

四月份,我们宣布了对 HTTP/2 服务端推送技术的支持,我们是通过 HTTP 的 Link 头部来实现这项支持的.我的同事 John 曾经通过一个例子演示了在 PHP 里支持服务端推送功能是多么的简单. 我们想让现今使用 Node.js 构建的网站能够更加轻松的获得性能提升.为此,我们开发了 netjet 中间件,它可以解析应用生成的 HTML 并自动添加 Link 头部.当在一个示例的 Express 应用中使用这个中间件时,我们可以看到应用程序的输出多了如下 HTTP 头: 本博客是使用

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

netjet 使用了带有定制插件的 PostHTML 来解析 HTML.目前,netjet 用它来查找图片.脚本和外部 CSS 样式表.你也可以用其它的技术来实现这个. 在响应过程中增加 HTML 解析器有个明显的缺点:这将增加页面加载的延时(到加载第一个字节所花的时间).大多数情况下,所新增的延时被应用里的其他耗时掩盖掉了,比如数据库访问.为了解决这个问题,netjet 包含了一个可调节的 LRU 缓存,该缓存以 HTTP 的 ETag 头部作为索引,这使得 netjet 可以非常快的为已经解

NW.js —— 在浏览器端调用 Node.js 模块

NW.js 详细介绍 NW.js 可以让你直接在 DOM 上调用所有 Node.js 模块,相当于使用一种新的方法来编写 Web 应用.NW.js 的前身是 node-webkit . 特性: 使用 HTML5.CSS3.JS 和 WebGL 编写应用 完全支持 Node.js APIs 以及其 第三方模块 性能表现良好,Node 和 WebKit 运行在同一个线程,函数调用更直接,对象在同一个内存堆中,可直接引用 方便打包和分发 支持跨平台 演示程序:https://github.com/zc

为高负载网络优化Nginx和Node.js的方法_nginx

在搭建高吞吐量web应用这个议题上,NginX和Node.js可谓是天生一对.他们都是基于事件驱动模型而设计,可以轻易突破 Apache等传统web服务器的C10K瓶颈.预设的配置已经可以获得很高的并发,不过,要是大家想在廉价硬件上做到每秒数千以上的请求,还是有一些工作要做的. 这篇文章假定读者们使用NginX的HttpProxyModule来为上游的node.js服务器充当反向代理.我们将介绍Ubuntu 10.04以上系统sysctl的调优,以及node.js应用与NginX的调优.当然,如

在windows8.1的iis8.5服务下安装node.js开发环境

nodejs很久前就想玩玩,不过一直没时间,昨晚花了4个小时来捣鼓到iis上架设成功了,废话不说了. PS:我的系统是windows8.1 x64,所以自带iis8.5的,下载的文件也是x64的. No.1:下载文件 Nodejs http://www.nodejs.org/download/ 开发环境-windows2012 iis8.5"> iisnode https://github.com/tjanczuk/iisnode/wiki/iisnode-releases IIS URL

Ubuntu 11.10 安装Node.js的方法_javascript技巧

1.安装依赖包 复制代码 代码如下: sudo apt-get install g++ curl libssl-dev apache2-utils sudo apt-get install git-core 2.下载源代码 复制代码 代码如下: git clone git://github.com/ry/node.git 这一步是因网络状况较差一直显示 Cloning to node... 可以从官网上直接下载源代码,解压到帐号的文件夹里. 文件名改为了node. 3.编译 三句命令: 复制代码

Delphi2010中DataSnap高级技术(2)—DataSnap服务端和客户端发布分发方法

这几天继续研究DataSnap技术. 针对服务器和客户端软件,如何发布呢?经过研究发现,分发方法非常简单! 服务器发布方法: 1.在unit ServerMethodsUnit1单元中,添加uses MidasLib;(添加MidasLib的目的是省去发布Midas.dll) 2.我用的是火鸟数据库,只需拷贝dbxfb.dll和fbclient.dll 分发的服务器软件只需三个文件:你的服务器程序.dbxfb.dll 和 fbclient.dll 客户端发布方法: 1.在客户端程序中加上uses

在Ubuntu下安装Node.JS的不同方式

如果你要在Ubuntu 15.04上安装Node.js的话,这篇教程对你来说肯定很重要.Node.js从本质上来说就是一个运行在服务端上的封装好了输入输出流的javascript程序.Node.js巧妙的使用单线程的事件循环来处理高吞吐量和非阻塞IO.同时它也是一个提供了通过操作系统读写文件和网络操作功能的平台层.所以这篇文章将展示在Ubuntu 15.04 server上不同的安装Node.Js的方式. 安装Node.JS 的方法 有许多安装Node.JS的不同的方法,我们可以选择其一.通过本

句柄-js调用自己写的ActiveX控件 在服务端都OK

问题描述 js调用自己写的ActiveX控件 在服务端都OK js调用自己写的ActiveX控件 在服务端都OK 到客户端能安装注册就是找不到句柄 什么情况 在线等 解决方案 那你要看你的activex是否安装正确,已经安装到系统了吗? 这个需要管理员权限. regsvr32.exe 注册 解决方案二: 对的啊 都是成功的 regedit 也能查看到