欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

優(yōu)化Node.js Web應(yīng)用運(yùn)行速度的10個(gè)技巧

 更新時(shí)間:2014年09月03日 09:01:23   投稿:junjie  
這篇文章主要介紹了優(yōu)化Node.js Web應(yīng)用運(yùn)行速度的10個(gè)技巧,本文講解了從并行、異步、緩存、gzip 壓縮、客戶端渲染等等技巧,需要的朋友可以參考下

Node.js 受益于它的事件驅(qū)動(dòng)和異步的特征,已經(jīng)很快了。但是,在現(xiàn)代網(wǎng)絡(luò)中只是快是不行的。如果你打算用 Node.js 開(kāi)發(fā)你的下一個(gè)Web 應(yīng)用的話,那么你就應(yīng)該無(wú)所不用其極,讓你的應(yīng)用更快,異常的快。本文將介紹 10 條,經(jīng)過(guò)檢驗(yàn)得知可大大提高 Node 應(yīng)用的技巧。廢話不多說(shuō),讓我們逐條來(lái)看看。

1. 并行

創(chuàng)建 Web 應(yīng)用的時(shí)候,你可能要多次調(diào)用內(nèi)部 API 來(lái)獲取各種數(shù)據(jù)。比如說(shuō),假設(shè)在 Dashboard 頁(yè)面上,你要執(zhí)行下面這幾個(gè)調(diào)用:

用戶信息 -getUserProfile().

當(dāng)前活動(dòng) -getRecentActivity().

訂閱內(nèi)容 -getSubscriptions().

通知內(nèi)容 -getNotifications().

為了拿到這些信息,你應(yīng)該會(huì)為每個(gè)方法創(chuàng)建獨(dú)立的中間件,然后將它們鏈接到 Dashboard 路由上。不過(guò)問(wèn)題是,這些方法的執(zhí)行是線性的,上一個(gè)沒(méi)結(jié)束之前下一個(gè)不會(huì)開(kāi)始。可行解決案是并行調(diào)用它們。

如你所知由于異步性,Node.js 非常擅長(zhǎng)并行調(diào)用多個(gè)方法。我們不能暴殄天物。我上面提到的那些方法沒(méi)有依賴性,所以我們可以并行執(zhí)行它們。這樣我們可以削減中間件數(shù)量,大幅提高速度。

我們可以用async.js來(lái)處理并行,它是一個(gè)專門(mén)用來(lái)調(diào)教 JavaScript 異步的 Node 模塊。下面代碼演示怎樣用 async.js 并行調(diào)用多個(gè)方法的:

復(fù)制代碼 代碼如下:

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

如果你想更深入了解 async.js ,請(qǐng)移步它的 GitHub 頁(yè)面。

2. 異步

根據(jù)設(shè)計(jì) Node.js 是單線程的。基于這點(diǎn),同步代碼會(huì)堵塞整個(gè)應(yīng)用。比如說(shuō),多數(shù)的文件系統(tǒng) API 都有它們的同步版本。下面代碼演示了文件讀取的同步和異步兩種操作:

復(fù)制代碼 代碼如下:

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

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


不過(guò)要是你執(zhí)行那種長(zhǎng)時(shí)間的阻塞操作,主線程就會(huì)被阻塞到這些操作完成為止。這大大降低你應(yīng)用的性能。所以,最好確保你的代碼里用的都是異步版本 API,最起碼你應(yīng)該在性能節(jié)點(diǎn)異步。而且,你在選用第三方模塊的時(shí)候也要很小心。因?yàn)楫?dāng)你想方設(shè)法把同步操作從你代碼中剔除之后,一個(gè)外部庫(kù)的同步調(diào)用會(huì)讓你前功盡棄,降低你的應(yīng)用性能。

3. 緩存

如果你用到一些不經(jīng)常變化的數(shù)據(jù),你應(yīng)該把它們緩存起來(lái),改善性能。比如說(shuō),下面的代碼是獲取最新帖子并顯示的例子:

復(fù)制代碼 代碼如下:

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 });
  });
});


如果你不經(jīng)常發(fā)貼的話,你可以把帖子列表緩存起來(lái),然后一段時(shí)間之后再把它們清理掉。比如,我們可以用Redis模塊來(lái)達(dá)到這個(gè)目的。當(dāng)然,你必須在你的服務(wù)器上裝 Redis。然后你可以用叫做 node_redis的客戶端來(lái)保存鍵/值對(duì)。下面的例子演示我們?cè)趺淳彺嫣?
復(fù)制代碼 代碼如下:

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 緩存,看看是否有帖子。如果有,我們從緩存中拿這些帖子列表。否則我們就檢索數(shù)據(jù)庫(kù)內(nèi)容,然后把結(jié)果緩存。此外,一定時(shí)間之后,我們可以清理 Redis 緩存,這樣就可以更新內(nèi)容了。

4. gzip 壓縮

