1. 程式人生 > >用Chrome開發者工具做JavaScript效能分析

用Chrome開發者工具做JavaScript效能分析

你的網站正常運轉。現在我們來讓它運轉的更快。網站的效能由頁面載入速度和程式碼執行效率決定。一些服務可以讓你的網站載入更快,比如壓縮JSCDN,但是讓程式碼執行的更快你要做的事情。

程式碼中很小的改動都可能對效能造成巨大的影響。快速靈活的網站和可怕的“無響應指令碼”對話方塊可能只有幾行程式碼的差別。這篇文章告訴你如何通過用Chrome開發者工具(Chrome Developer Tools)找到這幾行關鍵的程式碼。

設定一個基線

我們來看一個簡單的“顏色排序器”應用,這個應用展示了一個由各種顏色構成的網格,你可以拖拽這些顏色進行混合。每一個點都是一個div標籤加上一些讓它看起來是圓的的CSS。

用chrome開發者工具進行JS效能分析

頁面載入的很快,但還是花費了一些時間,在渲染之前還閃了一下。是時候對這個頁面進行效能分析讓它更快了。

在開始做效能優化的時候要設定一個基線,來明確這個頁面的速度到底怎樣。這個基線可以讓你知道自己是否做了優化並幫助你權衡利弊。在這片文章裡我們要使用chrome開發者工具

效能分析器(profiler)是chrome開發者工具的一部分,點選小扳手下面的工具選單就可以開啟它。Firebug也有一些效能評測工具,但是webkit核心的瀏覽器(chrome和safari)在對程式碼進行效能分析和展示時間線方面是最棒的。Chrome還提供一種很棒的事件跟蹤工具,叫做 speed tracer

在時間線(timeline)標籤下開始記錄,載入頁面然後停止記錄,這樣就設定了一個基線。(開啟chrome開發者工具,點選“時間線”標籤,然後點選視窗底部圓形的黑色“記錄”圖示開始記錄)。chrome是很智慧的,只有頁面開始載入的時候才會開始記錄。我記錄了三次然後取了平均值,以防我的電腦在第一次測試的時候執行的很慢。

用chrome開發者工具進行JS效能分析

我的平均基線,也就是從第一個請求到頁面全部渲染結束所花費的時間是1.25秒。這個時間不是太長,但是對於這樣一個小的頁面來說也不算好。

我想讓程式碼執行的更快,但是我並不知道是什麼讓它慢下來的。效能分析器(profiler)幫助我找到原因。

建立一個Profile

時間線(timeline)告訴我們程式碼執行花費的時間,但是並沒有幫助我們知道程式碼執行的時候發生了什麼。我們可以做一些改動然後不斷的測每次程式碼執行的時間,但這是盲目的。profiles給我們提供了更好的方法。profiler告訴我們哪些函式的執行佔用了大部分時間。讓我們切換到chrome開發者工具的“Profiles”標籤頁開始效能測試,這裡一共提供了三種類型的效能測試。

1、      javascript cpu 效能測試

顯示javascript佔用了多少CPU

2、      css選擇器效能測試

顯示處理CSS選擇器佔用的CPU

3、      堆疊快照

顯示javascript物件的記憶體佔用情況

我們想要javascript程式碼執行的更快,所以我們進行CPU效能測試。我們開始效能測試,重新整理頁面然後停止。

用chrome開發者工具進行JS效能分析

通過效能分析首先知道很多函式在執行。“顏色排序器”使用了jQuery和jQuery  UI,來處理些管理外掛和解析表示式之類的事情。我發現列表最頂端的是decimalToHex和makeColorSorter兩個函式。這兩個函式佔用了CPU13.2%的時間,這是做優化的好地方。

我們可以點選函式呼叫旁邊的“下一個”箭頭來檢視完整的函式呼叫堆疊。展開後,可以看到decimalToHex是被makeColorSorter呼叫的,makeColorSorter是通過$(document).ready呼叫的。

程式碼如下

