首頁  >  文章  >  web前端  >  優化Node.js Web應用程式運行速度的10個技巧_node.js

優化Node.js Web應用程式運行速度的10個技巧_node.js

WBOY
WBOY原創
2016-05-16 16:37:421020瀏覽

Node.js 受益於它的事件驅動和非同步的特徵,已經很快了。但是,在現代網路中只是快是不行的。如果你打算用 Node.js 開發你的下一個Web 應用程式的話,那麼你就應該無所不用其極,讓你的應用更快,異常的快。本文將介紹 10 條,經過檢驗得知可大幅提升 Node 應用的技巧。廢話不多說,讓我們逐一來看看。

1. 並行

創建 Web 應用的時候,你可能要多次呼叫內部 API 來取得各種資料。比如說,假設在 Dashboard 頁面上,你要執行下面這幾個呼叫:

使用者資訊 -getUserProfile().

當前活動 -getRecentActivity().

訂閱內容 -getSubscriptions().

通知內容 -getNotifications().

為了拿到這些訊息,你應該會為每個方法建立獨立的中間件,然後將它們連結到 Dashboard 路由上。不過問題是,這些方法的執行是線性的,在上一個沒結束前下一個不會開始。可行解決案是並行調用它們。

如你所知由於非同步性,Node.js 非常擅長並行呼叫多個方法。我們不能暴殄天物。我上面提到的那些方法沒有依賴性,所以我們可以並行執行它們。這樣我們可以削減中間件數量,大幅提高速度。

我們可以用async.js來處理並行,它是一個專門用來調教 JavaScript 非同步的 Node 模組。下面程式碼示範怎樣用 async.js 並行呼叫多個方法的:

複製程式碼 程式碼如下:

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

如果你想更深入了解 async.js ,請移步它的 GitHub 頁面。

2. 非同步

根據設計 Node.js 是單線程的。基於這一點,同步程式碼會堵塞整個應用程式。比如說,多數的檔案系統 API 都有它們的同步版本。下面程式碼示範了檔案讀取的同步和非同步兩種操作:

複製程式碼 程式碼如下:

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

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


不過要是你執行那種長時間的阻塞操作,主執行緒就會被阻塞到這些操作完成為止。這大大降低你應用的效能。所以,最好確保你的程式碼裡用的都是非同步版本 API,最起碼你應該在效能節點異步。而且,你在選用第三方模組的時候也要很小心。因為當你想辦法把同步操作從你程式碼中剔除之後,一個外部函式庫的同步呼叫會讓你前功盡棄,降低你的應用效能。

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的客戶端來儲存鍵/值對。下面的範例示範我們怎麼快取貼文:
複製程式碼 程式碼如下:

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 這樣的編譯工具來包裝你的資源檔案。 </script>

結論

上面 10 個技巧肯定可以提高你的 Web 應用的速度的。不過,我知道還有改善和優化的空間。如果你有任何改善性能的技巧的話,在回覆裡告訴我。

謝謝閱讀!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn