性能優化感覺大家都能說出幾條來,粗略點無非是減少http請求、減輕請求數據大小等等,詳細點就是css/js合并壓縮、雪碧圖等等,但實在是散亂無章,如何有條理地回答面試官的問題就很重要了,其實可以從不同的維度,不同方面去進行回答。前端文章同質性太嚴重了,我最近的我都是總結整理,不是自己寫的!
總結自:
鳥瞰前端 , 再論性能優化
預備知識
“從用戶輸入URl到頁面展示給用戶瀏覽器客戶端的過程中發生了什么?”
前端經典面試題: 從輸入URL到頁面加載發生了什么?
瀏覽器渲染原理
- HTML被解析成DOM Tree,CSS被解析成CSS Rule Tree
- 把DOM Tree和CSS Rule Tree經過整合生成Render Tree(布局階段)
- 元素按照算出來的規則,把元素放到它該出現的位置,通過顯卡畫到屏幕上
CSS不會阻塞DOM Tree生成,會阻塞渲染,但JS會阻塞DOM 加載。
重繪和回流
瀏覽器宿主環境
1. 突破單線程解析渲染阻塞限制
瀏覽器是一個單線程解析模式去解析渲染從服務器端拿到的html文本,css加載(渲染)的過程中會對后續的腳本資源加載造成阻塞,腳本的加載也會阻塞后續DOM結構的解析造成頁面的留白時間增長,雅虎的35條軍規中有一條就是樣式文件放在頭部,腳本文件放在DOM節點最末尾,減少阻塞。這里還有幾個針對腳本文件的優化:
- 針對不需要DOM操作(主要考慮是需要操作DOM的腳本往往需要獲取一些樣式信息)的Js腳本可以采用動態創建script的方式載入,動態載入的腳本不阻塞后續資源的加載。
- 腳本文件加載可以加上defer或者async屬性標識防止阻塞
defer是在HTML解析完之后才會執行,如果是多個,按照加載的順序依次執行
async是在加載完成后立即執行,如果是多個,執行順序和加載順序無關
2. 避開Cookie性能bug——靜態資源CDN
Cookie是前端作為前后臺登錄態校驗最通常用的緩存方案,但鑒于瀏覽器在每次都會往同域的任何資源的http請求中自動帶上cookie信息的情況,這里有必要進行優化一下,因為像css、js、image這些資源請求是不需要cookie信息的,會無端造成請求帶寬的浪費(想象一下我們的cookie大小假設為10K,100個請求就是近1M的大小,高并發下以我們現行網絡帶寬也是蠻大的一筆負擔了)。
Cookie free性能優化方案的處理方式是CDN異域靜態資源服務器部署我們的前端css、js、image資源。
3. 代碼優化——事件委托等
其實這里有很多點:
- 要插入DOM片段時最好使用fragment一次性插入;
- 動態生成100li如何綁定事件,可以通過事件冒泡利用事件委托給父元素綁定事件即可;
- 對于查找過的節點可以緩存下來,避免再次查找
- ...
DNS層
DNS預解析
前端優化:DNS預解析提升頁面速度
這里也是我第一次遇到link標簽的另外用法。
HTTP層
1. 減少HTTP請求數量
2. 減輕HTTP請求數據大小
css、script、圖片壓縮:這些可以gulp或者webpack自動化腳本里面定義腳本任務來完成。
服務器開啟gzip壓縮:一般現在服務器都有開啟Gzip壓縮,壓縮率通常都是30%以上,效果還是不錯的。