JavaScript
1234 $(document).ready(function(){makeColorSorter(.05,.05,.05,0,2,4,128,127,121);makeSortable();});

弄清楚這兩個函式是哪裡呼叫的,也就弄清楚了讓顏色可以排序並不是最大的效能問題。通常情況下效能問題都是由多餘的排序操作造成的,但是在我的程式碼中相比與排序增加DOM元素花費了更多時間。

我想要讓這些函式執行的更快,但是首先我想要將我的改動區隔開。在頁面載入過程中會發生很多事情,我不想要這些影響到我的效能分析。

區隔問題

我做了第二個版本,這個版本中“顏色排序器”在我點選按鈕之後才載入,而不是在document ready的時候載入。這就把文件載入的過程分離出去,讓我可以只對顏色分類進行效能測試。調完效能之後我可以立刻改回去。

讓我們呼叫新的函式testColorSorter並把它繫結到一個可點選的按鈕上。

JavaScript
1234 functiontestColorSorter(){makeColorSorter(.05,.05,.05,0,2,4,128,127,121);makeSortable();}
JavaScript
1 <button id="clickMe"onclick="testColorSorter();">Click me</button>
1

在我們進行效能分析之前改變應用可能導致意外的結果。這個改動看起來很安全,但是我還是要重新執行效能檢測器來看看我是不是無意中改變了什麼。我會開始一次新的效能分析,點選應用中的按鈕然後停止。

用chrome開發者工具進行JS效能分析

我首先注意到decimalToHex函式的載入只佔用了4.23%的時間。這是程式碼執行花費時間最多的地方。我們建立一個新的基線來看看這個方案對程式碼有多大的優化。

用chrome開發者工具進行JS效能分析

有些事件在我點選按鈕之前有觸發了,但是我只關注從我點選滑鼠到瀏覽器渲染“顏色排序器”花費的時間。滑鼠在390毫秒時點選,渲染事件在726毫秒處被觸發。726減去390得到我的基線336毫秒。和第一個基線一樣我重複了3次來取平均值。

這時,我知道如何獲得並且得到了程式碼確切的執行時間,我們已經準備好開始解決問題了。

讓程式碼更高效

效能分析器只告訴我們哪個函式造成的問題,所以我們要檢視下函式的原始碼來了解函式做了些什麼。

JavaScript
1234567 functiondecimalToHex(d){varhex=Number(d).toString(16);hex="00".substr(0,2-hex.length)+hex;console.log('converting '+d+' to '+hex);returnhex;}
JavaScript
1

“顏色排序器”中的每一個顏色點都有一個16進位制的色彩值,例如#86F01B和#2345FE.這些值表示一種顏色中紅,綠,藍三原色各自的數值。例如的背景色是#2456FE,代表紅色的值是36,綠色的值是86,藍色的是254,每一個數值必須是0到255之間的。

decimalToHex函式把這用RGB值表示的顏色轉化為頁面中我們使用的16進位制顏色。這個函式十分的簡單,但是我還是留下了一個可以去掉的除錯程式碼console.log在那裡。

decimalToHex 函式還在數字之前加上了補位。這是很重要的一點,因為有些10進位制數字對應的是1個16進位制數字。比如十進位制中的10對應著16進制中的C,但是在CSS中需要一個兩位數。為了讓這個進位制換算更快速,我們讓這段程式碼不是那麼泛化。我知道每個需要補位的數字長度都為1,所以我們可以這樣重寫這個函式。

JavaScript
123 functiondecimalToHex(d){varhex=Number(d).toString(16);returnhex.length===1?'0'+hex:hex;}
1

第三個版本的“顏色排序器”只有在需要補位的時候才改變字串,並且不用呼叫substr函式。有了這個新函式,執行時間是137毫秒。再次對程式碼進行效能測試,可以發現decimalToHex函式只佔用了總時間的%0.04,到了列表的下部。

用chrome開發者工具進行JS效能分析

