咱們都但願建立高性能的Web應用程序。因爲咱們的應用程序變得愈來愈複雜,咱們可能想要支持豐富的畫面以及理想的60幀/秒,這能保證咱們的應用程序響應靈敏且生動流暢。javascript
知道如何衡量和提升性能,是一個有用的技能,在這短短的文章中,我會帶您簡單回顧關於如何經過 Chrome DevTools的 Timeline 和Profiles作到這一點。html
看!這是一個美麗的GIF動畫。這標誌着這篇文章這裏開始展開:)前端
Timeline工具欄提供了對於在裝載你的Web應用的過程當中,時間花費狀況的概覽,這些應用包括處理DOM事件, 頁面佈局渲染或者向屏幕繪製元素。java
它可讓你深刻獲得三個層面的數據,來幫助你明白問什麼你的應用很緩慢:事件, 框架和實時的內存用量。開始,瀏覽你的應用,並在DevTools中切換到Timeline工具欄。node
默認狀況下Timeline不會顯示任何數據,可是你能夠這樣開始一個記錄會話,打開你的應用並點擊灰色圓圈☻,它在工具欄的底部——使用Cmd/Ctrl+E 快捷鍵也能開始一個記錄。web
這個記錄按鈕會從灰色變成紅色,而Timeline將開始從你的頁面獲取時間線(timeline)。在你的應用中完成一些操做,記錄到一些數據以後,再一次點擊按鈕來中止記錄。chrome
請注意:會清除你現有的記錄會話,以便開始一個新的會話。將會強迫V8完成一輪的垃圾回收,在調試中它頗有用。將會對顯示的詳細信息進行過濾,只顯示那些完成耗時超過15ms的記錄。瀏覽器
檢查網絡
接下來,咱們着手檢查一下記錄的數據。對影響性能的成本要素按優先級排序。是JavaScript嗎?仍是渲染?咱們先看一看Timeline Events 模式,它能幫助回答這些問題。app
在這個模式中,Summary視圖(在Timeline的頂部)顯示了一些水平的柵欄,分別表明頁面中的網絡和HTML解析(藍色),JavaScript(黃色),樣式重計算和佈局(紫色)以及繪畫和合成(綠色)事件。重繪是瀏覽器事件,是爲響應諸如窗口大小改變或者滾動之類的視覺變化而調用的。
CSS屬性的修改會對樣式從新進行計算,而佈局事件(即重排)是由元素位置的改變引發的。別擔憂記不住這些,在Timeline面板下方有圖例告訴你。
在Summary視圖下面是Details視圖,包含了某個會話被記錄後,相關類別的記錄的詳細內容。
每個記錄在左側有用於說明的標題,右側是時間軸區域。鼠標移到一個記錄之上,會顯示更多的提示信息,其中包括從開始錄製到結束的時間 – 這很是有用,有必要多關注一下,特別是其中的調用棧信息。
點擊調用棧(Call Stack)或者氣泡提示中的超連接,會跳轉到相應的Javascript代碼行。若是你發現一個瀏覽器時間花費了過多的時間(能夠從詳細的氣泡提示中的‘Duration’知道),你也許會進一步去研究其緣由。
回到記錄列表,點擊某個記錄將其展開,能夠看到更進一步的記錄,描述了這個記錄是由哪些事件組成的。
若是你只對某個特段的數據感興趣,在Summary視圖中經過點擊和拖拽能夠選擇放大的區域。
Chrome把你的應用展現到屏幕上須要生成每一幅幀,而幀模式 可讓你能夠深刻到每一幀生成的內部細節。
做爲平滑的體驗,你看到的幀率最好一直保持在30-60fps,若是過低了,你的應用就會由於丟幀看上去 混亂 或者抖動。
在幀模式下,帶陰影的豎條對應正在重計算樣式、正在組合等等狀況。每一個豎條的透明區域對應於空閒時間,至少對於你的頁面是空閒的。例如,假設第一幀用了15ms,下一幀用了30ms。一般每一幀都會按刷新率進行同步,這個例子中第二幀的渲染多花了15ms,致使第三幀錯失了」真正「的硬件幀的時間,直接跳到下一幀的渲染。這樣,第二幀的實際生效時間就加倍了。
正如Andrey Kosyakov Chromium 的博客中提到的,即便你的程序沒有不少動畫,幀的概念也是有用的,由於瀏覽器在處理輸入事件時會生成重複動做的序列。若是你在一幀中留有足夠的時間處理這些事件,就會使你的程序看上去有更好的響應性,這意味着更好的用戶體驗。
若是咱們的目標是60fps, 那麼最多有 16.66ms 去作全部的事情。這個時間並很少,因此儘量從動畫中擠出時間來提升性能仍是很重要的。
讓咱們再次放大Summary視圖,看一下那些不知足幀率的幀,你就會發現瀏覽器(以及程序的行爲)對此的影響了。
舉個例子,最近咱們使用幀視圖(以及事件視圖)發現咱們的程序有過多的圖像解碼,這是由於瀏覽器須要不斷的實時的調整圖片的大小。
做爲替代方案,爲圖片預先準備好全部須要的尺寸,咱們就避免了這些開銷,從而達到60fps的目標,對於最終用戶來講更爲平滑。
相關提示:經過在Settings菜單打開Show FPS meter選項,你能夠在DevTool中打開實時的FPS計數器。
這能夠在程序的右上角顯示一個儀表盤,像下面這樣,這使得你能夠在程序的幀率低於預期的時候看到直觀的反饋。
移動端
注意在移動端,如同Paul在Breakpoint Ep 4 演示 的那樣,動畫和幀率都與桌面上大不同,能夠差幾個數量級。要達到更高的幀率要更困難一些,而像Timeline的幀模式這樣的工具(經過 遠程調試 鏈接)能夠幫你發現瓶頸所在。
檢查耗時的繪製,是困難的
要想檢查一段時間內的繪製(paint)是另外一個挑戰。若是你打算知道爲何某個特定的元素繪製的比較慢,你能夠把DOM樹中的部分元素設置成display:none將它們從佈局/內容樹中移除,而且設置visibility:hidden不讓它們繪製。而後你能夠用Timeline進行錄製以便測量,看一下繪製時間,在強制重繪模式中能夠觀察(實驗性的)繪製率(感謝Paul提供的竅門)。
減小內存使用與避免鋸齒形曲線
你的應用有可能會遭受內存泄露問題,Memory 模式對於偵測這種問題的初期症狀很是有用。
爲使用這個功能,再花幾分鐘記錄你與應用之間的交互,以後中止記錄並檢查。在 Summary 視圖中,你會看到隨着你在應用不一樣部分之間的跳轉,這些動做引發的內存使用狀況。其中既有內存使用的攀升,也有普通的垃圾回收發生。
淺藍色的區域表明一個給定時間裏,你的應用所使用的內存大小,而白色的區域是已經分配的內存總量。
若是你觀察到Summary視圖中有一個鋸齒圖形 ,這即是表明了應用的成本費用。例如,一個無參的requestAnimationFrame 函數將帶來垃圾,無論怎麼說,你須要關注鋸齒的陡峭度。若是它變得很是陡峭,說明你製造了太多的垃圾。
你能夠進一步的在新的會話記錄中,經過與應用之間的交互來測試這一點,空閒幾分鐘以後中止並再次查看結果。當應用處於空閒(或者你剛剛製造了許多垃圾),V8引擎會執行一系列的垃圾收集過程。若是在你空閒以後,內存彷佛從沒有真正的降下來,那麼說明你創造了太多的垃圾。
經過幾個週期的垃圾回收,理想狀況下內存視圖的輪廓應該是扁平的。若是在兩個GC週期間隔中它持續不斷的上升(你看到會說它是一個階梯函數),那麼你可能會發生內存泄漏。
在Memory模式Detail視圖的左側,你能發現三個選項:文檔計數(Document count),DOM節點計數 (DOM node count)以及事件偵聽計數 (Event listener count)。
DOM節點計數 圖顯示了保存在內存中的已建立DOM節點的數量(即尚有待垃圾回收的那些節點),而另外兩個選項相似的顯示了事件偵聽與documents/iframe的實例數。要是你只想看特定的計數類型,能夠在Details視圖取消其它的選擇以便將它們隱藏。
咱們如今知道了有潛在內存泄漏的可能,可是咱們應該定位它們的源頭。咱們可使用另外的堆分析儀(Heap Profiler)功能,它就在Profiles面板中。
在肯定使用什麼性能分析工具(profile)以前,你要知道是什麼致使程序的瓶頸,這一點很重要。例如,若是你看到在Timeline上有不少黃色的部分,那多是腳本產生的問題,能夠選擇JavaScript CPU 分析工具。若是問題是CSS selector產生的,那就選擇CSS Selector 分析工具。
對於咱們的例子,咱們打算使用堆的性能分析工具,由於咱們關心的是 堆的數據,可是正以下面列出的建議,也能夠選擇其餘的性能分析工具。
性能分析工具中,Take Heap Snapshot的選項可讓咱們在懷疑點以前和以後獲取內存的快照,獲得當時程序中活動的Javascript對象(以及DOM節點)在內存中的分佈。
要使用這個功能,點擊‘Start’,重複你懷疑(出現你發現的那些信息的時刻)會引發內存泄露的動做,這時記錄下第一個快照。 接下來點擊record按鈕 ☻ 來記錄第二個快照,此次不須要與程序進行交互。
咱們如今‘Heap Snapshots’下至少能看到兩個快照,讓咱們比較一下它們。
在DevTools窗口的下方,能夠看到‘Summary’下拉框,可讓你在可見的快照之間切換。Summary 視圖適用於 DOM泄漏,而Comparison 視圖擅長於發現 內存泄漏的緣由。 選擇Comparison ,而後點擊‘Snapshot 2′。
如今你看到的信息是在profile之間建立的對象。信息的差集可讓你對比垃圾收集所刪除的內存是否匹配上對象的建立所花費的內存。點擊特定的構造函數能夠在面板下面的對象的retaining tree視圖看到更多信息。
我知道這可能看起來有點可怕,但請忍受一下。一個典型的應用場景是試圖中發現一個你已經刪除或者斷開關聯的一個DOM節點是否任然存在。一旦你發現了形成內存佔用的代碼,你就能夠添加必要的代碼來清除那麼你不在須要的相關對象。
例如,在應用中咱們發現一個咱們已經卸載的HTMLImageElement元素任然存在。經過點擊構造函數,同時一直向下分析,直到咱們發現了那個任然包含了這個圖片引用的Window(高亮的) ,如今咱們知道了如何尋找那些不利於窗口對象的事件監聽器。
衡量和提高你應用程序的性能會須要花費一點事件。不幸的是,到目前爲止並無一顆銀彈能解決掉全部的問題。可是,DevTools中的Timeline和Profiles能幫助減輕你在發現這些主要問題時的痛苦。你在你的優化工做流中你能夠嘗試用這些工具,看它是否能幫助到你。
翻譯:http://www.oschina.net/translate/performance-optimisation-with-timeline-profiles