本文提供一個優化網頁性能的大概思路,具體操做網上資料不少。css
性能優化第一步,即是管理好頁面的緩存,避免重複下載資源。不然,即增長服務器壓力,又折磨用戶的錢包。html
按照這一套邏輯,即可規劃好網站的緩存。css3
一般沒法作到這一點,由於瀏覽器發現資源沒過時,根本不會發出請求。
可是能夠經過修改資源的網址來實現。因此須要給資源文件名加上版本號或者隨機標記。例如 style.1234.css。
也就是說,不要讓瀏覽器緩存html文件,不然,過時以前,瀏覽器都不會請求服務器。瀏覽器
最好的優化,即是根本不下載資源。因此要儘可能減小比不要的資源。緩存
瀏覽器渲染一張網頁經過如下步驟。性能優化
說人話:瀏覽器先解析HTML,發現<link>就去請求CSS文件,發現<script>就去請求js文件。
當CSS文件徹底取回,便會開始構建CSSOM樹,當CSSOM樹和DOM樹都構建完成,纔會開始渲染頁面。
當JS文件徹底取回,並不必定馬上執行,須要等待CSSOM樹構建完成。同時,若是DOM樹還沒有構建完成,就會暫停構建,等待JS執行完成。由於瀏覽器不知道JS文件是否會修改CSS和DOM。
因此,在網頁中隨意擺放<link>和<script>,極有可能形成各類阻塞,必須精心安排。
優化關鍵渲染路徑,即是指優化這個渲染過程,讓網頁儘快呈現出來。服務器
重繪過程:
異步
優化動畫即是優化以上步驟使動畫達到60幀。
CSS選擇器要簡單,避免瀏覽器遍歷DOM樹來尋找元素。
js修改的元素要避免牽連過多致使佈局發生變化。
要減小須要重繪的元素。重繪時,同一個layer的元素都會被重繪。重繪也是很是耗費性能的一步。async
即佈局發生變化。Chrome, Opera, Safari, Internet Explorer中叫layout. 火狐稱之爲Reflow。
reflow老是牽涉整個文檔流。
由於動畫一直在運動,因此要避免使用會致使佈局發生變化,和致使必須從新計算元素像素(重繪)的CSS屬性製做動畫。而transform和opacity兩個CSS屬性正是咱們所需的。
由於瀏覽器渲染網頁時,會將網頁分層(layer),最後將不一樣層合併,而後完成渲染。
同一層中,哪怕只有一個小小的元素髮生變化,整個層都會被repaint。函數
開發者工具的Paint Profiler界面中觀察到每一層的繪製過程
因此,能夠考慮將動畫放在單獨的layer中。
CSS的will-change和 transform: translateZ(0)能夠用來建立新layer;
再搭配transform和opacity,用CSS3製做動畫。根據個人實驗,能夠徹底避免reflow和重繪。
可是過多layer也消耗內存和性能,用開發者工具中的 Performance判斷新layer是否帶來優化,不然不要建立新layer。
開發者工具的layer界面中能夠觀察網頁有多少個layer,每一個layer包含哪些元素。
網頁時給人用的,因此最惱人的是鼠標或手指操做頁面時,頁面卡卡的。
而響應用戶操做的JS都是異步的。若是JS線程太繁忙,遲遲不能進入下一個事件循環,就會致使響應用戶操做不及時。
儘可能增長線程空閒時間,讓事件循環能夠及時取出回調函數。提升響應的優先級,用戶交互時,停下其餘耗時的JS。
但響應沒必要過於及時,在100ms內獲得反饋,人類都不會察覺到卡頓,能夠把一些耗時的工做分解成不少步,利用這個時間差去執行它們。
活用requestAnimationFrame方法。
requestAnimationFrame在下一幀開始前調用函數。優於setInterval的地方是每一幀只會調用一次,而setInterval則不必定。
交互事件的監聽函數的執行時間不能太長,不然會阻塞頁面滾動。
監聽函數可能會調用preventDefault, 致使瀏覽器必須等待監聽函數執行完成。
不過新擴展的addEventListener方法第三個參數能夠是一個對象,對象的passive屬性用來事先承諾不會調用preventDefault方法,瀏覽器則不會等待監聽函數。
不要再交互事件的監聽函數中修改樣式,會致使強制同步reflow,阻塞js執行。
由於監聽函數會在requestAnimationFrame以前執行,若是監聽函數中修改了樣式,又用到requestAnimationFrame來製做動畫,便會致使強制同步reflow。
某些交互事件觸發極頻繁,注意要debounce。
debounce:不要高頻率調用函數,事件連續觸發時,只調用一次函數。