Node.js 受益于它的事件驱动和异步的特征,已经很快了。可是,在现代网络中只是快是不行的。若是你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异常的快。本文将介绍 10 条,通过检验得知可大大提升 Node 应用的技巧。废话很少说,让咱们逐条来看看。node
建立 Web 应用的时候,你可能要屡次调用内部 API 来获取各类数据。好比说,假设在 Dashboard 页面上,你要执行下面这几个调用:nginx
为了拿到这些信息,你应该会为每一个方法建立独立的中间件,而后将它们连接到 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
根据设计 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
若是你用到一些不常常变化的数据,你应该把它们缓存起来,改善性能。好比说,下面的代码是获取最新帖子并显示的例子:数据库
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 缓存,这样就能够更新内容了。
开启 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')));
如今有超多功能强劲的客户端 MVC/MVVM 框架,好比说 AngularJS, Ember, Meteor, 等等,构建一个单页面应用变得很是简单。基本上,你只要公开一个 API,返回 JSON 响应给客户端就能够了,而不须要在服务端渲染页面。在客户端,你能够用框架来组织 JSON 而后把它们显示在 UI 上。服务端只发送 JSON 响应能够节省带宽,改善性能,由于你不须要在每一个响应里面都返回布局标记了,对吧,你只须要返回纯 JSON,而后在客户端渲染它们。
看下个人这个教程,它是关于怎样用 Express 4 公开一个 RESTful APIs的。我还写了另外一篇教程,演示了怎样把这些 APIs 和 AngularJS 结合起来。
典型的 Express 页面应用, Session 数据默认是保存在内存中的。当你把太多数据保存在 Session 的时候,会致使服务器开销显著增大。因此,要么你切换到别的储存方式来保存 Session 数据,要么尽可能减小存储在 Session 中的数据量。
好比说,当用户登陆到你的应用的时候,你能够只在 Session 中保存他们的 ID 而不是整个用户数据对象。还有,对于那些你可以从 id 拿到对象的查询,你应该会喜欢用 MongoDB 或者 Redis 来存储 session 数据。
假设你有个博客,你要在主页上显示最新帖子。你可能会经过 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 });
集合上的一些操做,好比 map,reduce,和 forEach 不必定支持全部浏览器。咱们能够经过前台的库解决部分浏览器兼容性问题。但对于 Node.js,你要确切知道 Google 的 V8 JavaScript 引擎支持哪些操做。这样,你就能够在服务端直接用这些内建方法来操做集合了。
Nginx 是个微小型轻量 Web 服务器,用它能够下降你的 Node.js 服务器的负载。你能够把静态资源配置到 nginx 上,而不是在 Node 上。你能够在 nginx 上用 gzip 压缩响应,让全部的响应都变得更小。因此,若是你有个正在营运的产品,我以为你应该会想用 nginx 来改善运行速度的。
最后,你还能够大大提升页面应用速度,经过把多个 JS 文件打包。当浏览器在页面渲染中碰到 <script> 元素的时候会被堵塞,直到拿到这个脚本才继续运行(除非设置了异步属性)。好比,若是你的页面有五个 JavaScript 文件,浏览器会发出五个独立的 HTTP 请求来获取他们。若是把这五个文件压缩打包成一个,总体性能将能够大幅提高。CSS 文件也是同样。你能够用诸如 Grunt/Gulp 这样的编译工具来打包你的资源文件。
上面 10 条技巧确定能够提升你的 Web 应用的速度的。不过,我知道还有改善和优化的空间。若是你有任何改善性能的技巧的话,在回复里告诉我。
英文原文:10 Tips to Make Your Node.js Web App Faster
出处:让你的 Node.js 应用跑得更快的 10 个技巧