Dart DevTools

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

I guess I'll start using those tools now :) pretty dope actually

👍︎︎ 5 👤︎︎ u/foreveryellowXL 📅︎︎ Jul 09 2020 🗫︎ replies
Captions
[MUSIC PLAYING] FILIP HRACEK: Hi, I'm Filip of Developer Advocate on the Flutter team. And I'm here today with Kenzie. Hi, Kenzie. KENZIE SCHMOLL: Hey, Filip. I'm Kenzie. I'm a Software Engineer on the Flutter Developer Experience team. FILIP HRACEK: Kenzie is actually one of the engineers behind DevTools. And that's what we're talking about today. So that's fortunate. Kenzie, what are DevTools? KENZIE SCHMOLL: So, DevTools is a tooling suite for Flutter and Dart developers consisting of layout inspection tools, performance tools, memory tools-- really just all the debugging tools that you need to be an efficient and effective Flutter developer bundled into a single web suite for you. FILIP HRACEK: Oh, so the DevTools have been around for a while. But what you're showing is a little different. KENZIE SCHMOLL: It is a little different. We actually rewrote the entire suite and added some cool and new features to the tooling suite. And the best part is we rewrote it entirely in Flutter. FILIP HRACEK: So it's Flutter tooling written in Flutter running in a web browser. KENZIE SCHMOLL: Yes. FILIP HRACEK: Do you use-- do you use DevTools to debug DevTools, Kenzie? KENZIE SCHMOLL: I do. I do use DevTools to debug DevTools. And it's quite useful. FILIP HRACEK: Awesome, awesome. Let's show how you actually get to DevTools. In Android Studio, there is this-- if you run your app in either debug or profile, you have this little icon which you can click on, and it opens up DevTools in your favorite web browser. If I was using VS Code, there's this handy little notification here. But also if I was actually running the app from here, there would be a similar-looking icon that I could click. So it's pretty easy to get to. And even if you're running from the command line, there's ways to open it up from the command line, which I will not be doing today. I wanted to show you-- or I wanted to start with the app that we'll be trying to debug or troubleshoot today. And the app is called "Sloth App." And it's something that I've been using for a while now. It is just terrible. It's full of issues and full of performance inefficiencies and stuff like this. And that is intentional. And so I want to show you how you would use DevTools to make things right in an app like that. Hopefully your apps are a little better. So the app is structured like this. I have it here on my phone. And it's just connected to my screen so that you can see it. But the way it's structured is that there is always some issue on every third page of this page view. And the reason for that is just so that the different issues don't interact with each other. So they are separate, right? So let's have look at the first issue, and that's actually a layout issue. So here, you have, "Flutter is Google's UI toolkit for building beautiful," and that's cut off. And that's not great. It seems like a layout issue, but maybe I want to look at the code. Maybe it's a little hard to parse what exactly this means. Kenzie, how can DevTools help there? KENZIE SCHMOLL: So to solve this problem, we're going to want to use the Flutter inspector in DevTools, which is our tool for helping you diagnose and debug layout issues and just getting an overall understanding of the general layout of your Flutter application. So here, we can see I have the same app running that Filip does. And I am running in Debug mode so I can see these errors. And we see the all-too-familiar caution tape error for render overflows. And we want to use the inspector to figure out why that's happening and how we can fix it. So, I have the row selected that contains the Flutter logo and the padding. If I enable that, you can see this is the overall row. And what I can do is look in the summary tree here-- that gives me just the overall view of my widget hierarchy-- find the widget I'm looking for, which is this row, and then jump over to the Details side of the inspector, which allows me to look at specific properties for that row, as well as the properties for children of the widget and so forth. So what we could do is look through here and try to look through the renderObject constraints and see if something's unconstrained or if there's something that we can fix. But that's complicated and not very friendly. So we will use the Layout Explorer, which is a feature that we added to the Flutter version of DevTools which was just released. And it's an example of where building our own app in Flutter allowed us to build some really cool features that would have been more difficult in the previous version. So in this Layout Explorer, I can tweak certain values of, say, axis alignment or flex values. And I can see the change hot reloaded into my running application. So this allows me to kind of plug and play with different properties and see if there's anything I can fix. So I'm going to play with properties and see if it fixes my problem. That didn't, so I'll put it back. And there we go. The render overflow error goes away, and I now have my text widget in this application where the padding widget containing the text has a flex value so the row knows to give the remaining space to that padding widget. And now I can go back to my application and make that change. Does that help, Filip? FILIP HRACEK: Absolutely, yes. Let's actually show how that would work. So I have the code here. It's a Flutter logo and a padding. And then I can just use another DevTool thing-- I mean, develop tool thing which is the wrap with the widget. And I can use either Flexible or Expanded here to give it the flex value that Kenzie did in the UI. And I think the key thing here is that Kenzie could play with it without actually touching the code. And it's-- at least for me, it's much more understandable if I said in the Layout Explorer that, OK, so these children want to take this much time and make-- it's not this much time-- this much width. And they can, because there is just not enough. And you can also see, if you click on the padding or text, it's not flexible, which coming from a different framework, you might be like, oh, but text should be kind of flexible, right? But no, it's by design. It's not unless you put it into a flexible widget like Expanded or Flexible here. So it explains and also really quickly points you to the right direction. So I [INAUDIBLE]. All right, let's have a look at the next example. And the next example is a performance problem, my favorite kind of problem. So I'll turn on the performance overlay. And I'll just go here and edit-- it should be a pretty normal-looking infinite list, right? But then at some point, you see that-- I don't know if you actually see the jank of the scrolling itself. But you can definitely see that spike there in the performance overlay. And that happens for some reason. And again, I might want to look at the code. But imagine the code is very complicated. I would love to find out what's going on through WebTools. So, Kenzie, how can WebTools help here? KENZIE SCHMOLL: Yeah, so let's look at the timeline in DevTools to solve this problem. So here in the timeline, I have data loaded from the same app and scroll that Filip just showed. And I have a few different parts of this page to explain. So the top chart here is the Flutter frames chart, which basically takes all the timeline activity that's coming in from your Flutter application and breaks it down by Flutter frames. So you can see you when you have a single janky frame or a single frame that maybe missed the budget you need to hit in order to achieve a high frame rate of 60 FPS. And so for this example, we can see that there's clearly one culprit frame that is taking too long. And that's where we would probably want to look to find our performance problem. So if I select this frame, that's going to zoom these timeline events below to the timeline events that correspond to that frame that I selected. So in this chart, we have events that are asynchronous events either from the Flutter framework or HTTP events that come in, or even events that you sent yourself from the Dart developer APIs. And then we have some synchronous events that also come in on either the Dart threads, the UI thread, or events that pertain to the raster portion of drawing a Flutter frame, so from the Flutter engine and similar of like that. So for this example, we can see that it's the UI portion of the frame, or the Dart code, that's hogging CPU and taking too much time. And we can obviously see that's taking time. But we don't really have a good idea of what exactly is happening within this chunk of events that we need to solve in our application. So to solve this, we're actually going to use a feature called Track Widget Builds. So I'll clear the timeline and enable this Track Widget Builds feature. And basically what that does is when we are receiving events from the Flutter framework, it's actually sending events for each widget that was built during the time that the build portion of a Flutter frame is occurring. And so not only do we know, hey, the build time of this frame took a long time. We can then dig further into which specific widgets were being built. So here is the long frame again. I selected it. And I'm zooming to these events in the chart. And it looks like we are building MyExpensiveWidget, and it's taking quite a long time. And we have some normal widgets that are occurring, but these build times aren't really concerning. If I had to take a wild stab at it, I'd say that MyExpensiveWidget is probably our expensive widget. What do you think, Filip? FILIP HRACEK: I forgot all about MyExpensiveWidget. It is a widget that, if you look at the code, is actually building a stack of normal widgets that is 100 items deep. So it's basically one normal widget but a hundred times overlaid on top of each other, which is not great for performance. And it's also totally absurd. But it's-- again, I needed some example to show that even things like that, even without looking at the code, Kenzie could find out, oh, there is a problem here, and it's called-- the widget is called something. And I can look through my code and see what's going on there, right? So that's super helpful. I would probably say that Check Widget Builds is disabled by default for a reason. It takes resources for the profile mode app to track all these widgets and their builds. So you don't want to have it on always because it will make your profile-built apps slower than they actually should be. And it interferes with your measurement and stuff like this. But it's really, really helpful to be able to open it up once in a while or turn it on so simply in the DevTools and then drill down to what exactly which widgets take what time and what they contain. So that's super helpful. All right, let's have a look at the third problem, and I think our last. And look, it's another scrolling-- infinite scrolling view. And this one is actually janking all over the place. It's not just one widget there. But it's just generally not great. And as you can see here in the performance overlay, or maybe even just by looking at the scroll, it's not super smooth, right? So I would like to know what's going on there. And I can, of course, look at the actual code. So in this case, I have just a listView.builder. That's great. I can look at the item, and I see that this is all very-- you know, so like you have Container, Row, SizedBox, Expanded, Text. Like, there's nothing that could indicate that this thing is slow in any way. And I could go deeper and deeper and read the whole thing. But again, it would be super nice if I could just look at DevTools and let it tell me where I should look first. So Kenzie, can you help with that? KENZIE SCHMOLL: Yes. Yes, DevTools can definitely help here. So here's a recording of what Filip just showed in the timeline again. But in this case, I'm not seeing anything jumping out at me that says, hey, you have a janky frame. Go fix what's happening in a single frame being built in your app. This is a situation where we have a performance problem, but it's probably over a span of frames rather than happening in a single Flutter frame. So the timeline may not be the best tool for this. And what we can probably do is just use a traditional CPU profiler to figure out what's going on. So what I'll do is I will record. And then on my phone, I'll do the same scroll that Filip showed. Stop the recording, and now I have a CPU profile for what I just recorded in my application. And what that looks like for this is we have a few different visualizations we can show. So this is the Flame chart, which will give you a kind of top-down visual representation of that CPU profile where each one of these little samples is a sample of what the call stack looks like at any given time that we took it. So then we aggregate them all together and then put it into a nice Flame chart graph for you to spot out hotspots within this graph. We also have a Call tree, which is basically the same thing as the Flame chart, but instead of using a graph, we use a table view. And this is going to help you identify expensive paths. You can see that 63% of the samples we took began with _drawFrame, which is to be expected. We were just scrolling through a list. But this isn't going to help us identify expensive methods. What we want to do for that is use the Bottom Up chart. So if I go to the Bottom Up chart, it'll sort by the time that the CPU profiler or the CPU was actually spent in a single method. So when you take a sample, whatever's on top of that call stack, that's where the CPU is actually spending its time. And we had a lot of our samples in this method right here, fibonacci, which, just to take a guess at what that method does-- and to look here, it's probably recursive. And we're probably spending too much time doing something with fibonacci. So does that help, Filip? FILIP HRACEK: Oh, yeah. Yeah, it turns out I am actually using fibonacci. But I want to show that even if I didn't know my code at all, just looking at the method name, I could just go and say, hey, what are the fibonacci methods that I am calling in my app? And there's actually two. But if I look at this one, it's actually in the same item line. And it turns out that I am computing Fibonacci numbers for every of these subtitles for no particular reason except to be terrible. So it's obviously not a good thing to do. I just want to, again, make a point here that even though this example may be absurd, 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're parsing JSON. You're parsing Markdown. You're doing all this stuff that might be like regex and stuff like this. And from the top-- that line view, it doesn't seem that there is any problem. And it's really hard to find out, like, why is my app slow here? But if you look at the Bottom Up table, you can see, oh, it's actually this particular 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 deal with this particular problem is just don't show Fibonacci numbers in subtitles. But in other places, you could cache these things. You could precompute 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. Then you don't maybe need to parse all of it in one frame. And third, and probably the best option, if it's really something computationally intensive, is it just go and make that computation on a different thread. So use .isolate, 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. All right, so Kenzie, I think we are almost at a time. This is it. But could you show us some other things that DevTools can do for us? KENZIE SCHMOLL: Sure. So I've already showed 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 heap looks like at the time I took the snapshot. So what I just showed was the Heat Map view where we can zoom into the heap and check out what's going on and what's hogging the memory. Or we can look at it in a table view and just kind of jump into the classes and objects that are allocated and how much space they're taking. So Filip showed earlier that each page is separated by a different GrayPage. So you can see we have 11 instances of GrayPage and only one of the GreenPage. So that reflects what we would expect. And then you can go even further and look at the instances to see if there is any notable information in those instances. So that's the Memory page. We also have a Network page, which collects HTTP requests that come in and allows us to inspect those to check out their headers, their properties for the response and request, as well as any timing data. So when was it initiated? When was it received? And this is a lot easier than doing print debugging. So if I have a network request coming in and I want to check out the isolateId, for example, OK, I can print that. But then what if I also want to see the contentLength? Well, I can print that too. But what if I also want to see the reasonPhrase? And you can use your imagination. Printing a lot of properties for an object like this can be time consuming. And wouldn't it be nice if there's just a nice network inspector for you to look at all those properties in our tool? So that's what this is. So that is the Memory page, the Networking page, and then a couple other things to show-- we have a full source-level debugger. So I can set a breakpoint-- I'll set a breakpoint here, which should be hit. And I can step over and in and through, just as we'd expect. I can also look at the variables that are available at the breakpoint and inspect those properties and values. And I can see print logs that come in. Anything that's coming to the console will come directly to me. I can look up other classes and files in my code. So let's maybe look at the green screen. And here's the green screen in the app. And I can inspect that code and just read through the source there. Let's resume and get out of the debugger. And then we also have a Logging view that listens for logs coming into your application, whether those are GC events or just regular console prints, or even logs that you've tagged yourself. So here is a log that Filip gave a special tag. The Flutter framework's not the only one that can make nice tagged logs. So he did that. And let's say I only want to see my_network_logs that come in. I can filter for those in this Logging view and only see those requests. Or let's say, I don't want to see anything from GC events. So I can do a negative filter and get rid of those. So that's kind of fun. Another thing to call out in this Logging view is see these Flutter frame events. Because we're displaying this in Flutter and not just a console, we can do creative things like give you a visual representation of how long the frame took. So here's a Flutter frame that took 52 milliseconds to render and one that took 31. And so you can see the proportional difference between this bar visualization. So again, something that's just-- we were able to do in Flutter that was really easy and elegant and makes it hopefully easier for you to understand and read. So that's a brief overview. Hope that helps and gives you a good idea of what we have to offer. FILIP HRACEK: Thanks. OK, so I want to encourage everyone to go to flutter.dev and look at the DevTool documentation. There's a bunch of pages right here. So you should read all those. But maybe more importantly, just fire up DevTools, see what's new there, and try to play with it, because I guarantee you that you don't know about all the things that are available. And many of them will be super useful at some point in your future. So, all right. I think-- well, I want to thank you, Kenzie, for both showing us today what DevTools can do and for building these tools in the first place. And I want to thank you, audience, for watching. KENZIE SCHMOLL: Thank you. [MUSIC PLAYING]
Info
Channel: Flutter
Views: 45,891
Rating: undefined out of 5
Keywords: dart devtools, intro to dart devtools, dart devtools tutorial, how to use dart devtools, Flutter devtools, intro to flutter devtools, how to use flutter devtools, flutter devtools tutorial, flutter day 2020, flutter developers, developers, developer, flutter developer, flutter news, flutter developers news, flutter developer news, flutter latest, flutter updates, flutter developer updates, flutter, type: Conference Talk (Full production);, pr_pr: Flutter, purpose: Educate
Id: nq43mP7hjAE
Channel Id: undefined
Length: 25min 19sec (1519 seconds)
Published: Thu Jul 09 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.