OneProfile 是一個網頁版的小工具,可以用全新的方式展示 JavaScript 性能分析的結果,幫助開發者洞悉函數調用關系,優化應用性能。
背景
Chrome Dev Tools 自帶的 CPU Profile 功能非常好用。用它可以方便的生成 JavaScript 的 Flame Chart
。

更棒的是你可以把 Flame Chart
導出,留著下次或者拷貝到其它機器上查看,特別好奇它是怎么實現的。
但是網上關于它的文件格式以及怎么畫圖的文檔非常稀有,所以我自己摸索了一下它的文件格式,并嘗試著用另一種方式展示 CPU Profile 的結果。
如何生成 CPU Profile 文件
使用最新版的 Chrome 打開任意一個 測試網站,按 F12 打開 Devtools
, 切換到 Profiles
頁,點擊 Start
開始
收集 Profile 信息,在當前頁面任意滑動鼠標等待大約5秒后, 點擊 Stop
停止 Profile。在生成的 CPU Profile 名字上單擊右鍵可以導出 .cpuprofile
后綴名的文件。
你可以自己生成一個,也可以直接下載這個用來測試 sample.cpuprofile
理解 .cpuprofile 文件格式
用你的編輯器打開 sample.cpuprofile
,你會驚奇的發現:
1. sample.cpuprofile
其實就是一個 JSON 格式的文件,有 head
, timestamps
, samples
等幾個重要的屬性
2. head
指向一個結點,官方的名字叫CpuProfileNode
,同時它的 children
指向子結點, 因此是一個嵌套結構
3. CpuProfileNode
有很多重要的屬性,包括 functionName,lineNumber,columnNumber,hitCount 等
4. timestamps
是一個數組,記錄著 Profiling 過程中每個采樣點的時間戳
5. 對應 timestamps
下的每個時間點,samples
數組相同的位置都會有一個數字,這個數字比較神秘,后面解釋
CpuProfileNode 詳解
{
"functionName": "lineTo",
"scriptId": "0",
"url": "",
"lineNumber": 0,
"columnNumber": 0,
"hitCount": 45, // 被采樣到的次數
"callUID": 6, // 函數入口的 UID
"children": [],
"positionTicks": [
{
"line": 1,
"ticks": 45
}
],
"deoptReason": "", // 逆優化的原因
"id": 11
}
samples, timestamps 和 CpuProfileNode 的關系
如果從 head
開始,對 head
結點及其 children
屬性下的結點做一次深度優先的遍歷,每個可能路徑都會有一個編號。
研究表明這個數字正對應于 samples
的值。因此知道了路徑編號,便可以知道那些函數處在激活狀態。在 OneProfile
中用藍色表示。
OneProfile 使用說明
鏈接地址
使用 Chrome 打開: OneProfile
圖例
黑色
系統函數
暗紅色
存在逆優化的函數,鼠標懸停可見原因
藍色
當前采樣點活動的函數
操作
滾輪
縮放窗口
prev
前一個采樣點
next
后一個采樣點
一些用例
某在線地圖網站的前端代碼,紅色較多說明存在大量 v8 無法優化的代碼

是不是很像外星人

( 請原諒作者笑點低 >< )
關于
本文相關的源碼在:
https://github.com/wyvernnot/javascript_performance_measurement/tree/gh-pages/cpuprofile_topology;
本文由OneAPM工程師原創 ,想閱讀更多技術文章,請訪問OneAPM官方技術博客。