網站前端效能優化 (performance optimize)的方法

York Chen
9 min readMar 27, 2019

最近面試了一波前端工程師的工作,比較專業的公司在面試或筆試時都會問到:「請說明一下你所知道的前端效能優化(performance optimize)方法有那些?」這個問題是大哉問,卻也是前端工程師存在的最大價值之一。

本篇文章分為四個部份介紹,第一部分介紹使用PageSpeed Insights進行檢測。其餘三部分,根據Google提供的最佳化建議與診斷,進一步查找相關技術文件,說明效能優化的方法。

使用Google提供的工具:PageSpeed Insights

如何檢測網站網頁的效能?

使用的方法很簡單,在PageSpeed Insigh這個網頁的中間輸入需要檢測的網站網址,按下分析Google即會幫忙你檢測該網站的效能。下圖以我的個人作品集網站為例:

( 圖1 PageSpeed Insights 以我的作品集網站為例搜尋)

搜尋後,Google會為該網站進行分析,並給予該網站行動版、電腦版網頁的效能評分:

圖2 PageSpeed Insights 個人作品集網站電腦版效能分數
圖3 PageSpeed Insights 個人作品集網站行動版效能分數

由於我的個人作品集網站是一個輕量的網站,幾乎只有前端網頁畫面的渲染,也沒有串接後端資料庫,因此分數可以拿到快速的高分。但PageSpeed Insights還是會提出一系列網站最佳化的建議與診斷,如下圖:

圖4 PageSpeed Insights最佳化建議與診斷

以及個人作品集網站效能通過的優化稽核項目,如下圖:

圖5 PageSpeed Insights 通過網站效能優化稽核的項目

影響網頁效能的關鍵:圖片

從上面 PageSpeed Insights針對我的個人作品集網站提供的最佳化建議,可以明顯看到4項建議中,有3項建議都是針對圖片優化。圖片是影響網頁效能的關鍵,它總是佔最多載入網頁時的記憶體,解決了它,網站效能的優化就解決大半,可以明顯感受到網站的載入速度變快。以下提供一些圖片優化的方法:

  1. 能不用圖片就不用圖片:能用程式就用程式來製作圖片。
  • 網站背景不要用圖片,使用CSS指定背景顏色(background-color)
  • 圖片特效使用CSS的陰影( box-shadow )、圓角( box-radius)、漸層( background-gradient)。
  • 圖片使用Canvas 與 SVG來繪圖,不過有些舊瀏覽器不支援SVG,如果在舊瀏覽器還是需要使用 jpg 、png檔案取代。

2. 圖片使用內容傳遞網路(Content delivery network, CDN)載入:透過這種電腦網路系統,能將圖片這種靜態資源放到離使用者更近、更快的伺服器節點來獲取網頁檔案,讓圖片快速載入、提高效能。

  • 圖片可以使用現成的icon font library 作為icon圖片,如FontAwesome,透過這種方法載入的圖片也具有彈性可以自由縮放圖片大小、改變顏色。
  • 自己利用免費 CDN 圖片分流加速服務來加速載入自己製作的圖片,如 AWS CloudFront ,設定後在載入網站時,會幫助使用者指向至最近節點獲取圖片、同時進行快取,除了能加速外亦有節省流量的效果。

3.最佳化圖片

  • 使用合適的圖片大小:網頁上要呈現的長、寬多少像素,就將上傳的圖片裁切成同樣的大小,可以減少網路數據使用量、縮短載入時間。
  • 使用新的圖片壓縮技術:如JPEG 2000、JPEG XR 或WebP 等圖片格式,這類技術的圖片壓縮效率會比傳統的PNG 或 JPEG好,能夠更快下載完成圖片、減少網路數據使用量。
  • 延遲載入圖片:使用如lazyload.js的Jquery套件,讓使用者一開始載入網頁時,不會將全部網頁一起載入,而是網頁卷軸滾動到時才會載入。或是先載入圖片小圖,再載入圖片大圖。
  • 優先使用向量圖片:向量圖片較不受解析度和圖片縮放影響,可以應用在多種裝置,如SVG圖。
  • 減少不必要的網路圖片下載:可以利用Chrome的開發人員工具,觀察下載了那些不必要的網路圖片,將之刪除或放到伺服器本地。

程式語言優化

1.壓縮(minify)程式檔案:將CSS、Javascript檔案中的空白、註解去除,最小化程式語言檔案。

