# Flutter DevTools
本場次相關紀錄如下 (歡迎大家增加你的心得)
---
## 技術相關
1. DevTools: 開發 Flutter 相關的工具,像是Performance tool, Inspector tool, Debug tool.
2. 檢查 Layout 的問題,建議可ㄧ使用 Layout Explorer.

3. Timeline 可以顯示 App 在執行過程中的效能(by timeframe)。

4. Performance 能夠及時檢視 App 執行時的 CPU 使用狀況

5. Debugger inspector tool

6. Logging tool
---
## 補充知識
---
## 問題紀錄
---
## 逐字稿
Andrew Fitx Gibbon
And 我們回來了!
看起來在 codelabs 上有很多動靜, 而且我一直有跟上 streams (直播?) 來自整個社群, 能夠看到這麼多參與真的是太 wonderful 了! 例如來自 Florida 的 Hendrix Tavarez 帶我們看過了 Dart 跟 Flutter 的初次體驗影片. And then i caught up with the videos released the last couple of days, 例如 Mahtab 跟 Max 的 [Flutter Explained](https://www.youtube.com/channel/UCgUnLn1FpuHHmO66vn4o1NA) 頻道, 直播 coding some form controls. 在今天以及這整個週末, 還有很多活動像是 "Flutter Day Turkey" run by Sebagian besar, Flutter Karachi 正在舉行 online quize, and "Women in tech Saudi Arabia" organized by Mace, running in content 在接下來的 6天中. There are so many streams going out throught the community I can't list all. 我希望你能 catch one of these 靠近你的 Flutter Day 活動, 不論是今天明天或是接下來幾天. 在此同時歡迎你回到這個直播, 如果你剛加入我們, Hi! thanks for join in. 你可以查看下面影片描述中的 links, 有關更多 Flutter Day 的資訊.
特別是我們有很多 codelabs 其中有一些是新的, 另一些有 refresh 更新. 這些 codelabs 是一個學習更多經驗很好的方式, 涵蓋各種不同的 Flutter Topics 主題. 也許, 你可以在其中 finding some puzzle pieces. (找到一些問題的解答)
but starting right now, Kenzie Schmoll (Software Engineer) and Filip Hracek (Developer Advocate) will talk about performance in some of the newest features of DevTools. And we'll have them back just after it for a Live Q&A.
Let's listen in.
F: 嗨, 我是 Filip, Developer Advocate of Flutter team. I'm here today with Kenzie. Hi Kenzie.
K: 嗨, Filip. I'm Kenzie. I'm a Software Engineer on the Flutter Developer Experience Team.
F: Kenzie is actually one of the engineers behind DevTools. And that's what we'll talking about today. So you know, eh, that's fortune (這很幸運).
F: so, Kenzie, 什麼是 DevTools?
K: DevTools is tooling suit of Flutter & Deat 開發人員, 包括 Layout 檢查工具, 效能工具, 記憶體工具, really just all the debugging tools you need to be an efficient and effective Flutter Developer, bundled into single web suit for you.
F: oh, so, DevTools 已經存在一段時間, 但是妳顯示畫面有點不一樣.
K: it is a little different. 我們實際上重寫了整個 suit (套件), 而且新增了一些很酷的新功能! and the best part is, 我們用 Flutter 重寫了整個 DevTools.
F: 所以這是 Flutter 工具, 用 Flutter 寫成, 在 web browser 裡運行.
K: YES.
F: 妳有用過 DevTolls debug DevTools?
K: YES! I DO use DevTools to debug DevTools. and it's quite USEFUL.
F: AWESOME. 讓我們真正示範一下如何開啟 DevTools. 在 Android Studio 中, 如果你 run your application in debug 或 profile, 你會看到一個小 icon 可以點擊, 並在你喜歡的 web browser 打開 DevTools . 如果使用的是 VS Code, 則有一個方便的小通知.
如果是用 command line run flutter application, 也有方法可以從 command line 執行 DevTools, 不過今天不會示範.


F: 我想要示範, 我們今天將試著進行 debug 或是 trouble shoot 故障排除. 示範用的 App 叫做 Sloth App. 我已經使用它一段時間了. 真的是太可怕了, 到處都是問題, low performance, inefficiency 和類似的問題. 不過那都是故意的. 所以我想要 show you how to use DevTools to make things right, in App like that. 希望你的 Apps are better, but you know. ?! xD
F: so the App sturcture is like that, i have it here my phone, and it's just, eh, you know, connected to my screen, so you can see it. 但是它的結構是, 在每個第三頁上一直有一些問題. And the reason for that just different issues, don't interact with each other. so they are separate, right.
F: 我們先來看第一個問題, 這實際上是 Layout 問題. 這裡有一段文字 "Flutter is Google's UI toolkit to buil beautiful, .....", 文字在 UI 上被切斷了, that's not great, it seems like a Layout 問題, 可能... 我想看一下 code, 可能有一點難去 parse 這到底是什麼問題. Kenzie, DevTools 可以怎樣幫我 help there?
K: 所以要解決這個問題, 我們將要在 DevTools 中使用 Flutter Inspector. 這個 tools 可以幫助你診斷並 debug Layout 問題, 而且 just 全面了解 of the general layout of your Flutter Application. 所以這裡我們可以看到同一個 Filip 做的 App 正在執行, 而且我正在 debug 模式下執行, 因此我們可以看到這些錯誤. 而且我們看到了大家都很熟悉的 Precaution Tape Error, for Render Overflows.

K: 我們想使用 Inspector 來找出為什麼會發生這種情況以及我們如何可以解決它.
K: SO, 我選擇了 Row, 包含 Flutter Logo 跟 Padding. 你可以看到這是一整個 Row. 我們能做的, 只要看這邊的 Summary Tree, 這讓我了解 the Overall View of the Widget 的階層結構 (hierarchy), 找到我想要找的 widget, 就是這一行 Row. 然後我們跳到 Inspector 右邊的細節區塊, 它讓我們可以查看點選到的這一個 Row 的特定屬性, 以及這個 Row 的 children widgets 的特定屬性. 所以我們可以做的就是查看這裡, 並嘗試檢查 Render Object 的 constrain 屬性, 看看是否有什麼東西沒有設定 constrain 或是其他可以修正的問題. 但這很複雜, 也不是很方便 Friendly.
K: SO, 我們將使用 the Layout Explorer, 這是我們添加到 DevTools (Flutter 版) 的新功能, 才剛剛發布 release. 這是一個很好的例子, 我們使用 Flutter 來開發我們的 App, 能夠讓我們打造一些真的非常酷的功能. 如果是在以前的不是 Flutter 開發的版本, 可能會更困難做到.

K: So, 在這個 Layout Explorer, 我可以調整某些值, 例如 Axis Alighment or flex values. 我可以看到我的修改已經自動 hot reload into my running application. 所以這讓我可以 plug-n-play, 調整不同的屬性, 試試看有沒有哪一個屬性的調整可以 fix 這個 overflow issue. 所以我現在要試試看不同的屬性, 看看這個能不能修正問題. 嗯, 這個不行, 我們放回去. Ok, 我們找到了! The Render Overflow Error 消失了. 現在我們的 Padding Widget 有設定 flex 值, 所以這一行 Row 知道 to give the remaining space to the padding widget. 現在我可以回到我的 application 程式碼並做出調整. 這樣對你有幫助嗎, Filip?
F: Absolutly, Yes. 讓我們實際秀一下這個是怎麼做的. 所以我這邊有程式碼, 這是 Flutter Logo 跟 Padding, 然後我可以 just 用另一個 DevTools 功能, 叫出功能選單, 選擇 "Wrap with widget...", 使用 Flexible 或是 Expandable 來包住 Padding widget, 來給予 Kenzie 在 UI 中設定的 flex 值. 我認為這邊的關鍵是, Kenzie 可以不用實際看到程式碼也能 debug. 至少對我來說, 如果我在 Layout Explorer 看到它, 就會更容易理解. So ok, so these Children Widgets want to take this much time, eh, 不是 this much time, 是這麼多寬度, 而且它們做不到, 因為就是沒有這麼寬. 你也可以看到, 如果你在 Layout Inspector 點選 Text 或 Padding, 它們不是 flexible. 如果你以前用的是其他 framework, 可能會想, oh, but Text 應該要是 flexible 的吧? But, 根據 Flutter 的 Design, it's not, 你要把 Text 放進 Flexible 或 Expandable widget, 它才會有 flexible 的屬性. 所以使用 DevTools, 它可以解釋並且可以很快為你指向正確的方向.
F: 讓我們來看下一個例子, 下一個例子是 Performance 效能問題, 我最喜歡的一種問題. So, 我將點開右側的 (turn on) Performance Overlay, 然後我們來這邊.

F: 它應該是一個看起來很正常的無限列表, 對吧? But then, 在某個時候, 我不知道你是否能夠看到在滾動的時候, 會有些微的停頓. 但是你一定可以看到在 Performance Overlay 裡面出現一個突然飆高的數值. 而會發生這樣的情況, 其實是有某個原因造成的. Again 同樣地, 我們可能會想要直接去檢查程式碼. 但是試著想像一下如果這段程式碼非常複雜, 無法馬上找到問題點. 所以如果我真的很想透過 DevTools 找到程式到底發生了什麼事情的話, DevTools 在這裡可以怎麼幫助我們呢, Kenzie?
K: Yes, so let's look at the Timeline in DevTools 來解決這個問題. 所以這裡在 Timeline 我有資料已經載入, 來自於 Filip 剛才滾動無限列表的同一個 App. 在這一頁我會解釋幾個不同的區塊.

K: 所以, 這個最上面的圖表是 Flutter frame 圖表, 這邊基本上顯示所有來自你的 Flutter App 的 Timelive 活動, 並且根據 Flutter frame 拆分開來. 這樣一來, 你就能看到當你出現某一個 frame 卡住, 或是某個 frame 被漏掉了為了達到 60 FPS 的高 frame rate. 所以對於這個例子, 我們可以看到, 顯然有一個罪魁禍首的 frame 花費了太長時間. 這個很可能就是在尋找效能問題時我們想要檢查的地方.
K: 所以如果我選擇這個 frame, 將會放大相關的這些 Timeline 事件, 顯示在下方. 所以在這個圖表中, 我們有一些事件, 是 asynchronous 事件, 可能來自 Flutter framework 或是來自進來的 HTTP 事件, 甚至可能是你透過 Dart Developer API 觸發的事件. 這邊我們也有看到一些 synchronous 事件, 來自於 Dart threads, UI threads, 或是 events that pertain to the raster portion of drawing a Flutter frame, 因此來自 Flutter 引擎之類的. 所以以這個例子來看, 我們可以看到 UI 相關的 frame 或占用大量 CPU 時間的 Dart code. 我們顯然可以看到這塊 frame 吃掉很多時間, 但是我們真的沒有一個好主意, 關於在這一系列事件中到底發生了什麼事情, 該如何來解決發生在我們 App 中的問題.
K: 因此, 要解決問題, 我們實際上將使用一個功能, 叫做 "追蹤 Widget builds". 所以, 我現在會清除 Timeline 並且啟用這個功能.

K: 基本上這就是當我們接收事件時, 從 Flutter 框架開始, 它實際上是在發送事件, 對於這段時間內 build 的每個 widget, 在 Flutter framework 中的 build 部分正在發生. 所以, 我們不僅知道框架的 build 所花的時間, 你可以看到花了很長的時間, 然後我們可以更深入挖掘檢查有哪些特定的 widgets 正在被 build.

所以我選了一個時間很長的 frame, 我正在 zoom in 圖表中的這些事件. 看起來我們正在 build 我們的昂貴 widgets, 而且它佔用了相當長的時間. 然後我們也可以看到一些正常的 widgets 也在 build, 但是它們的 build time 並沒有很嚴重. 如果要我做一個大膽的猜測, 我會說 "MyExpensiveWidget" 可能是問題的原因... 你覺得呢, Filips?

F: 嘿這個... 我忘了我寫過這個 "MyExpensiveWidget" 了. 如果你檢查程式, 你會看到這一個 widget, 它實際上正在 build 一堆 MyNormalWidget 放在一個 Stack 裡. 總共有 100 個, 所以基本上是 build 一個普通的 widget 但是執行 100 次, 彼此疊加上去. 這段程式對效能不好, 而且這也是完全荒謬的.

但是在這裡同樣的, 這只是一個例子來證明, 這樣的事情, 即使不看程式, Kenzie 也可以找出答案, 喔這裡有問題, 某一個 widget 怪怪的, 然後我就可以看看我的程式, 檢查一下到底發生了什麼事情, 對不對? 所以, 這其實很有幫助, 我們可能可以說 "追蹤 Widget builds" 這個功能, 在預設的情況下是 disabled, 是有原因的. 因為它會占用大量 profile 所需的資源, 例如 modle Ap, 來追蹤所有這個 widgets 以及它們 build 的過程. 因此你不會想一直開著這個功能, 因為這樣會讓你的 profile build Apps 變得比實際情況還要慢, 也會干擾你的測量分析或是類似的東西. 但是偶爾打開它來看看, 也會非常非常有幫助. 只要很簡單地在 DevTools 中啟用它, 就能夠深入了解有哪些 widgets 需要花費多少時間, 以及其中包含的東西. 所以這真的是超級有幫助!
F: 好吧, 讓我們來看看第三個問題, 我想這是我們的最後一個. 看, 這是另一個無限滾動 View. 而實際上, 這個例子不管怎麼滾動都會卡住, 而不是某一個 widget 卡住而已, 通常這並不是一件好事, 而且正如你在 Performance Overlay 那個例子學到的, 也許我們只要看一下它滾動時 frame 效能的情況, 就可以看得出來不是很平滑, 對不對?

F: 所以我想知道到底發生了什麼事情. 我當然可以看看實際的程式, 所以, 在這個例子, 我只有一個 ListView.builder, 那很棒. 然後我們可以看一下 ItemLine widget, 然後發現這一切看起來都很正常, 你有 Container, Row, SizeBox, Expanded 這些 widgets. 沒有什麼線索可以顯示這個 App 執行的時候會變慢. 當然我們可以更深入更深入地閱讀檢查每一行程式. 但是另一種方式會超級好, 假如我可以看看 DevTools 並且讓它告訴我, 我應該先看哪些地方. So, Kenzie, 妳可以幫幫我嗎?
K: yea ah, 所以這邊是一個 Timeline 的例子, 剛才我們有說 Performance Overlay 是一個效能檢查工具, 但它可能無法用來解決所有效能有關的問題. 所以這邊我又有錄製了剛才 Filips 遇到的問題的 frame 圖表. 但是你可以看到, 沒有某個特別的問題跳出來, 沒有某個 frame 特別卡住顯示說, 嘿這邊有點問題, 某一個 build 方法或其他方法正在執行消耗很多效能的動作. 從這次的 frame 圖表中, 沒有任何超過 60 FPS 的情況發生, 所以也許, 這個例子的效能問題不是單一 frame 出問題, 而是跨好幾個 frame 相關的問題. 要檢查這類型的問題, 我們將會採用傳統的 CPU profiler 來解決問題.

K: 所以我要做的是開始錄製, 同樣地我手上有剛剛 Flips 展示的 App, 我將重現他看到的相同問題. Ok, 我們停止錄製, 現在我已經為這個 App 記錄了 CPU Profile, 顯示在滾動那個 list 時發生的情況. 而且我們可以透過不同的觀點來看這些數據, 例如第一個 tab 是 CPU Flame Chart, 這是一個圖形表示或叫做視覺展示這個 CPU Profile 的內容. 我們收集的每個樣本, is what the call stack looked like at the time we sampled it. And so we can aggregate all that data to merge common samples, and then help you identify hotspots within your application of, OK, this path was hit a lot, something must be happening down there.

K: So 這就是 Flame Chart, 相同的數據, 從上到下. 第二個 tab 是 Call Tree. 所以在 Call Tree 裡面我們可以再次確定占用大量資源的程式路徑. 所以, 你可以看到, 在此 Profile 中有 68% 的樣本, 是從 \_drawFrame 開始, 這看起來很正常. 我們繼續瀏覽 Call Tree 裡面的 call stack 列表, 所以這可以幫助我們了解哪些 path 很耗效能.

現在, 我們想尋找有沒有單一個 method 佔去很多的 CPU 時間. 所以我們再切換到第三個 tab, Bottom Up 圖表, 其中, 這些方法中的每一個都是, 位於我們採樣的 call stack 的頂部. And so if we have multiple samples that have a shared method on the top of the call stack, that's a good indication that the CPU is spending a lot of time in that method.

K: 在這裡我們可以看到我們花費了 32% 的 CPU Time 在一個 \_fibonacci 的方法中, 我敢肯定, 我們所有人都可以做一個大膽假設, 這個方法應該是 recursive 呼叫的. 我們可以在這裡看到, 它的確是不斷遞迴呼叫, 佔用了很多時間. 所以, Filips, 也許你可以在你的 App 裡找到一個叫做 \_fibonacci 的方法. 看看你是不是在不正確的地方, 呼叫了它.
F: 好的, 是的! 事實證明我真的有呼叫 \_fibonacci 這個方法. 所以在這個例子, 我想證明的是即使我根本不用看我的程式碼, 只要看一下 DevTools 裡的圖表, 我就可以找到, 看到某一個方法有問題, 然後說, 嘿, 這個 \_fibonacci 的方法是做什麼的? 它正在拖慢我的 App 嗎? Ok, 我們看到程式碼中, 實際上有兩個類似的名稱. 我們可以看到, 實際上是在同一個 ItemLine widget 裡面, 我正在對所有的 sub title 計算 \_fibonacci 數列, 毫無任何理由, 除了這很糟糕之外. 因此顯然這不是一件好事. 我只想再強調一次, 在這裡, 即使這個例子可能是荒謬的, there are other things that you as a developer want to do that are computationally expensive, and you sometimes do them in build methods without even realizing it, right? Like you are parsing JSON. You are processing mark down. You're doing all this stuff, like regex and stuff like this. And from the top line view, it doesn't seem that there is any problem.

F: And it's really hard to find out why is my app slow here? But if you look at the bottom of the table, you can see, oh, actually this particle method is taking this many milliseconds every frame. Where is it called from, and why? And then you can deal with it. So the way you would deal with this particular problem is just, don't show Fibonacci numbers in subtitle. But in other places, you could cache these things. You could pre-compute them before the user even comes here. But you can also kind of spread the work through different frames. So sometimes you do have to, I don't know, parse a little bit of something. And then you don't maybe need to parse all of it in one frame. And third, and probably the best option is, if it's really something computationally intensive, is just go and make that computation on a different thread. So use Dart isolates. And that's very easy. My computer almost fell down. But that's OK. I saved it. So yes, you can do this. And it's very helpful to be able to look at the CPU profile.
F: All right, So Kenzie, I think we are almost at time. This is it. But could you show us some other things that DevTools can do for us?
K: Sure. So I've already shown some of the layout inspection tools as well as performance tools in DevTools, but we also have tools for a variety of other use cases, such as the memory page.

So the memory page allows me to see a live view of both Dart and Android memory. so I got my native memory on the right, and then the Dart memory over here on the left. And as I do things in my application, the memory increase will show in the graph, or as garbage collections happen, those will show in the graph as well. And I can take snapshots to get a live view of what my heat look like at the time I took the snapshot.
s w i j s
c o w g o
t v
so p s e e p s b
s t r
a n i i t i
s t m p
we also have n page
inspect those
pattern
rdceived
y i
t i id
b mw i i want to
p a l o p
so thats what itis
set a breakpoint
step ver it
a ailabe
valuemto the console
green screen n the app
there
lets resume
and we also have
gc events
gave a special tag
my_ etwork_log
so thats kind fun
we can
took 52 m seconds
so again
hopfully
what we have to offer
De Tools documentation
whats new there
that area availabe
super useful
for both showing
audience
Q&A
h w a a f
h
h
e
k
i n
stable
which new bit y f
previous version
as
layout ex inspector
ubderstanding
use often
sloth app
bamgamut
th
generally
visually
network tabmbottomup
grateful for that
boost the performance
canvas kit
kia backend seems great
really useful forus
hot reload is great
we should say
soni guess
the rest you can
constanc
so i have a complement
how can you check th ecode coverage
fluter test--coverage
---