極速Node.js:來自LinkedIn的10個性能提高祕籍

from:http://faylai.iteye.com/blog/1293194javascript

 

一、避免使用同步的方法css

 

nodejs 是基於單線程。爲了讓單線程可以處理高併發的請求,咱們儘可能要避免讓線程等待,阻塞,同步,和長時間運行某項操做。nodejs 一個顯著的特色就是徹頭徹尾的異步。這個特性在基於事件驅動的應用上表現的很是的出色。html

 

不幸的是在nodejs 中仍然存在能夠同步或者阻塞調用方法。例如,許多的文件系統操做既有異步的方法也有同步的方法,像 fs.writeFile 和 fs.writeFileSync。儘管你避免在代碼中使用同步的方法,但你引用的外部庫中可能包含導致阻塞的方法調用。一旦這種狀況出現,將會對性能產生顯著的影響。java

 

// 正確寫法: 異步的寫文件
fs . writeFile ( 'message.txt' , 'Hello Node' , function ( err ) {
console . log ( "It's saved and the server remains responsive!" );
});
 
// 音響性能的寫法: 同步的寫文件
fs . writeFileSync ( 'message.txt' , 'Hello Node' );
console . log ( "It's saved, but you just blocked ALL requests!" );
二、關閉 socket 鏈接池

nodejs http client 自動使用socket 鏈接池,默認狀況下每一個主機將socket per 限制到五個。當socket 被回收重用後資源的增加將會沒法控制,特別是你要處理從同一主機發送大量併發請求數據時候將會致使嚴重的性能瓶頸。這種狀況下,最好的解決辦法是增長 maxSockets 或者禁用 socket 鏈接池:node

 

var http = require ( 'http' );
var options = {.....};
options . agent = false ;
var req = http . request ( options )
三、不要用nodejs 來管理靜態資源
靜態資源像css文化和圖片文件,可使用其餘的web服務器來管理,好比 nginx ,或者你把你的文件上傳到CDNs.
這樣作有兩個好處:(1)減小nodejs 的負載(2)CDNs可選擇最近的服務器然投遞靜態內容減小了傳輸延遲。
四、渲染放到客戶端
讓咱們快速比較下頁面在服務端渲染和客戶端渲染區別。若是咱們用nodejs 渲染,每次請求咱們返回的html以下:
<html>
<head>
<title>LinkedIn Mobile </title>
</head>
<body>
<div class= "header" >
<img src= "http://mobile-cdn.linkedin.com/images/linkedin.png" alt= "LinkedIn" />
</div>
<div class= "body" >
Hello John!
</div>
</body>
</html>
顯然的除了用戶的名字是動態,其餘都是靜態。也就是說相同東西每次都要加載一遍。更有效的方法就是直接讓
nodejs 返回動態的json數據:
{"name": "John"}
剩下的靜態標籤可使用javascript 模版引擎
<html>
<head>
<title>LinkedIn Mobile </title>
</head>
<body>
<div class= "header" >
<img src= "http://mobile-cdn.linkedin.com/images/linkedin.png" alt= "LinkedIn" />
</div>
<div class= "body" >
Hello <%= name %>!
</div>
</body>
</html>
靜態javascript 模版能夠用nginx 代理,其實若是放到CDN就更好了。
另外你能夠在模版第一次時保存到瀏覽器緩存中或者存放到 本地存儲中。以後頁面初始化完畢,
就剩下動態的json數據 的交互。大大減少了cpu 時間和io 負載。
 
五、開啓gzip
愈來愈多的web服務器和客戶端支持gzip 壓縮。
這個好處真的不要放過哦,不論是響應客戶端或者請求服務均可以採用。
六、使用並行
試着把請求遠程服務,數據庫調用,文件系統訪問這些操做並行起來運行。若是按照線性的步驟來運行這些費時
的操做延遲總量等於每一個操做延時總和。推薦使用 Step 來管理你的callback 流程。
七、儘可能不要使用session
Express framework 管理request/response 的生命週期,許多 express 的例子包含下面的配置:
app . use ( express . session ({ secret : "keyboard cat" }));
 
默認狀況下,seesion 是存儲在內存中的,這個會增長服務器的額外開銷,特別用戶量增長時候。
你能夠把session 存儲到數據庫,例如MongoDB 或者Redis ,
可是每一個請求的都會從數據庫查詢session 信息這樣也增長了額外的性能開銷。
若是能夠,最好的選擇不要在服務端存儲狀態信息。express 中沒這樣的配置,可是性能提高是顯然。
八、使用二進制模塊
若是能夠,使二進制模塊來取代javascript 的模塊,
例如當咱們從用javascript 寫SHA 的模塊切換到編譯成二進制模塊時,咱們發現很大性能提高空間。
// 使用本地內置的二進制模塊
var crypto = require ( 'crypto' );
var hash = crypto . createHmac ( "sha1" , key ). update ( signatureBase ). digest ( "base64" );
九、使用標準v8 javascript 而不是客戶端庫
許多的javacript 庫專門用於web瀏覽器,
這些瀏覽器的javascript 引擎不一致:有些瀏覽器支持某些方法像 forEach,map 和reduce,
可是其餘的瀏覽器沒有這些方法。
結果致使,客戶端庫含有許多有損性能的代碼來保證方法的兼容。
話說回來,你要準確的知道nodejs 哪些方法是能夠用的:nodejs 使用v8 引擎 ,v8 實現了   ECMA-262, 5th edition . 直接使用v8標準函數將會得到大的性能提高。
 
十、 保持代碼簡潔
 
保持的你的代碼的清潔不論是客戶端或者服務端。不斷的審視本身:"咱們真須要這個模塊嗎?","爲何須要這個框架","性能的消耗值得嗎?","是否有更簡單的方法?"。簡潔的代碼每每更加的高效。
相關文章
相關標籤/搜索