歡迎您光臨本站 註冊首頁

前端性能優化指南

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  

在“A Node.JS Holiday Season”系列叢書的這一章中,我們將會討論一些前端性能和介紹一些基於Mozilla的快速開發工具。

我們將要使用前段性能自動化中非常重要的工具之一的connect-cachify。

開始之前,讓我們簡要重述一下作為開發者如何讓機器運行的更穩定。如果你已經了解前端最優化的方法,請跳過前面的部分,了解如何使用connect-cachify完成自動化功能。

 


3c 客戶端性能優化

網站上到處都是與性能優化相關的最佳實踐的信息。雖然存在許多先進的技術可以為你的網站調整每一毫秒,但有三種基本工具是最基礎的——連接、壓縮和緩存。

 

連接

連接的目標是盡量減少對伺服器發出的請求數量。伺服器請求是昂貴的。建立一個HTTP連接所需的時間有時比傳送數據本身所花的時間還要多。每個請求增加很多用於檢測你的網站的開銷,尤其是在移動設備上,這會造成顯著的連接延遲。你是否用手機通過Edge網路瀏覽過一個購物網站,上面的圖片一個一個蹦出來?這就是連接延時的現象。


 

 
 

SPDY是一個構建在HTTP協議之上的新協議,旨在通過合併多個資源請求到一個單一的HTTP請求來減少頁面載入時間。不幸的是,目前只有最新版本的Firefox、Chrome和Opera瀏覽器支持這個新協議。

儘可能的合併外部資源,可能方法過時,但是可以跨瀏覽器工作,並且不會因為SPDY的到來而退化。已經有很多用來合併JavaScript、CSS和圖片這三種最常見外部資源的工具。
 

JavaScript & CSS

當一個網站有多個外部的JS時,需要把他們合併成一個文件。在JS載入完成前,瀏覽器會阻止掉所有的渲染。(也就是你看不到JS的效果)。被請求的JS文件將會出現延遲,比如執行下面的代碼將會花費更長的時間。

1 <script src="jquery.min.js"></script>

2 <script src="main.js"></script>

3 <script src="image-carousel.js"></script>

4 <script src="widget.js"></script>

把四個Js文件整合成一個,將會減少延遲時間。(像下面這樣)
1 <script src="main.production.js"></script>

使用整合過的JS有一點難度,所以大多數情況下,使用在正式的項目中。
 

Css和進程也是一樣,在做項目的時候也應該整合到一起。

 

Images
Data URIs和image sprites減少請求圖片的兩種基本方法。

data: URI
data URI一個URL的特殊形式,直接把圖片嵌入到HTML或者CSS裡面。Data URIs可以作為img的src標籤或者是CSS中background-image的url值。因為嵌入圖片是基於base64編碼的,所以他們需要更多的空間,好處是比之前的二進位圖像少了一次HTTP請求。所以,當要嵌入的圖片很小時,由於圖片編碼產生的大小往往被減少一次HTTP請求所抵消。

註:IE6和IE7都不支持 data URIs

 

Image sprites

Image sprites在data URI不能用的時候會是一個很好的選擇。image sprite是用很多小圖像組合而成的一張大圖片。一旦這個圖片生成后,CSS就可以用來顯示指定部分的圖片。許多工具都是用來做這種圖片的。

缺點是維護起來麻煩,當你要添加、刪除或者修改一個圖片時,你需要修改其對應的CSS。

Sprite Cow幫你獲得sprites 的 background-position, width and height並生成一個可複製的css表。

 

刪掉多餘的位元組 – 精簡,優化,壓縮

組合資源,減少訪問次數可以有效的提升訪問速度,除此之外,也應該精簡向用戶傳遞的數據。 精簡,優化,壓縮也是減少位元組的通常做法。


 

 

JavaScript & CSS

JavaScript和CSS作為文本資源,可以通過去除瀏覽器中無關的代碼實現精簡。一般情況下,JS和CSS採用的方法是刪掉多餘的註釋和空格。JS的精簡更加複雜,一些人刪掉命名規則中的不必要的部分,把變數的命名縮短,甚至有人用更短的代碼替換較長的代碼來實現。

UglifyJS,YUICompressor還有Google Closure Compiler是三個常用的JS精簡工具。

YUICompressor and UglifyCSS是兩個CSS精簡工具。

 

Images Optimization

圖片中包含一些數據,移除也不會影響視覺效果。清除這些數據需要專業的圖片處理工具。我們的Francois Marier寫了兩篇博客文章講解處理PNG圖片和GIF圖片。

Smush.it是雅虎的在線圖片優化工具。OSX的離線工具ImageOptim也有同樣的功能-將圖片拖入,工具自動優化圖片文件大小。ImageOptim還可以用處理后的小文件替換原始文件。

如果可以接受視覺效果的適度損失,高壓縮比重新壓縮圖片也是可行的。
 

伺服器也可以幫忙!
除了合併和縮小資源外,還有其他辦法。幾乎所有的伺服器和瀏覽器都支持 HTTP 壓縮 功能。最受歡迎的兩種壓縮方案是使用 deflate 和 gzip。在數據被伺服器傳送到客戶端前,這兩種方案都使用了高效的壓縮演算法來壓縮被傳送的資源以達到減少傳送數據的目的。

 

緩存

拼接(Concatenation)和壓縮(Compression)可以改善用戶的第一次訪問。緩存(Caching)優化了用戶的回訪。再一次訪問時不需要重新下載所有的資源文件。HTTP協議提供了兩種方式實現緩存機制,緩存頭和ETags。

緩存頭可以緩存經常修改的資源。它包含兩個部分:Expires和Cache-Control:max-age。Expires標記過期時間,此後的訪問將重新請求資源。max-age表示資源的有效秒數。當帶有緩存頭時,瀏覽器只會在緩存頭過期后重新請求資源。
 

