Yahoo Frontend Best Performance 最佳實務 常見五條
Yahoo Frontend Best Performance,總共有35條,並分類為 Content, Server, Cookie, CSS, Javascript, Images, Mobile,而 Rails 中的 Asset pipeline
就已經包含其中的一些實作。
以下為最常見的其中五條:
- Minimize HTTP Requests
- Use a Content Delivery Network
- Put Stylesheets at the Top
- Put Scripts at the Bottom
Gzip Components
1. Minimize HTTP Requests (Content)
藉由減少 HTTP 請求數量來調校網站的執行效能是個不錯的開始,根據 Tenni Theurer’s blog post Browser Cache Usage - Exposed! 的文章中提到,每日 40~60% 網站造訪者是 empty cache,這也意味著增加網頁讀取速度是帶給使用者良好體驗的關鍵所在。
Combined files 方法是透過將所有 Script 整合成一份 Script,達到減少 HTTP 請求數量的目的,如網站中所有需要的 CSS 都彙整成一份 CSS 檔案,HTTP 就可以減少為一次,減少 Response 時間,但當每個網頁所需要的 CSS 或 Script 不同時,就會增加實作上的難度。
CSS Sprites 是常見用來減少 image requests 的實作方式,結合各背景圖片(background image)成單一張圖片,並以 CSS background-image 與 background-position properties 來呈現所需的網頁效果。
Image maps 則是整合多張圖片成單一圖片,檔案總大小不變,但減少了 HTTP 請求數量,加速了網頁讀取,但此實作方式僅適用 contigous 形式的網頁如 Navigation bar。定義 Image map 的對應座標,實作上相當繁瑣乏味且容易出錯。實務上並不推薦使用。
Inline images 使用 data: URL scheme (http://tools.ietf.org/html/rfc2397) 將圖片資料嵌入實際頁面中,此舉將增加HTML文件的檔案大小,可減少 HTTP 請求數量,但並非所有瀏覽器都支援 inline images。
2.Use a Content Delivery Network(Server)
約 80~90% 的用戶端的 response time 是花費在下載網頁所需的各種物件上包含 images, stylesheets, scripts, Flash 等等,與其花費時間重新設計網站架構增加效能,倒不如將一些 static content 分散式儲存,透過 CDN 來實現,可大幅降低 response time。
content delivery network (CDN) 是透過分散各地儲存相同內容的 web server 更有效率傳送相關內容到用戶端,通常都依據用戶端所在計算選用對應的 web server 來發送內容,例如選用透過較少的 network hops 或是具最快 response time 的 web server。
大公司通常都會擁有自己的 CDN,一般新創公司或小型私人網站,實行 CDN 通常是一筆可觀投資,但當用戶數成長與來自全球各區域的客戶增加,CDN 就是必要採取的效能提升方式,以 yahoo 為例,其透過 CDN 改善了用戶端的 response time 達 20% 以上,選用 CDN 是相較於其他程式優化之下較簡單的實作方式,而且可以有效改善網站效能。
3.Put Stylesheets at the Top(CSS)
當在 Yahoo! 中研究網站效能時,團隊發現到將 stylesheet 移到 HTML 文件 HEAD 位置時,網頁具有較快的讀取速度,這是因為此舉可使呈現頁面上更按部就班。 前端工程師希望 HTML 頁面的呈現順序是 header, the navigation bar, the logo at the top 等等向下進行,如此一來使用者等待網頁讀取的同時也能接收到一些回饋,可改善使用者體驗。 此外將 stylesheet 移到 HTML 文件移至底下時,會限制頁面上對應效果的呈現,可能就會造成頁面出現空白區塊。
4.Put Scripts at the Bottom(Javascript)
Script 文件所造成的效能問題在於,下載 Script 時會阻斷其他並行的檔案下載,而直到 Script 文件下載完畢前,都不會下載網頁中的其他物件。
但在某些情況下,這實作方式會遇到困難,例如,可能在網頁中需呈現一些 Script 中的效果(像是document.write),若此時找不到 Script 文件就會造成 Scoping issue。此時有個選擇是使用 deferred scripts,此類含 DEFER attribute 的 scripts 不包含
document.write
,這樣網頁會略過此動作而繼續呈現頁面,但 Firefox 不支援 DEFER attribute。若使用 deferred scripts 就可以將 Script 文件下載動作移至網頁文件最後執行,可增加縮短網頁讀取速度。Ref: Explaining JavaScript Scope And Closures
5.Gzip Components(server)
一般而言,傳送 HTTP 請求到取得回應所花費的時間可由前端上做大幅度的改善,當然其他因素如:使用者的網路頻寬速度、網際網路服務商等等也會造成影響,但這些都不在開發團隊的管轄,但還有其他變數,像是壓縮(Compression)可縮小 HTTP 請求的檔案大小進一步減少 Response time。
從 HTTP/1.1 開始,在 HTTP 請求中加入 Accept-Encoding header 可使 Client 端可支援壓縮,指令如下: Accept-Encoding: gzip, deflate
當 Server 端接收到含有此 header 的請求,就會使用 Client 端指定的方式中選定一個執行壓縮,而 Server 端則在回應加入一行 Content-Encoding header 指令:
Content-Encoding: gzip
Gzip 是目前最常見與最具效率的壓縮方式,一般而言可減少約 70% 左右的 response 檔案大小,現今聲稱 90% 網路中透過瀏覽器傳送的請求與回應都支援 Gzip
Server 根據檔案類型決定是否做 Gzip,大多數網站對 HTML 文件做 Gzip,包含 scripts, stylesheet 或是其他 text response 像是 XML, JSON,而對 image 與 PDF 則不做 Gzip,因為這些檔案本身已經做過壓縮。
盡可能對可執行 Gzip 的文件實作 Gzip 是一種簡單降低 page weight 與提升使用者體驗的方式。
轉載自 Spring