Video details

Katya Pavlenko - Debugging Angular with Flame charts | AngularUP 2021


Debugging Angular with Flame charts "What do you know about how Angular works? You read articles explaining what it does under the hood, how change detection works, what zonejs is needed for and trust those articles. But what if you want to check it yourself to debug next nasty bug which is probably related to framework code? First idea is to put breakpoints and try to follow them in Sources tab Chrome
But there is a better way that not everyone knows about – use performance tab and record your interaction to flame chart, which would show you how exactly framework is working, and you'd be able to see where button click is born and what journey it does to update app state.
Talk not only useful for angular developers, but for any frontend developer.
Focus can be shifted to performance or zonejs." Katya Pavlenko -
Freelance consultant


React app at home. Well know what it says. Few words about me. In fact, three facts. The professional fact that I'm quoting since eleven. It sounds. But actually I'm doing front and for money for the last eight years and last seven of them. Doing it with angular since angular one. And now there is Angular 13 released few days ago. Kind of a journey. The geographical fact. I was born and lived in St. Petersburg, Russia and moved to Israel three years ago. Living happily since then. Here. This is my first time performing in Israel. This is my first time performing in English. A bit nervous. Thank you. And the fun fact. I like cosplaying mushrooms. And this is me on this poorium it's my poor room costume. Did it myself. Developed this pouring passion when I moved to Israel. Have another two photos. Can show you afterwards. So enough about me. Let's talk about Chrome flame charts. Who used it? No. One. Two people. Yeah. Wonderful. So next, slides are not for you. This flame charts is just a part of Chrome DevTools. It's hidden in the performance tab and if you go there and click on it you will see something like that and it says like la, press recording, do something, then observe the result. And if you do this you may see something like that which looks intimidating and scary. And in fact it's not as bad. In fact, this is JavaScript call stack. This is all JavaScript that was running during your doing recording. To break it down, let's go over a simple example. Let's imagine that we have this is my whole app and it has only one button and this button has eleven listener which starts method working day. Method working day has methods before work. We don't care what's inside because we just only care about the order and the names of the methods. And then there is after work, in the middle there is work and then we are recursively. Calling work one more hour for eight times should look familiar for most of you. So if we actually do a recording, we start recording, click on this button and end recording. What would appear in the flame chart? It would look like that still can't understand much, so let's break it to little parts. This thing in the middle is JavaScript call stack because we didn't invoke a lot of JavaScript. It's pretty lonely here. This is JavaScript methods thing. On the top is a timeline with the trends. You see trends, they just repeat what goes on in the call stack. It also has information about total time of recording. I warned you, you can see this but it says 1 second, 300 milliseconds. And in the bottom part it's just a summary and details giving you more information about what you see. This is a tool developer performance and has a lot of things dedicated to time and other things we're not going to talk about performance. Today we're going to talk about another usage of this tool. So let's Zoom in into what is interesting to JavaScript call stack. If we do this, we would see something much more structured and less scary. So let's remove everything we don't want to pay attention on and talk about what we see here and compare it to the code we had. So what we see first we see the click. It says event click. Fair enough. There was a click, then it says that it says working day method was called fair enough. It was called because we had an event listener under it. There is before work, correct, after work, correct in the middle work, also correct. I should stop saying the same word few times in a row. But then we see one method and seven times more going downstairs. In fact, what we see here, we see a call stack of our app, what was called, in which order, what invoked what, and that's in fact a flame chart. So this is a thing that visualizing your call stack during the recording that you made. It shows which functions were called, what triggered them, how long did they run, what other functions they called, and much more. We don't have time to cover it all. And as Image says, this is fun. But the first thing you're going to ask me, it's a performance tab, isn't it only for performance? And this is super legit question. And this is one of the reasons I'm doing this talk, because there is actually performance tab is for performance. And you can be a developer for a long time. You can work successfully but never actually face a performance problem in your app. So you never go there and you never use it and you never learn how it can be beneficial in other cases. So for me, it also can be used as a great tool for debugging and visualizing of your solution. So let's debug and visualize something. I was thinking for a long time, what can be used as an example? So it would be Angular related, it would be actual debugging of something. It would be familiar to lots of people here. And it would be fun to use flamecharts for it. And I came with my favorite error, which is expression change after it has been checked, please, who faced it? Wonderful. The target is correct. So this error is so common that it has its own fan page on Angular documentation. And it has a wonderful video explaining why it happens, how we fix it. We have millions of articles in the internet explaining why it happened, how to fix it, and for those who don't remember, let's recall it quickly. First, what we know from these articles is that it's caused by some additional check in Dev mode. Then we know that the most common things that cause it is changing template bindings inside of Ng after the unit, or using random values in template bindings and how to fix it. We move code to Ng on Anit we call detect changes one more time or we are using set timeout to change what you need or we just don't use random values. This is forbidden. This is nice. And I was fixing this problem for a long time. You open an article, you scroll down, you find like set timeout, you put set timeout and it works. Probably done. But have you ever thought like why? And you can actually understand why you can open an article. You can read an article like choose the best one that you like. But this is reading and there is a saying that one picture was a thousand words. So we're here today to look at this picture and try to understand what is going on by ourselves. Short live coding. Yay. So there is an app I wrote. It has only one purpose. It causes problems. So you call click here, there is some stack trace. Our favorite error is traced. You click again, it disappears. Okay, works. So if you go to the code, what will we see here? There is an app component which has a button and it has a problems component which holds all the problems inside. And if we go there, what we see super small template with the getter this, getter what it returns counter the private field. And this counter is incremented in Ngftunit in this method. I also added all the life cycle hooks here just so we will see them in the flame chart because we can only see the methods that we called actually. And this is it pretty straightforward. And if we go to the performance tab and start recording and that's it a few times what we see, not very friendly but we can first of all Zoom in and navigate. And let's look here. This is the click. The last one we have few. Okay. I just know where it's located. So there is some stack trays. So what we can do what we want to achieve, we want to understand what is this. So let's take this method which is the last one, the stack trace and just let's find it here. I can use control F insert. It is located here. I can Zoom in, I can Zoom out. So we know that it is here and this happens under the click. So this is the place where we need to drill down not to struggle with all these Zoom in, Zoom out and have ability to highlight something. I just screenshot it the flame chart and we're going to continue from here. Scary. But if we look at it closer it would stop being scary. First thing, our problem downstairs. So we need to Zoom into this place. The chart is big so I broke it into half. Top half, bottom half. Let's start from the top because we're in this stack trace. So we should go from the top to bottom to understand what's going on top part. What can we see here? Click. Okay then if we look at this method, it's the same method from our template which toggles problems. So what we see event listeners which we put in the app are invoked here. Sounds legit. Okay, what else can we see here? Smaller remark. You see some something is blue, something is green and it means that these methods were located in different JavaScript files. You remember that angular builds all the few bundles. So here it is. It just indicates that it's from different files. So what we see here, something blue with the word zone. We're not going to dive into it, but this is how zone handles the click. Okay. And downstairs sometimes say next demit, next, next run invoke. And this is framework handling the event not going to dive into it now today also. But I can just tell you that this part you can play with it at home is Angular handling click and what is going on in mysterious bottom, we come in closer. Here it is. Okay. So if we look at it closer and try to understand what is gone, we see the detect changes method. Pretty familiar. Means something about change detection cycle I guess. Okay, right next to it, the second column containing the problem check no changes method looks not so familiar but kind of corresponds to this information from the beginning about like check happen in Dev mode. Okay. And the last one small, it says default error logger and we understand that it's just the part that outputs this nice trace tech trace. What else can we investigate here and what can we find? Look again what we see ng on an it ng do check ng after content in it something we can understand ng after viewing it. So we get one clue already from just looking at this chart that ng after view in it is like providing our problems not just somehow we see that it stays apart. One clue there is. Let's look again. This is get problems caused from our template method called once, method called twice. Okay. And in geometry unit is exactly between them. Okay, second clue. Then let's combine everything we have. This is NGF unit. This is the time when we call the getter from the template and counter equals zero. Then ng asteroid starts and it increments the counter. Then we call this getter again. Counter equals one. And then suddenly out of nowhere we get an error saying expression has changed. After it has been checked it was zero and now it's one. Wow. It's like we see it as one picture on the screen and understand everything. We just see with our eyes that whatever happens between these two checks, we don't even care. Like why are the two checks yet? Whatever happens here and makes them return different values causes us problems. And wow, we are almost there and we understood why it causes problems. But it's just a half of the journey we are not to understand. How can we fix it? And let's look again at the picture. Everything is in the picture. So we need to prevent change in value between these two sequential checks. How can we do this? First, go into the random thing that was in the beginning. We just can't use it. We see it here, that if we use it, it doesn't matter. We have NGF review needs. We have anything there, they would return different values. Okay, this is too simple. Second, what we can do, we can move this to NGO and eat and now we understand why we should like why was NGone and need a solution? We can move it there and it would help us. Or we can move it there. It else also would help us because it will solve the problem. How can we do this? Set them out. We will try it in a second. And the last thing, which is not so obvious, but we can just add additional check. Like our problem is two sequential checks giving us different values. So let's do it one more time. After we have the new value, let's try it. So let's go back and let's try the first one with a set time out. The most common one. Oh no. And we don't care about like you heard about it today. I guess we don't need any significant time here. Okay, let's go. Okay, I'm clicking here. By the way, you see nothing thrown. So starting recording. I can few times observing this, zooming into the click. You can look for any method, anything here. I'm just knowing where to Zoom in and what we see. Suddenly we see timer. And by the way, remember I said that about framework handling events. It's completely the same here. So let's look what changed. Zooming in to have and G after viewing it have. But what is here? Blue stuff and set them out. And also this gives us a sneak peek about how zone JS actually works. So it's not just set time output, it's something happened. And this is Ongs. Also interesting thing we learned. So it sets timeout and then set timeout is invoked and it calls update counter. So at this place, counter is incremented and this is change detection. Lifecycle hooks and G to check. Legit check. No conflict work. Cool. So what else was the idea? To add detect changes. Okay, starting recording. Clicking again. No, nothing thrown again. Zooming in to click. There is no set time out now scrolling down ngstrom unit update counter detect changes. Get her called again. Conflict eliminated. So this is how it works. And what can we see? We solve the case by just looking at one image. Okay, we can Zoom in and scroll, but it's in fact it's like one graphical thing and we solved it. Just looking at it. Not reading any articles, not Googling anything. The last question is why did check no changes and how can we remove it and we also can try it by the way right now because we have some time left. So what is it? Who knows why these check no changes appears and how to remove it. Cool. I can amaze you. So there is a main TS that everyone has in their project and there is think enableproduct which enables only production and like some check existing only in production and here is like doing something only in production. This is it. And I'm like I'm not reading anything, I'm not Googling it. I will just prove it to you in action. I'm just copy pasting it and putting it here so it will be called in any case. And by the way, let's return the problem what we see. Okay. No error. Throne, let's do recording. I'm doing it a few times just for fun. So we Zoom in, we scroll down, we see get problems caused, get her like our lifecycle hooks and just reviewing it. There is no check so we removed it and we just see how it works and how it was removed. Wow. This is amazing. When I learned how to do this, I was like I was missing this tool for my whole life. Summary we came to an NDA few things to remember. First someone under and stood the picture. No, this is thank you. This is a dog sitting in the flames and this is flame charts and this is fun. Anyway, what is the outcome of this talk? First, flame charts. Apart from being a tool for performance, they help us to see how any complex solution works and do it in one place so you can see how framework Library your own code from two months ago works in one interface. They are useful for presentations because first of all they like compress lots of information in one place and also they make any presentation look cooler. So next time you're doing something some design session at work try to insert in screenshots from flame charts. It would amaze everyone. And the last thing I want to focus attention on there is a lot more features which we didn't cover today. This is super cool, powerful tool didn't have time to cover at all. So if you have any questions, if you want to play with it at home and I would be happy if at least one person would come tomorrow at work or today and open the laptop and try to record something, investigate what is going on and if you have any questions about it or about how it works or whatever, I would be happy to answer them today or using these contacts and that's it. Thank you very much for listening. You.