開(kāi)啟 gzip 壓縮對(duì)你的 Web 應(yīng)用會(huì)產(chǎn)生巨大影響。當(dāng)一個(gè) gzip 壓縮瀏覽器請(qǐng)求某些資源的時(shí)候,服務(wù)器會(huì)在響應(yīng)返回給瀏覽器之前進(jìn)行壓縮。如果你不用 gzip 壓縮你的靜態(tài)資源,瀏覽器拿到它們可能會(huì)花費(fèi)更長(zhǎng)時(shí)間。

在 Express 應(yīng)用中,我們可以用內(nèi)建 express.static() 中間件來(lái)處理靜態(tài)內(nèi)容。此外,還可以用 compression 中間件壓縮和處理靜態(tài)內(nèi)容。下面是使用例:

復(fù)制代碼 代碼如下:

var compression = require('compression');

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

5. 如果可以,在用客戶端渲染

現(xiàn)在有超多功能強(qiáng)勁的客戶端 MVC/MVVM 框架,比如說(shuō)AngularJS,Ember,Meteor, 等等,構(gòu)建一個(gè)單頁(yè)面應(yīng)用變得非常簡(jiǎn)單。基本上,你只要公開(kāi)一個(gè) API,返回JSON響應(yīng)給客戶端就可以了,而不需要在服務(wù)端渲染頁(yè)面。在客戶端,你可以用框架來(lái)組織 JSON 然后把它們顯示在 UI 上。服務(wù)端只發(fā)送 JSON 響應(yīng)可以節(jié)省帶寬,改善性能,因?yàn)槟悴恍枰诿總€(gè)響應(yīng)里面都返回布局標(biāo)記了,對(duì)吧,你只需要返回純 JSON,然后在客戶端渲染它們。

看下我的 這個(gè)教程 ,它是關(guān)于怎樣用 Express 4 公開(kāi)一個(gè) RESTful APIs的。我還寫(xiě)了 另一篇教程 ,演示了怎樣把這些 APIs 和 AngularJS 結(jié)合起來(lái)。

6. 不要在 Sessions 存儲(chǔ)太多數(shù)據(jù)

典型的Express頁(yè)面應(yīng)用, Session 數(shù)據(jù)默認(rèn)是保存在內(nèi)存中的。當(dāng)你把太多數(shù)據(jù)保存在 Session 的時(shí)候,會(huì)導(dǎo)致服務(wù)器開(kāi)銷顯著增大。所以,要么你切換到別的儲(chǔ)存方式來(lái)保存 Session 數(shù)據(jù),要么盡量減少存儲(chǔ)在 Session 中的數(shù)據(jù)量。

比如說(shuō),當(dāng)用戶登錄到你的應(yīng)用的時(shí)候,你可以只在 Session 中保存他們的 ID 而不是整個(gè)用戶數(shù)據(jù)對(duì)象。還有,對(duì)于那些你能夠從 id 拿到對(duì)象的查詢,你應(yīng)該會(huì)喜歡用MongoDB或者Redis來(lái)存儲(chǔ) session 數(shù)據(jù)。

7. 優(yōu)化查詢

假設(shè)你有個(gè)博客,你要在主頁(yè)上顯示最新帖子。你可能會(huì)通過(guò)Mongoose這樣取數(shù)據(jù):

復(fù)制代碼 代碼如下:

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

不過(guò)問(wèn)題是 Mongoose 的 find() 方法會(huì)把對(duì)象的所有字段都查詢出來(lái),而許多字段在主頁(yè)上并不要求。比如說(shuō),commentsis 保存的是特定帖子的回復(fù)。我們不需要顯示文章回復(fù),所以我們可以在查詢的時(shí)候把它給剔除掉。這無(wú)疑會(huì)提高速度??梢韵襁@樣優(yōu)化上面那條查詢:
復(fù)制代碼 代碼如下:

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

8. 用標(biāo)準(zhǔn)的 V8 方法

集合上的一些操作,比如 map,reduce,和 forEach 不一定支持所有瀏覽器。我們可以通過(guò)前臺(tái)的庫(kù)解決部分瀏覽器兼容性問(wèn)題。但對(duì)于 Node.js,你要確切知道 Google 的V8 JavaScript 引擎支持哪些操作。這樣,你就可以在服務(wù)端直接用這些內(nèi)建方法來(lái)操作集合了。

9. 在 Node 前面用 Nginx

Nginx是個(gè)微小型輕量 Web 服務(wù)器,用它可以降低你的Node.js服務(wù)器的負(fù)載。你可以把靜態(tài)資源配置到 nginx 上,而不是在 Node 上。你可以在 nginx 上用 gzip 壓縮響應(yīng),讓所有的響應(yīng)都變得更小。所以,如果你有個(gè)正在營(yíng)運(yùn)的產(chǎn)品,我覺(jué)得你應(yīng)該會(huì)想用 nginx 來(lái)改善運(yùn)行速度的。

10. 打包 JavaScript