2.禁止轉譯的資源(Render Blocking Resources):減少在HTML <link>外部的CSS、JavaScript,將網頁中首次載入網頁必要使用的CSS、JavaScript,直接嵌入HTML<head>;延後載入之後需要的CSS樣式,如之後需要使用時,再用JavaScript 載入。

3.減少JavaScript的執行時間:優化JavaScript的演算法運算的時間複雜度。

4.避免 DOM 節點數量過多:Google建議應少於 1,500 個左右。理想的網頁樹狀層級應包含少於 32 個元素,以及少於 60 個下層/上層元素。過多的DOM會使用過多的記憶體。

5.使用單頁式( Single Page Application)網站設計: 避免重復重新導向網頁,會導致網頁頁面延遲載入。

6.規劃好HTML的輪廓(HTML Outline):使用區塊標題<header>、導覽列<nav>、區域元素<section>等語意標籤來取代區塊標籤<div>,使HTML的上下層級是有階層的,更易載入,同時也強化網站的SEO。

7.CSS的Reflow 及 Repaint:回流Reflow)與重繪Repaint)是CSS影響效能的兩大兇手。可參考下圖瀏覽器渲染步驟了解原理,當CSS 檔解析出 CSSOM Tree後會和HTML解析出來的DOM Tree,合作疊加產生 Render Tree,才開始計算畫面的Layout,如Box Model的位置大小,以及可不可見(visible),最後轉化成像素畫(Paint)到瀏覽器上。

圖6 瀏覽器的渲染步驟, 圖片來源:faressoft

Reflow就是瀏覽器要重新渲染時,要重新計算Layout的動作;Repaint就是將計算結果重畫到畫面上的動作。要如何減輕這兩個動作的效能計算呢?大約有以下三種方法:

(1)CSS屬性替換,選擇用 translate 取代Box Model屬性與 定位(Position)屬性如top,left等

(2)使用精確的Class或修改cssText:在使用JS修改樣式時,明確指定到某區塊(div)的CSS來做修改,避免多餘的區塊修改時的計算。

(3)減少觸發:跟前面第3點同理,節點數量不要過多與過深,減少渲染觸發影響的範圍。另外可以在JS將需要的屬性先存起來如Height,避免直接在CSS重新觸發,漸少效能損發。常見的CSS觸發可參考CSS triggers

使用網路技術優化與字型優化

  1. 使用快取(Cache):將部分需要載入的資源暫時存在使用者電腦的本地端。
  2. 預先連上必要來源:新增預先連線或預先擷取使用者的 DNS 的資源提示,及早連線至重要的第三方資源,不過關閉瀏覽器時會結束請求資源的請求。在HTML的<head>連結JS、CSS檔案時,使用 <link rel="preload">,如:<link rel="preload" as="script" href="main.js"><link rel="preload" as="style" href="main.css">
  3. 延遲載入必要來源:新增未來才會使用到的資源, 這些資源可以結合catch機制有更好的效能,先暫存在 HTTP Cache 中加快未來載入時的速度,關閉瀏覽器時,不會立即結束請求,而是等待資源是否可以取得再決定是否要取消請求。語法同樣使用line屬性<link rel="prefetch">,如<link rel="prefetch" href="img.jpeg>
  4. 網站伺服器升級到 HTTP/2:更新 HTTP 通訊協定到HTTP/2, 這個新一代的協定可以向下完全兼容,不用修改任何程式碼,它主要修改的底層通訊封包的傳輸,它具有連線多工(Multiplexing)的特性,在單一次網路的連線,就可以同時傳輸多個 HTTP Request 和 Response,一次請求多個 CSS、JavsScript和圖片等等的網路資源。
  5. 網路字型的優化
  • 先從使用者端的電腦載入字型,如使用者未有該字型,再從網路上下載:
/* 思源黑體字型*/
@font-face {
font-family: 'Noto Sans TC', sans-serif;
src: local('Noto Sans TC Regular'), /* 指定使用者電腦中的字型 */
url(Noto Sans TC Regular'.woff2); /* 從網路下載字型*/
}
  • 將字型檔案進行壓縮,將未使用到的字剔除,只擷取所需要的字。
  • 減少使用過多的網路字型,減少載入字型所造成的網頁載入延遲。

參考資源:

--

--

York Chen

Cooking is an indispensable part of life. It is a taste that can’t be forgotten.