让你的 Node.js 应用跑得更快的 10 个技巧

Node.js 受益于它的事件驱动和异步的特征,已经很快了。可是,在现代网络中只是快是不行的。若是你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异常的快。本文将介绍 10 条,通过检验得知可大大提升 Node 应用的技巧。废话很少说,让咱们逐条来看看。node

1. 并行

建立 Web 应用的时候,你可能要屡次调用内部 API 来获取各类数据。好比说,假设在 Dashboard 页面上,你要执行下面这几个调用:nginx

  • 用户信息 -getUserProfile().
  • 当前活动 -getRecentActivity().
  • 订阅内容 -getSubscriptions().
  • 通知内容 -getNotifications().

为了拿到这些信息,你应该会为每一个方法建立独立的中间件,而后将它们连接到 Dashboard 路由上。不过问题是,这些方法的执行是线性的,上一个没结束以前下一个不会开始。可行解决案是并行调用它们。git

如你所知因为异步性,Node.js 很是擅长并行调用多个方法。咱们不能暴殄天物。我上面提到的那些方法没有依赖性,因此咱们能够并行执行它们。这样咱们能够削减中间件数量,大幅提升速度。angularjs

咱们能够用 async.js 来处理并行,它是一个专门用来调教 JavaScript 异步的 Node 模块。下面代码演示怎样用 async.js 并行调用多个方法的:github

function runInParallel() {
  async.parallel([
    getUserProfile,
    getRecentActivity,
    getSubscriptions,
    getNotifications
  ], function(err, results) {
    //This callback runs when all the functions complete
  });
}

若是你想更深刻了解 async.js ,请移步它的 GitHub 页面。web

2. 异步

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

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

// Synchronous
var content = fs.readFileSync('file.txt').toString();

不过要是你执行那种长时间的阻塞操做,主线程就会被阻塞到这些操做完成为止。这大大下降你应用的性能。因此,最好确保你的代码里用的都是异步版本 API,最起码你应该在性能节点异步。并且,你在选用第三方模块的时候也要很当心。由于当你千方百计把同步操做从你代码中剔除以后,一个外部库的同步调用会让你前功尽弃,下降你的应用性能。mongodb

3. 缓存

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

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 的客户端来保存键/值对。下面的例子演示咱们怎么缓存帖子:express

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 缓存,这样就能够更新内容了。

4. 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')));

5. 若是能够,在用客户端渲染

如今有超多功能强劲的客户端 MVC/MVVM 框架,好比说 AngularJS, Ember, Meteor, 等等,构建一个单页面应用变得很是简单。基本上,你只要公开一个 API,返回 JSON 响应给客户端就能够了,而不须要在服务端渲染页面。在客户端,你能够用框架来组织 JSON 而后把它们显示在 UI 上。服务端只发送 JSON 响应能够节省带宽,改善性能,由于你不须要在每一个响应里面都返回布局标记了,对吧,你只须要返回纯 JSON,而后在客户端渲染它们。

看下个人这个教程,它是关于怎样用 Express 4 公开一个 RESTful APIs的。我还写了另外一篇教程,演示了怎样把这些 APIs 和 AngularJS 结合起来。

6. 不要在 Sessions 存储太多数据

典型的 Express 页面应用, Session 数据默认是保存在内存中的。当你把太多数据保存在 Session 的时候,会致使服务器开销显著增大。因此,要么你切换到别的储存方式来保存 Session 数据,要么尽可能减小存储在 Session 中的数据量。

好比说,当用户登陆到你的应用的时候,你能够只在 Session 中保存他们的 ID 而不是整个用户数据对象。还有,对于那些你可以从 id 拿到对象的查询,你应该会喜欢用  MongoDB 或者 Redis 来存储 session 数据。

7. 优化查询

假设你有个博客,你要在主页上显示最新帖子。你可能会经过 Mongoose 这样取数据:

Post.find().limit(10).exec(function(err, posts) {
  //send posts to client
});

不过问题是 Mongoose 的 find() 方法会把对象的全部字段都查询出来,而许多字段在主页上并不要求。好比说,commentsis 保存的是特定帖子的回复。咱们不须要显示文章回复,因此咱们能够在查询的时候把它给剔除掉。这无疑会提升速度。能够像这样优化上面那条查询:

Post.find().limit(10).exclude('comments').exec(function(err, posts) {
  //send posts to client
});

8. 用标准的 V8 方法

集合上的一些操做,好比 map,reduce,和 forEach 不必定支持全部浏览器。咱们能够经过前台的库解决部分浏览器兼容性问题。但对于 Node.js,你要确切知道 Google 的 V8 JavaScript 引擎支持哪些操做。这样,你就能够在服务端直接用这些内建方法来操做集合了。

9. 在 Node 前面用 Nginx

Nginx 是个微小型轻量 Web 服务器,用它能够下降你的 Node.js 服务器的负载。你能够把静态资源配置到 nginx 上,而不是在 Node 上。你能够在 nginx 上用 gzip 压缩响应,让全部的响应都变得更小。因此,若是你有个正在营运的产品,我以为你应该会想用 nginx 来改善运行速度的。

10. 打包 JavaScript

最后,你还能够大大提升页面应用速度,经过把多个 JS 文件打包。当浏览器在页面渲染中碰到 <script> 元素的时候会被堵塞,直到拿到这个脚本才继续运行(除非设置了异步属性)。好比,若是你的页面有五个 JavaScript 文件,浏览器会发出五个独立的 HTTP 请求来获取他们。若是把这五个文件压缩打包成一个,总体性能将能够大幅提高。CSS 文件也是同样。你能够用诸如 Grunt/Gulp 这样的编译工具来打包你的资源文件。

结论

上面 10 条技巧确定能够提升你的 Web 应用的速度的。不过,我知道还有改善和优化的空间。若是你有任何改善性能的技巧的话,在回复里告诉我。

英文原文:10 Tips to Make Your Node.js Web App Faster
出处:让你的 Node.js 应用跑得更快的 10 个技巧

相关文章
相关标签/搜索