最后,你還可以大大提高頁(yè)面應(yīng)用速度,通過(guò)把多個(gè) JS 文件打包。當(dāng)瀏覽器在頁(yè)面渲染中碰到 <script> 元素的時(shí)候會(huì)被堵塞,直到拿到這個(gè)腳本才繼續(xù)運(yùn)行(除非設(shè)置了異步屬性)。比如,如果你的頁(yè)面有五個(gè) JavaScript 文件,瀏覽器會(huì)發(fā)出五個(gè)獨(dú)立的 HTTP 請(qǐng)求來(lái)獲取他們。如果把這五個(gè)文件壓縮打包成一個(gè),整體性能將可以大幅提升。CSS 文件也是一樣。你可以用諸如 Grunt/Gulp 這樣的編譯工具來(lái)打包你的資源文件。

結(jié)論

上面 10 條技巧肯定可以提高你的 Web 應(yīng)用的速度的。不過(guò),我知道還有改善和優(yōu)化的空間。如果你有任何改善性能的技巧的話,在回復(fù)里告訴我。

謝謝閱讀!

相關(guān)文章

  • NodeJS連接MongoDB數(shù)據(jù)庫(kù)時(shí)報(bào)錯(cuò)的快速解決方法

    NodeJS連接MongoDB數(shù)據(jù)庫(kù)時(shí)報(bào)錯(cuò)的快速解決方法

    下面小編就為大家?guī)?lái)一篇NodeJS連接MongoDB數(shù)據(jù)庫(kù)時(shí)報(bào)錯(cuò)的快速解決方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考
    2016-05-05
  • nodejs轉(zhuǎn)換音頻文件格式并壓縮導(dǎo)出zip格式(vscode語(yǔ)音插件開(kāi)發(fā))

    nodejs轉(zhuǎn)換音頻文件格式并壓縮導(dǎo)出zip格式(vscode語(yǔ)音插件開(kāi)發(fā))

    FFmpeg是一套開(kāi)源的音視頻處理工具,通俗地講,可以對(duì)音視頻文件進(jìn)行剪切、拼接、水印、轉(zhuǎn)碼等處理,這篇文章主要介紹了nodejs轉(zhuǎn)換音頻文件格式并壓縮導(dǎo)出zip格式(vscode語(yǔ)音插件開(kāi)發(fā)),需要的朋友可以參考下
    2023-05-05
  • Node使用Nodemailer發(fā)送郵件的方法實(shí)現(xiàn)

    Node使用Nodemailer發(fā)送郵件的方法實(shí)現(xiàn)

    這篇文章主要介紹了Node使用Nodemailer發(fā)送郵件的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 使用Node.js實(shí)現(xiàn)簡(jiǎn)易MVC框架的方法

    使用Node.js實(shí)現(xiàn)簡(jiǎn)易MVC框架的方法

    下面小編就為大家?guī)?lái)一篇使用Node.js實(shí)現(xiàn)簡(jiǎn)易MVC框架的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • node.js從數(shù)據(jù)庫(kù)獲取數(shù)據(jù)

    node.js從數(shù)據(jù)庫(kù)獲取數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了node.js從數(shù)據(jù)庫(kù)獲取數(shù)據(jù)的具體代碼,nodejs可以獲取具體某張數(shù)據(jù)表信息,感興趣的朋友可以參考一下
    2016-05-05
  • Nodejs使用mysql2操作數(shù)據(jù)庫(kù)的方法完整講解

    Nodejs使用mysql2操作數(shù)據(jù)庫(kù)的方法完整講解

    MySQL2是一個(gè)基于Node.js的MySQL數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序,它是MySQL官方推薦的驅(qū)動(dòng)之一,下面這篇文章主要給大家介紹了關(guān)于Nodejs使用mysql2操作數(shù)據(jù)庫(kù)的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • 深入理解Node.js中通用基礎(chǔ)設(shè)計(jì)模式

    深入理解Node.js中通用基礎(chǔ)設(shè)計(jì)模式

    大家在談到設(shè)計(jì)模式時(shí)最先想到的就是 singletons, observers(觀察者) 或 factories(工廠方法)。本文重點(diǎn)給大家介紹Node.JS一些基礎(chǔ)模式的實(shí)現(xiàn)方法,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2017-09-09
  • 淺析Node.js的Stream模塊中的Readable對(duì)象

    淺析Node.js的Stream模塊中的Readable對(duì)象

    這篇文章主要介紹了淺析Node.js的Stream模塊中的Readable對(duì)象,是Node.js入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-07-07
  • Node.js如何對(duì)SQLite的async/await封裝詳解

    Node.js如何對(duì)SQLite的async/await封裝詳解

    這篇文章主要給大家介紹了關(guān)于Node.js如何對(duì)SQLite的async/await進(jìn)行封裝的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • node實(shí)現(xiàn)socket鏈接與GPRS進(jìn)行通信的方法

    node實(shí)現(xiàn)socket鏈接與GPRS進(jìn)行通信的方法

    這篇文章主要介紹了node實(shí)現(xiàn)socket鏈接與GPRS進(jìn)行通信的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05

最新評(píng)論