前言
性能優化無非就是讓頁面的打開速度更快一些,以得到更好的用戶體驗。前端在這方面可以做到的有兩方面,頁面級別的優化,比如減少 Http 請求次數、加快資源的加載速度;二是代碼級別的優化,頁面重新渲染一次會經過瀏覽器的重排(reflow)和重繪(repaint),這兩部操作是非常耗時的,本文將根據這兩方面的優化途徑,大致總結一下。
頁面級別優化
1. 減少 HTTP請求數
首先,每個請求都是有成本的,既包含時間成本也包含資源成本。一個完整的請求都需要經過 DNS尋址、與服務器建立連接、發送數據、等待服務器響應、接收數據這樣一個 “漫長” 而復雜的過程。時間成本就是用戶需要看到或者 “感受” 到這個資源是必須要等待這個過程結束的,資源上由于每個請求都需要攜帶數據,因此每個請求都需要占用帶寬。另外,由于瀏覽器進行并發請求的請求數是有上限的 (具體參見此處 ),因此請求數多了以后,瀏覽器需要分批進行請求,因此會增加用戶的等待時間,會給用戶造成站點速度慢這樣一個印象,即使可能用戶能看到的第一屏的資源都已經請求完了,但是瀏覽器的進度條會一直存在。
減少 http 請求次數的主要方法:
設置 HTTP緩存
http 緩存是 web 性能優化中非常重要的一種手段,把一些常用資源在首次加載時緩存到瀏覽器本地,再次加載時可大大減少請求次數,緩存的資源越多,性能當然越好。
緩存的規則主要有兩種,強制緩存和對比協商緩存,兩種緩存分別通過Http報文頭部不同的字段進行控制。
資源合并壓縮
CSS、 Javascript、Image 都可以用相應的工具(Webpack)進行壓縮,壓縮后往往能省下不少空間。
CSS Sprites
合并 CSS圖片,減少請求數的又一個好辦法。
懶加載
這條策略實際上并不一定能減少 HTTP請求數,但是卻能在某些條件下或者頁面剛加載時減少 HTTP請求數。
2. 把 js 腳本置底加載
js 腳本是很容易形成阻塞,導致資源加載停滯,為了避免這種情況,先加載其他資源,最后加載腳本。
3. inline 腳本異步執行
inline 腳本與外鏈引用的腳本類似,也有可能會引起阻塞,所以也要將 inline 腳本放到頁面底部或者異步方式來加載,
例如使用script標簽的defer?和async屬性、使用setTimeOut。
4. 動態加載 js 模塊
5. css 放在 head 中
頁面渲染過程還要經歷重繪重排,這樣做是避免會出現 DOM 加載完之后卻沒有樣式的情況。
代碼級別優化
DOM操作應該是腳本中最耗性能的一類操作,例如增加、修改、刪除 DOM元素或者對 DOM集合進行操作。
而修改 DOM 會引起網頁的重新渲染。
重新渲染,就需要重新生成布局和重新繪制。前者叫做"重排"(reflow),后者叫做"重繪"(repaint)。
需要注意的是,"重繪"不一定需要"重排",比如改變某個網頁元素的顏色,就只會觸發"重繪",不會觸發"重排",因為布局沒有改變。但是,"重排"必然導致"重繪",比如改變一個網頁元素的位置,就會同時觸發"重排"和"重繪",因為布局改變了。
這這兩步只是網頁生成的最后兩部,關于頁面的生成過程,主要有五步:
1. HTML代碼轉化成DOM2. CSS代碼轉化成CSSOM(CSS Object Model)3. 結合DOM和CSSOM,生成一棵渲染樹(包含每個節點的視覺信息)4. 生成布局(layout),即將所有渲染樹的所有節點進行平面合成5. 將布局繪制(paint)在屏幕上
這五步里面,第一步到第三步都非常快,耗時的是第四步和第五步。
"生成布局"(flow)和"繪制"(paint)這兩步,合稱為"渲染"(render)。
具體技巧參照:http://ruanyifeng.com/blog/2015/09/web-page-performance-in-depth.html