ETag表示資源的版本,用於與伺服器比對是否相同。它適用於任意改變的內容資源。資源的ETag頭告訴瀏覽器“去問問伺服器有同人沒,如果有就不改寫啦!”。但是ETag還需要和伺服器交互,不太適用於完全緩存的資源。
 

緩存破壞

相對於ETag,基於時間的Cache-Control頭的優勢在於只在過期后請求資源。但這也是最大的缺陷。如果資源改變了(但緩存頭沒過期),我們需要一些方法破壞緩存。

破壞緩存通常的方法是資源URL添加版本號。URL的改變會拋棄原有的緩存頭重新請求資源。

例如資源http://example.com/logo.png的緩存頭過期時間是一年,但logo更新了。已經緩存logo的用戶在一年後才看到新logo。添加版本標識就可以避免這個情況:

舊的logo

1 http://example.com/v8125/logo.png

或者

1 http://example.com/logo.png?v8125

更換新logo后,修改版本信息以重新請求資源
1 http://example.com/v8126/logo.png

或者
1 http://example.com/logo.png?v8126
 

Connect-cachify —— 一個用來服務串聯和緩存資源的NodeJS庫
Connect-cachify 是一個由Mozilla開發的NodeJS中間件,用來簡化提供正確的鏈接和緩存的資源的任務。

在生產模式下,Connect-cachify提供帶一年高速緩存的生產資源的預生成。如果不在生產模式下,取而代之的則是個人開發資源來避免調試變得複雜。Connect-cachify自己不進行字串串聯和極簡化,全靠你在構建腳本中進行。
 

可以通過setup函數配置connect-cacheify。setup函數有兩個參數,asset與options。asset是一種產品資源文件與開發資源文件的對應關係。每一個產品資源文件關聯於一系列單獨的開發資源文件。

options有以下設置參數:

prefix——加於hash碼之前的前綴字元串。(默認為空)
production——由開發資源還是產品資源輸出。(默認為true)
root——訪問靜態資源的根路徑,這個與之前中間件的路徑一致。(默認為'.',當前路徑)
 

connect-cachify 實例

首先,讓我們為connect-cachify準備一個簡單的HTML文件。文件引入了3個CSS文件和3個Javascript文件。

 
01 ...

02 <head>

03 <title>Dashboard: Hamsters of North America</title>

04 <link rel="stylesheet" type="text/css" href="/css/reset.css" />

05 <link rel="stylesheet" type="text/css" href="/css/common.css" />

06 <link rel="stylesheet" type="text/css" href="/css/dashboard.css" />

07 </head>

08 <body>

09 ...

10 <script type="text/javascript" src="/js/lib/jquery.js"></script>

11 <script type="text/javascript" src="/js/magick.js"></script>

12 <script type="text/javascript" src="/js/laughter.js"></script>

13 </body>

14 ...
 

中間件的設置

其次,把 connect-cachify 庫引入到你的 NodeJS 伺服器中。建立你自己的 production 的開發資源映射並配置好中間件。

01 ...

02 // Include connect-cachify

03 const cachify = require('connect-cachify');

04  

05 // Create a map of production to development resources

06 var assets = {

07 "/js/main.min.js": [

08 '/js/lib/jquery.js',

09 '/js/magick.js',

10 '/js/laughter.js'

11 ],

12 "/css/dashboard.min.css": [

13 '/css/reset.css',

14 '/css/common.css',

15 '/css/dashboard.css'

16 ]

17 };

18  

19 // Hook up the connect-cachify middleware

20 app.use(cachify.setup(assets, {

21 root: __dirname,

22 production: your_config['use_minified_assets'],

23 }));

24 ...

為了保持代碼清爽,asset 映射可以放到一個文件中,這樣既可成為 connect-cachify 的配置,也是你的程序的配置。

 

更新你的模板來使用cachify
最後,必須更新你的模板以指出使用到的 Javascript 和 CSS 在哪裡。JavaScript 用 “cachify_js” 來指明,而 CSS 用 “cachify_css” 指明。

01 ...

02 <head>

03 <title>Dashboard: Hamsters of North America</title>

04 <%- cachify_css('/css/dashboard.min.css') %>

05 </head>

06 <body>

07 ...

08 <%- cachify_js('/js/main.min.js') %>

09 </body>

10 ...

 
 

Connect-cahified輸出
如果將參數production設置為false,connect-cachify將輸出三個link標籤與三個script標籤,與原來的輸出一樣。如果將production設置為true,將只輸出各一個標籤。各標籤的url將被加上MD5 hash碼前綴。而MD5 hash碼前綴用於防止緩存。hash碼將會隨著產品資源文件內容發生變化,以清除緩存機制副作用。

1 <head>

2 <title>Dashboard: Hamsters of North America</title>

3 <link rel="stylesheet" type="text/css" href="/v/2abdd020a6/css/dashboard.min.css" />

4 </head>

5 <body>

6 ...

7 <script type="text/javascript" src="/v/acdd2ab372/js/main.min.js"></script>

8 </body>

9 ...

以上便是connect-cachify的所有設置。

結論
有許多簡單的方法來加快網站速度。利用3C技術-合併(concatenation)、壓縮(compression)與緩存(caching)-將大大提高網站的下載速率與改善用戶的使用體驗。Connect-cachify通過合併與緩存顯著改善NodeJS應用,但我們應該可以做的更好。在下一篇章節中,將介紹如何使用ETagify生成動態內容並儘可能的緩存資源。
 



[火星人 ] 前端性能優化指南已經有489次圍觀

http://coctec.com/docs/program/show-post-71302.html