我們還可以發現佔用CPU最多的函式是 jQuery的e.extend.merge。我不知道這個函式的作用,因為程式碼是壓縮過的。我可以使用開發版本的jQuery,但是我發現這個函式是被makeColorSorter呼叫的。所以下一步我們先讓這個函式執行的更快。

減小改動

“顏色排序器”中的多彩顏色是用過正弦曲線生成的。在光譜中設定一箇中心點,然後以一定的偏移來建立這個曲線。這就把顏色變成了一個“彩虹模型”。我們還可以通過改變紅綠藍三原色的使用頻率來改變顏色。

JavaScript
1234567891011121314151617181920 functionmakeColorSorter(frequency1,frequency2,frequency3,phase1,phase2,phase3,center,width,len){for(vari=0;i<len;++i){varred=Math.floor(Math.sin(frequency1*i+phase1)*width+center);vargreen=Math.floor(Math.sin(frequency2*i+phase2)*width+center);varblue=Math.floor(Math.sin(frequency3*i+phase3)*width+center);console.log('red: '+decimalToHex(red));console.log('green: '+decimalToHex(green));console.log('blue: '+decimalToHex(blue));vardiv=$('<div class="colorBlock"></div>');div.css('background-color','#'+decimalToHex(red)+decimalToHex(green)+decimalToHex(blue));$('#colors').append(div);}}
1

我們要去掉console.log函式。這些呼叫非常的糟糕,因為每次執行都會呼叫decimalToHex函式,這意味著decimalToHex函式會被多呼叫2倍的次數。這個函式大幅度的改變了DOM結構。每次迴圈,都向id為colors的div中新增一個新的div。這就讓我懷疑這就是e.extend.mergefunction做的事情。用效能分析器做一個小實驗就可以搞清楚。

我想要一次把所有的div新增進去,而不是在每個迴圈中新增一個新的div。建立一個變數來儲存資料,然後在最後一次性新增進去。

JavaScript
1234567891011121314151617 functionmakeColorSorter(frequency1,frequency2,frequency3,phase1,phase2,phase3,center,width,len){varcolors="";for(vari=0;i<len;++i){varred=Math.floor(Math.sin(frequency1*i+phase1)*width+center);vargreen=Math.floor(Math.sin(frequency2*i+phase2)*width+center);varblue=Math.floor(Math.sin(frequency3*i+phase3)*width+center);colors+='<div class="colorBlock" style="background-color: #'+decimalToHex(red)+decimalToHex(green)+decimalToHex(blue)+'"></div>';}$('#colors').append(colors);}
1

這個小改動意味著DOM只在新增所有div的時候做一次改變。用時間線進行測試,我們發現從點選到渲染花費了31毫秒。這個dom變動,使得第四個版本的執行時間降低了86%。我可以再次開啟效能分析器(profiler),發現e.extend.merge函式佔用了很少的時間,在列表中已經看不到它了。

我們還可以完全移除decimalToHex函式讓程式碼更快一點。因為CSS支援RGB顏色,所以我們不需要把他們轉換到16進位制。現在我們可以這樣寫makeColorSorter函式。

JavaScript
1234567891011121314151617 functionmakeColorSorter(frequency1,frequency2,frequency3,phase1,phase2,phase3,center,width,len){varcolors="";for(vari=0;i<len;++i){varred=Math.floor(Math.sin(frequency1*i+phase1)*width+center);vargreen=Math.floor(Math.sin(frequency2*i+phase2)*width+center);varblue=Math.floor(Math.sin(frequency3*i+phase3)*width+center);colors+='<div class="colorBlock" style="background-color: rgb('+red+','+green+','+blue+')"></div>';}$('#colors').append(colors);}
JavaScript
1

第五個版本的執行只用了26毫秒而且程式碼行數從28行減少到18行。

在你的應用中進行Javascript效能分析

實際工作中的應用要比“顏色排序器”複雜的多,但是做效能分析要遵循同樣的基本原則

1、      設定一個基線,這樣你就知道你是從何處開始的。

2、      把問題從應用的其他程式碼隔離出來。

