前端效能優化的常用手段

無名小貝勒發表於2017-07-13

反正,前端效能優化就是很重要,不好好學習怎麼進階到20K+的薪水啊?!

效能優化方面一直有所關注,但如果不去對自己所負責的專案進行一下回鍋,實踐實踐,優化優化,總會有點“書上得來終覺淺”的感覺吧!

從最開始的CSS放到<head>裡面、js放到</body>前面、使用雪碧圖等,到後面的靜態資源壓縮、合併以及使用iconfont代替小圖示,再到最近實踐的gzip壓縮、設定HTTP Header快取欄位...

gzip壓縮、設定ETag等,早就在《高效能網站建設指南》那兩本書中看過,但我一直認為這都是後端小夥伴幹得事,就沒有怎麼留意過。直到最近,對前後端分離的理解越來越充分,對整個專案的部署越來越清晰,對專案裡面的資源請求越來越明白,才恍然意識到:前後端分離了,這他媽就是前端自己乾的事啊!!!

從以下幾個方面來說一說自己實踐過的優化方法:

瀏覽器渲染頁面的過程

所謂優化,第一個要弄明白的就是:優化什麼、從哪裡優化。前端做出來的頁面是在瀏覽器裡面呈現的,那瀏覽器是怎麼渲染這個頁面的呢?遇到CSS、js靜態資源,瀏覽器是怎麼處理的?具體的過程這裡不再贅述,網上資源一大堆,我自己之前也寫過一篇,《網站效能優化—CRP》,算是谷歌文件的翻譯版吧。

理解了瀏覽器渲染頁面的過程,也就明白了:CSS為什麼要放到<head>裡面、js放到</body>前面,以及js的非同步載入(async、defer)等優化。

減少HTTP請求

  • CSS/JS 合併打包
  • 小圖示等用iconfont代替:作為單個DOM節點使用,可以設定大小、顏色等,非常便利。個人建議前端來維護這個字型包,每次有新增的圖示,讓設計師給我們對應的svg檔案即可,前端自己去 icomoon.io/ 這個網站,匯入原來的selection.json檔案,增量生成新的css,無比方便。之前,我一直以為iconfont只能是單色的呢,其實也可以是多色的,svg裡面多一些path而已,設計師會搞定的。生成字型後,前端正常引用即可(引用的時候,多色字型會多一些標籤)
  • 使用base64格式的圖片:有些小圖片,可能色彩比較複雜,這個時候再用iconfont就有點不合適了,此時可以將其轉化為base64格式(不能快取),直接嵌在src中,比如webpack的url-loader設定limit引數即可
  • 使用雪碧圖:設定背景圖尺寸大小,感覺很麻煩,而且雪碧圖的維護也不怎麼便利,好像使用率越來越低了,都被iconfont取代了

減少靜態資源的體積

  • 壓縮靜態資源:合併打包的js、css檔案體積一般會比較大,一些圖片也會比較大,這個時候必須要壓縮處理。前後端分離專案,不論是gulp還是webpack,都有相應的工具包。針對個別圖片,有時候也可以單獨拿出來處理,我個人經常使用這個網站 tinypng.com/ 線上壓縮
  • 編寫高效率的CSS:涉及到程式碼層面的優化比較多也比較細,不同水平的技術人員寫出來的肯定不一樣,這裡不做進一步的分析。但是為什麼要把CSS拿出來說一說呢?因為現在專案裡面基本上都在使用CSS前處理器,Less、SaaS、Stylus等等,這導致了某些初級前端的濫用:巢狀5、6層,甚者能達到7、8層,嚇死個人!巢狀這麼深,影響瀏覽器查詢選擇器的速度不說,這也一定程度上產出了很多冗餘的位元組,這個要改、要提醒,一般建議巢狀3層即可。關於編寫高效率的CSS,推薦一篇文章,《Writing efficient CSS selectors》
  • 服務端開啟gzip壓縮:大招,最近剛知曉,真是太牛逼了,一般的css、js檔案能壓縮60、70%,當然,這個比率可以設定的。前後端分離,如果前端部署用node、express作伺服器的話,使用中介軟體compression即可開啟gzip壓縮:

    // server.js
    var express = require('express');
    var compress = require('compression');
    var app = express();
    app.use(compress());複製程式碼

    對於一般的SPA專案,如果node伺服器的作用比較簡單,比如只是做個介面轉發之類的,很多人更傾向用Nginx作伺服器,Nginx在轉發介面、壓縮、快取等功能上更勝一籌。不過,大部分前端對Nginx應該陌生一些,為了實踐技術,用熟悉的node即可,真正的專案部署,有專業的實施人員來搞。

使用快取

設定Http Header裡面快取相關的欄位,做進一步的優化。

express裡面也有對靜態資源相關的設定,只不過平時沒怎麼注意:

可以設定etag、maxAge等,進一步會有200快取和304快取的區別:

200 OK (from cache) 是瀏覽器沒有跟伺服器確認,直接用了瀏覽器快取;而 304 Not Modified 是瀏覽器和伺服器多確認了一次快取的有效性,然後再使用的快取。

相關的討論可以參考 知乎:阿里雲端儲存如何讓瀏覽器始終以200 (from cache)快取圖片?

記憶體溢位

這種優化因問題而異吧,最重要的是善於使用Google DevTools裡面的Performance皮膚和Memory皮膚去分析、查詢問題,進而找到優化的點。

記憶體溢位目前我只碰到過一次,同事用echarts畫K線圖,同事的js邏輯寫的有問題,點選事件發生時canvas反覆渲染,導致記憶體逐漸升高,在APP內,直接導致了APP閃退。我重寫了一下js邏輯,針對canvas做了一些優化,修復了這個bug。

目前對這塊分析經驗還不是很多,後續碰到問題再實踐。


效能優化這塊,都是一點一點接觸的,專案中碰到了問題,然後去分析、優化,解決問題的同時,自己也收穫了很多知識。以上是我做前端使用過的優化方法,可能對於大牛來說,或許不值得的一提,但是對於新手來說應該還是有些許參考意義。

有些高階優化還沒有實踐到,比如劃分主域,細節一點的無線滾動優化等,後期會繼續學習。

PS: [譯]無盡滾動的複雜度--來自Google大神的拆解,這個無線滾動的優化我看了好久了,還沒有理出個所以然來 ?

相關文章