如果你的網站在1000ms內載入完成,那麼會有平均一個使用者停留下來。2014年,平均網頁的大小是1.9MB。看下圖瞭解更多統計資訊。
網站的核心內容需要在1000ms內呈現出來。如果失敗了,使用者將永遠不會再訪問你的網站。通過降低頁面載入的時間,很多著名公司的收入和下載量有顯著的提升。比如
- Walmart 每降低100ms的載入時間, 他們的收入就提高1%.
- Yahoo 每降低400ms的載入時間,他們的訪問量就提升9%。
- Mozilla 將他們的頁面速度提升了2.2秒,每年多獲得了1.6億firefox的下載量。
網站優化的步驟
- 設定效能預算。
- 測試當前的效能。
- 找出導致效能問題的地方。
- 最後,duang,使用優化特技。
下面有幾種方法可以提升你的頁面效能,讓我們來看看
速度指標
速度指標是指頁面的可視部分被呈現在瀏覽器中的平均速度。表示為毫秒的形式,並且取決於viewport的大小。請看下圖(用視訊幀的形式展現頁面載入時間,以秒為單位)。
速度指標越低越好。
速度指標可以通過Webpagetest 來測試(由Google維護)
長話短說
Webpage test 有很多特性,比如在不同的地方用不同的瀏覽器跑多個測試。 還可以測算其他的資料比如載入時間,dom元素的數量,首位元組時間等等…
例如:檢視amazon在webpagetest上的測試結果 。
可以看看這個視訊,瞭解由 Patrick Meenan 講解的關於webpagetest的更多資訊(需要梯子)。
渲染阻塞
如果你知道瀏覽器如何執行,那麼你應該知道HTML, CSS, JS是怎麼被瀏覽器解析的以及其中哪個阻塞了頁面的渲染。如果你不知道,請看下圖。
點選how a browser works瞭解更多瀏覽器工作原理(作者為Tali Garsiel 和Paul Irish).
瀏覽器渲染的步驟
- 首先瀏覽器解析HTML標記去構造DOM樹(DOM = Document Object Model 文件物件模型)
- 然後解析CSS去構造CSSOM樹( CSSOM = CSS Object Model CSS物件模型)
- 在將DOM和CSSOM樹結合成渲染樹之前,JS檔案被解析和執行。
現在你知道瀏覽器如何進行解析了,讓我們看看是哪一部分阻塞了渲染樹的生成。
1. 阻塞渲染的CSS
有人認為CSS阻塞了渲染。在構造CSSOM時,所有的CSS都會被下載,無論它們是否在當前頁面中被使用。
為了解決這個渲染阻塞,跟著下面的兩個步驟做
- 將關鍵CSS內嵌入頁面中,即將最重要的(首次載入時可見的部分頁面所使用到的)style寫入head中的
<style></style>裡。
- 移除沒用到的CSS。
那麼我是如何找出沒用到的CSS的呢。
- 使用Pagespeed Insight 去得到像未使用的CSS,阻塞渲染的CSS和JS檔案等等的統計資料。例如:Flipkart的Pagespeed Insight統計結果。
- 使用Gulp任務,如gulp-uncss或是使用Grunt 任務,如grunt-uncss。如果你不知道他們是什麼,請閱讀我之前的文章。
##專業小貼士
2. 渲染阻塞的JavaScript
如果在解析HTML標記時,瀏覽器遇到了JavaScript,解析會停止。只有在該指令碼執行完畢後,HTML渲染才會繼續進行。所以這阻塞了頁面的渲染。
為了解決它
在<script></script>標籤中使用 async或defer特性。
- <script async>將會在HTML解析時下載該檔案並在下載完成後馬上執行。
- <script defer> 將會在HTML解析式下載該檔案並在HTML解析完成後執行。
例如: async and defer都在Google Analytics中使用
記憶體洩漏
記憶體洩漏和頁面臃腫 是前端開發者所要面對的問題之一。讓我們來看看如何發現並解決記憶體洩漏。
在JavaScript中尋找記憶體洩漏
使用Chrome Task Manager(工作管理員)去檢測app所使用的記憶體以及js記憶體(總體記憶體+實時記憶體)。如果你的記憶體一直隨著你的每次操作而提高,那麼你可以懷疑有記憶體洩漏了。
下面是Chrome Task Manager的截圖。
Chrome DevTools分析
使用 Heap Profiler 去檢視記憶體洩漏。開啟Chrome devTools 然後點選profiles 標籤,接著選中 take heap snapshot。如果你不瞭解Chrome DevTools,請閱讀之前的文章.
Heap Profiler有四個快照檢視(snapshot view)
- Summary 檢視 – 展示物件的總體數量以及它們的例項總數,淺部(Shallow)大小(物件本身的記憶體大小)以及保留(Retained)大小(自動GC發生後所釋放的記憶體大小+無法執行到的物件的記憶體大小)。
- Comparison 檢視- 用於比較一個操作的前後的兩個或多個快照,可以檢測記憶體洩漏。
- Containment 檢視- 展示了你的app物件架構的整體檢視 + DOMWindow 物件(全域性物件下的), GC 根部, 本地物件 (來自瀏覽器)。
- Dominators 檢視- 展示了 dominators 樹的堆圖。
點選瞭解更多 Heap profiler。
DOM洩漏
對DOM元素的引用會導致DOM洩漏並且阻礙自動垃圾回收(GC)的進行。
來看一個例子
1 2 3 4 5 |
<div> <div id="container"> <h1 id="heading">I am just a heading nothing much</h1> </div> </div> |
1 2 3 4 5 6 7 8 |
var parentEle = document.getElementById('container'); //get parent ele reference 得到父元素的引用 var headingEle = document.getElementById('heading'); //get child ele reference 得到子元素的引用 parentEle.remove(); //removes parent element from DOM 從DOM中移除父元素 //but its child ref still exist, So parentEle won't collect GC'd and causes DOM Leak //但是它的子元素引用仍然存在,所以parentEle不會被GC回收,因此導致了DOM洩漏。 |
將它的引用設定為null即可修復DOM洩漏。
1 |
headingEle = null; //Now parentEle will be GC'd |
上面就是前端開發者常遇到的問題。今天就講到這。如果你喜歡我的文章,請分享或者在下面評論。謝謝!!