3、      在一個可控的環境下進行優化,頻繁的使用時間線(timelines)和效能分析器(profiles)

還有一些效能優化的準則

1、      從最慢的部分開始,這樣在時間優化上可以得到最大的提升。

2、      控制環境。如果你換了電腦或者做了任何大的改動,都要設定新的基線。

3、      多次分析以防你電腦的異常導致得到不正確的結果。

每個人都想要他的網站更快,你必須開發新的功能,但是新的功能通常會讓網站更慢。所以花費時間來做效能優化是有價值的。

效能分析和優化使得最終版顏色分類器的執行時間減少了92%。你的網站可以變快多少?

【如需轉載,請在正文中標註並保留原文連結、譯文連結和譯者等資訊,謝謝合作!】

相關推薦

Chrome開發者工具JavaScript效能分析

你的網站正常運轉。現在我們來讓它運轉的更快。網站的效能由頁面載入速度和程式碼執行效率決定。一些服務可以讓你的網站載入更快,比如壓縮JS和CDN,但是讓程式碼執行的更快你要做的事情。 程式碼中很小的改動都可能對效能造成巨大的影響。快速靈活的網站和可怕的“無響應指令碼

使用 Chrome 開發者工具進行 JavaScript 問題定位與除錯

引言 Google Chrome 是由 Goole 公司開發的一款網頁瀏覽器,自 2008 年 9 月第一個測試版本釋出以來,其市場佔有率逐步上升,至 2014 年 5 月,Chrome 已超越 Firefox 成為全球市場佔有率第二的瀏覽器。Chrome 的受歡迎程度與其優秀的效能與相容性密不可分,並

還在DW?使用chrome開發者工具作為前端編輯器

chrome本身自帶了一個編輯器,支援程式碼高亮顯示,自動提示,自動縮排,再加上可以實時檢視文件DOM和編輯CSS,簡直不要太好用!支援多檔案編輯! 下面就來看看如何使用這個工具。 1.開啟chrome 按下f12鍵 按下之後就是這個樣子,我已經提前打開了本機

使用chrome開發者工具中的performance面板解決效能瓶頸

前面的話   使用Chrome DevTools的performance面板可以記錄和分析頁面在執行時的所有活動。本文將詳細介紹如何使用performance面板解決效能瓶頸 準備 【匿名模式】   匿名模式可以保證Chrome在一個相對乾淨的環境下執行。比如安裝了許多chrome外掛,這些外掛可

使用chrome開發者工具中的network面板測量網站網路效能

前面的話   Chrome 開發者工具是一套內置於Google Chrome中的Web開發和除錯工具,可用來對網站進行迭代、除錯和分析。使用 Network 面板測量網站網路效能。本文將詳細介紹chrome開發者工具中網路面板network的使用 概述 【開啟方式】   開啟方式有以下三種   

Chrome開發者工具不完全指南(四、效能進階篇)

前言   Profiles面板功能的作用主要是監控網頁中各種方法執行時間和記憶體的變化,簡單來說它就是Timeline的數字化版本。它的功能選項卡不是很多(只有三個),操作起來比較前面的幾塊功能版本來說簡單,但是裡面的資料確很多,很雜,要弄懂它們需要花費一些時間。尤其是在記憶體快照中的各種龐雜的資料。在這篇

Chrome開發者工具不完全指南:(三、效能篇)

<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> div{ height: 20px; widows: 20p

Jerry和您聊聊Chrome開發者工具

html5 sap chrome fiori Chrome開發者工具是Jerry日常工作使用的三大調試器之一。雖然工具名稱前面帶了個"開發者", 但是它對非開發人員仍然有用。不信? 用Chrome打開我們常用的網站,按F12,在Console標簽頁裏看到這些信息,這些都是很

Chrome開發者工具中Elements(元素)斷點的用途

chrom auto gem 文字 view function out bre html SAP Engagement Center UI的這個按鈕會每秒鐘刷新一次,顯示頁面已經打開了多長時間。 需求:需要找到哪行JavaScript代碼不斷刷新的按鈕文字。 按照經驗判斷

Chrome開發者工具詳解(2)-Network面板

eth 令行 完全 ssi .cn mco tools 命令 code 註: 這一篇主要講解面板Network,參考了Google的相關文檔,主要用於公司內部技術分享。 Chrome開發者工具面板 面板上包含了Elements面板、Console面板、Sources面板

F12開發者工具新功能-記憶體分析的作用

今天讓我們再來認識下可以分析記憶體使用的工具:記憶體分析。這是和UI響應工具一起加入到IE11開發者工具中的新功能。 記憶體分析的作用 記憶體分析工具可以幫助你瞭解應用的記憶體使用情況,從而幫助你避免記憶體洩漏或記憶體的過度消耗。要構建可供消費者長期執行的 Web 應用或複雜的互動式應用

Chrome開發者工具詳解(1)-Elements、Console、Sources面板

Chrome開發者工具詳解(1)-Elements、Console、Sources面板 Chrome開發者工具面板 面板上包含了Elements面板、Console面板、Sources面板、Network面板、Timeline面板、Profiles面板、Application面板、Secur

Chrome 開發者工具官方中文文件

傳送門 Chrome開發者工具官方中文文件 Chrome開發者工具詳解 前端學習front-end-study系列 Elements面板(https://zhuanlan.zhihu.com/p/24535735?refer=thinkingInFE) Elements

利用PyCharm的Profile工具進行Python效能分析

Profile: PyCharm提供了效能分析工具Run-》Profile,如下圖所示。利用Profile工具可以對程式碼進行效能分析,找出瓶頸所在。 測試: 下面以一段測試程式碼來說明如何使用pycharm的Profile功能。 測試程式碼見下文,檔案命名為

【善用工具】程式效能分析Gperftools初探(libwind+pprof+Kcachegrind)

gperftools效能分析通過抽樣方法完成,預設是1秒100個樣本,so,一個樣本是10毫秒,即時間單位是10毫秒. 之所以要在這裡特別說明,是因為需要注意到:如果程式執行時間不到10ms,那麼得到的結果可能會和開始執行的時候不同. 0.系統資訊 [email&

Chrome開發者工具-Network面板——公司官網的某張圖片需要優化

Network面板可以記錄頁面上的網路請求的詳情資訊,從發起網頁頁面請求Request後分析HTTP請求後得到的各個請求資源資訊(包括狀態、資源型別、大小、所用時間、Request和Response

Chrome開發者工具(上篇)

本文介紹的 Chrome 開發者工具基於 Chrome 65版本,如果你的 Chrome 開發者工具沒有下文提到的那些內容,請檢查下 Chrome 的版本 簡介 Chrome 開發者工具是一套內置於 Google Chrome 中的Web開發和除錯工具,可用來對網站進行迭

chrome開發者工具的小技巧

本文轉載自酷殼 介紹chrome的一些不為人知的功能 Chrome的開發者工具是個很強大的東西,相信程式設計師們都不會陌生,不過有些小功能可能並不為大眾所知,所以,寫下這篇文章羅列一下可能你所不知道的功能,有的功能可能會比較實用,有的則不一定,也歡迎大家

利用 Chrome 開發者工具遠端除錯 Android 中的原生 WebView

之前寫過一篇關於 Android Studio 斷點除錯技巧 的文章,但都是針對 Native 程式碼的除錯,對於 Hybrid 開發模式下的 WebView 卻無從下手。幸運的是,PC 中的 Chrome 瀏覽器提供的開發者工具能夠幫助我們遠端除錯 Andro

【開發工具】JAVA效能分析:8、超詳細的JProfiler執行緒分析(官方中文版)

Thread Profiling——執行緒分析 官方文件http://resources.ej-technologies.com/jprofiler/help/doc/index.html 錯誤地使用執行緒可能會產生許多不同型別的問題。太多活動執行緒可能導致執行緒不足,執行緒可能會相互阻塞並