 So today, I want to talk about debugging the web. And really, this is about I want to share with you some of the work that we've been doing in the Chrome Developer Tools. We've been working hard on a lot of stuff. And I want to share with you today. And just to step back for a moment, I just want to point out that really our goal here with the Chrome DevTools is that we want to maximize your productivity as a developer. We want to make sure that you are as effective at developing experiences for the web as you want to be. And not just that, I think we all enjoy web development because we get to craft the experience that users consume. And we get to bring them joy. And we want, on the DevTools team, to make sure that you have kind of that joy too. So we want to maximize your delight as a developer. So I'm going to be sharing with you a few things today, some big features that I'm really excited about, also some smaller things that just are smaller, subtle changes, but all targeting your experience and your workflow as a developer. So we're going to go through a few things from debugging and authoring, progressive web apps, and then some auditing stuff. And we've got a lot to get through, so let's get right into it. Debugging. I'm talking about JavaScript debugging. And so JavaScript debugging is how we understand the execution flow of our code. And it's how we remove all the bugs that we added to our code by accident. So it's a really important thing. And we spent a lot of time doing it. So we want to make sure that it's good. Let's start out small. This is the call stack. The humble call stack. This is what it looked like about six months ago. And we spent so much time here that we want to make sure that it's as good as possible. So we've done a little bit of UI refresh here. On the right-hand side is new call stack. Some small changes, just a little bit more clean, not as much zebra striping. The asynchronous hops are a little bit more obvious. The where execution sits is very clear. And up at the top, of course, you'll see exactly why you're paused. And this is called out very clearly, because sometimes you're not really sure. Also, sometimes you just pause on a breakpoint. It's kind of clear. But other times you're paused on an exception. So it tells you exactly what the exception message is right up there at the top, so you don't have to go and figure out and open up the console. Or you're in a promise rejection. You're on an XHR breakpoint, a DOM breakpoint. Whatever the reason, we want to make sure it's very clear to you on why you're sitting there paused on execution. So some changes there. But also on the call stack are some other things. Now here I have the DevTools fairly. Let me bring that back. Yep, uh-huh, uh-huh, uh-huh. It's good. It's great. The DevTools, in this case, are pretty big. It's not all the time that we have the DevTools maximized on the screen. And sometimes it's all over there squished to the window, but we still want to be effective. So this is what the call stack looked like a while ago. As you kind of reduce the size of the call stack, everything gets shrinked down. My function names, like I can't even read them anymore. So navigating between the call frames when I'm debugging is kind of rough. We decided we could make this a little bit better. So this is the experience now. So just as you have less screen real estate, we go in. We kind of stack the function name and the location. And when we run out of space, we just elide the location and take the text away from that. So making sure that whatever the screen orientation and we're always changing it, it's going to be readable and usable for you. So again, these are small changes, but important. Now a lot of us are authoring not just in kind of plain old JavaScript, but we're using JavaScript next ES6, ES2016, whatever. And we might be using tools like Babel or TypeScript to transpile them down to code that can be deployed across a variety of runtimes. And I just want to point out that the DevTools works great with all these new language features. In fact, we use them ourselves. This is the DevTools inspecting the DevTools. I'm using the black DevTools to view the other one. And this is just some of our code in some of our layer profiler. We use a lot of these new language features ourselves in our JavaScript. In here is a bunch of stuff. There's promises and error functions, template literals, the new array methods, good stuff. And this allows us to make sure that the experience of working with these new language features, whether it's debugging or in the console, is great for everyone who uses them. So the console itself is actually a really nice thing. If you're using Babel or something to transpile, if you're like, what exactly is happening here? Just come on over to the console and try it out in place here. Works great with all the new features and constant let. Here in the screenshot, we can see using the async await. This stuff is great. You can toss in a little debugger statement right there and understand exactly how it's moving. This is a lot of fun. So while we're talking about the console, let's spend a little bit more time here and talk about the console read line. Now, the console read line is, how did I do this? Yeah, I don't know. OK. Coming on over here. So opening up DevTools on my favorite site, example.com. It's a good one. The console read line is this thing here that we type on. And so usually, we type things that are just one liners. But not all the time. Sometimes you actually want a few more than just one line that you want to type out. And this has been kind of a pain before. You have to hold Shift Enter to avoid. To write in new lines, it's been kind of tough. So I'm going to write out just top of a function. And as I hit Enter now, we just immediately say, oh, actually, I don't think you're done here. Now, some folks call this smart return. In fact, Safari kind of paved the way on this one. They have this feature. And we really like it. It's fantastic. So now let me just finish the rest of this guy. I'm just going to log out my args. I hit Enter again. We still know that we're not done yet. I had a brace. And it's like, oh, yeah, I'll re-indent that for you back there. And I'll hit Enter again. And it's like, yeah, you're done. We'll execute that. Cool. So yeah. So as I had that too, you'll see that we are matching the braces, too. So very clear brace matching. And in fact, this is now syntax highlighted, whereas that is pretty new. Even things like multiple cursors and select next match, all these features that you and these keyboard shortcuts that you use in sublime text or whatever, they also work here, too. So some nice upgrades to the console read line. Now, the other thing is that we use the console as a way to inspect objects and kind of understand what's going on with them. So actually having the completions as we type and explore things is really important. So on this site, let's see, document.head. And I'm just going to look at child nodes real quick. So as I open up the square bracket, I do actually see immediately all the indices that I can use in child nodes. So I know that there is 11 child nodes, and that's kind of cool. I'm going to choose one. And one pain point that's happened in the console before is that any time that you have an array and you grab something from the array, and then you hit dot, and you're like, I might not see any, I can't, what is there? And I want those completions. And it didn't work. Anyways, it works now. So we're all happy. So in addition to that, you kind of want a little bit more power, and you've only been able to see what starts with what you typed. And so now if I want to see what the content is of this child node, I might type content, and then, oh, text content. Yeah, actually, that's the text content. So substring completions work now, too. In fact, the substring completions work not just here, but also in elements panel. So in case you forget something like border color, you can type color, and you'll eventually see where it is. All right, so some nice improvements there on the console. Again, small things, but nice. All right, sometimes you're writing some code, and to be honest, three lines of code isn't cutting it. You want a little bit more room, and you could go over to something like JS bin, and that's great for sharing, but sometimes you just want to play around. The snippets inside of sources, it's just kind of a place where you can noodle around, try out a few lines of code, put breakpoints, try things out, execute it. These are persisted into your Chrome profile. In this case, I was just playing with the battery API, seeing how much battery I was discharging and how much time was left. It was cool stuff. Just save it. There's a few things, like little debug helpers that I keep around, and if you Google DevTool snippets, you'll actually find a bunch of great debug helpers and performance monitors that people have written. Just take them, save them, throw them into your snippets, it's good stuff. All right, now, one more thing to kind of finish up debugging. Yeah, so this line of code that we're looking at here, asynchronous code, I got promises and some thens. This is actually a really tough thing to debug currently. In fact, if I place this breakpoint here on line 16, I pause before any of this, but there's really no way for me to pause inside of my error functions and see what's happening inside of them, and if I try and pause here because this has changed, it just doesn't work, that's not great. We wanna make sure that debugging asynchronous code is as easy as debugging synchronous code. So we've been working on this and thinking that there must be kind of a better way. So let's see, I'm gonna open up a snippet that I have here, and yeah, yeah, okay, this is good. So we've been thinking about this and working, let me bring that back, yeah, there we go. Working with the V8 team to see if we can improve this experience. So what I have here is some code and we are going to ask the GitHub API for some data. We're gonna fetch it and then turn it into JSON and then get some stuff and hopefully log it out. And let me just try this real quick. Okay, well, it looks like there's a problem. Okay, yep, great, problems are good. Now before, it's been pretty hard to understand what's going on because again, I could only pause in the very first line of this. But so now what I wanna do is I'm gonna place a breakpoint here. In addition to that, we've also found all the candidates along that line of code where you can place inline breakpoints. All right, yeah, nice. So now that we have that, let's see. I'm gonna run this again. So what just happened is I ran it again. Right now we're paused right here at this first guy, but I'll let that continue. All right, now, cool. We're paused halfway down the line, right after JSON. Now I do see that this response up here is there. Forbidden, that's gonna be fun to figure out. And I even see the return value, this promise. This is actually the return value of this call right here. Now I think I can go for, yeah, okay, yeah, go for it again. And well, to be honest, it looks like data here is coming back. So the problem with this demo is that I'm hitting the GitHub API and turns out that for whatever reason, RIP in this building has already exceeded its rate limit. We're like, kind of breaks the demo. So thanks for the people that are using the GitHub API on Authenticator right now. Luckily, I have a backup piece of JSON. This is what the payload was. That's just sitting there. So let me just, you know, just run, run, run, run, run, run. D, d, d, d. Ah, ah, ah, ah. Okay. How are we looking? Let's clear off these guys. Ah, ah, ah, ah, ah, ah. Uno momento. Okay, okay, great. So run that again. I do have a problem, and we can inspect exactly what is going on. I kind of think I know. We go forward. It was asking for data avatar, it doesn't exist, avatar URL. Yeah, that makes sense. Let me finish this off so that we don't have to worry about it anymore. And one moment. All right, here we go. Avatar URL. Enter. Really? What did I do? Oh, guys. I really, there we go. Yeah, so yeah, console image. A little known thing just tosses an image into your console. Why not? OK, to be honest, the implementation is down here, and it's cool. But yeah, all right. Anyways, in line break points, I'm really excited about this, really introducing a much better development experience for asynchronous code and all sorts of code. It doesn't really break anywhere you need to. All right, moving on to authoring. And we're going to start with the front end, and I'm going to head back into the browser. Over here, we have a PWA that me and Sam Sikoni have worked on. It's called CalTrain Schedule. As you can imagine, it shows the schedule for the CalTrain. And now, we've been developing this, and it's always times when you want to make changes. Now, a typical way of making changes, like we can try out some new colors. And if we like them, usually the method is shift selection and copy paste over in your editor. Now, we don't really like this workflow, and we think it can be better. In previous talks, you might have heard us talk about features like workspaces. And workspaces allows you to bind your local development folder with the actual site that you're looking at in the browser, allowing you to save to disk the things that you're working on. And this is some powerful stuff. But to be honest, there's been some configuration about it, getting it set up. If you've tried it, it's kind of like, is it working? I don't know. So we wanted to make sure it's really straightforward and simple. So I'm going to come back over to sources and clear this out of the way. So in sources, we see, OK, yeah, this is the code. I have a service worker here and some JavaScript and CSS. Great. But I want to be able to persist the disk. So the new experience now is a lot easier. So I'm going to take actually just my development folder. This is my Caltrain schedule folder locally. So I'm going to drag and drop it here and say, yeah, you can access that. And then immediately, you see a little green checkmarks light up. And it says, oh, yeah, the CSS of the file? Yeah, I know where that is. That's right on disk. And over here, I'm going to show you the file system. Here's the entire folder, like my editor config and things, my service worker. But everything that is coming in from the network has a little check mark to it. So this is a nice thing because we automatically find out for you how things map. In fact, it's not just the basics, but if you have a more complex setup, like you're transpiling your JavaScript or you're compiling SAS to CSS, that should work too without configuration. So I could explain how we made it. To be honest, I don't. It's like magic. So things like this TypeScript, we were able to map it back and forth. As long as you have a source map for the actual compiled code, we will figure out where it goes and map it so that any changes you make persist. So let's make a changer. So this title could afford to be bigger. That's nice. It's a little too strong. I'm going to change the foreground color a little bit, dial it back, get in the gray. That's good. Need some shadow. I'm going to use the new shadow editor. Little too black, but if we lay it up, ooh. That is some classy stuff. Yeah. I'm liking that. Now, one thing that you might see right here, this green check, it knows that this CSS is actually the one on disk. And if I click through to view it back in sources, we have the diff saying, oh, yeah, I know. You actually change these lines right here. And if I come back over to see my editor, or my terminal, and I just check my diff, well, yeah, that's the diff of the changes that I made. So automatically, this is the diff. Cool. So that CSS is looking good. But I'm actually talking about CSS. So the original styles of this site, Sam actually, was pretty responsible for it. But I don't even know if we were like, there's like a lot of styles here. And I don't even know if we're using all of them. I imagine that we've all been in the situation. You're shipping an app, and you're just like, are we even using these ones? I'm not going to try and remove them, because that's crazy. But I would like to know. This is hard. The browser kind of knows, right? We're like, maybe we should. So actually, as of today in a canary near you, you might find this little checkbox up here called CSS coverage. Now I'm going to try it out and just hit record. And in fact, that's it. It's kind of done. I'm going to head back to sources. And now in the CSS, we mark on the left-hand side if these styles were never used. Yeah, so actually, this is pretty good. Down here at the bottom looks like there's all this animation stuff that wasn't used. And I just want to verify that this is good. The animation is like, actually, these little bars that animate out. Looks like there's just two here. I wonder if I can, yeah, I'll try and trigger all of them. Let's just switch this over there. Yeah, that's a few animations. And come back, and yeah, OK. So we are using all those. Not that, but yeah, CSS is looking pretty good. So excited about this, because it gives us much better tools to understand what of the code that we're shipping are we actually using. Yeah, some good stuff. OK, OK, coming back. Now, talked about authoring in the browser. A lot of us are full-sac developers. We write JavaScript for the back end, too. And at Google I.O., we showed some work that we've been doing to bring profiling and inspection and debugging to Node.js. We've been excited about this, but there's always more work to do. So let's show a little bit of that. So coming back to this Caltrain schedule, I've actually been working on a small little feature to get the live position of every single train. There's an API for it, and I could get the live location. So you can see down here at the bottom of my JavaScript is I'm asking my local server for the position of a train, and I'm just polling for it. I've just started the feature. I'm very early on this one. So let's kick off the Node, right? So we'll come over here, this guy. And what we can do is we can hit Node dash dash inspect in the app, and whew, ignore that for a moment. We get this URL right here. And this is URL, and we can just actually copy-paste it into our browser and start debugging. But in this case, it's kind of awkward, because I already have a tab open with dev tools debugging the front end. It'd be nice to be able to look at the back end, too. So I'm actually, yeah, just going to allow this to run, but I'm going to come back over to the sources panel. And now when I open this up, and it is just the main thread and the service worker down here is Node. And it's like, oh, yeah, you're running Node, aren't you? Do you want to debug that, too? Yeah, yeah, actually, I'd be done with that. OK, good. So now we're connected to Node, and I know this, because if I switch over here, and I'm looking at just the Node context, that error that I was getting over here is still also exploding my screen over here. So that's great. OK, train is not defined, apparently. So let's see what's up. All right, so coming down, there's my app.js. This is my Node code. And apparently there's an error. Let's just pause on exceptions. It just paused right here. Train is undefined, right, yes, good. And train ID, yes, mistake, by bad. Train ID is just train. Now I'm just going to hit Control-S, and I think that takes care of it. And we'll know if we see sending API request. It's paused. Who said that? They get like two extra points in the quiz. OK, paused. All right, yeah, good sending API. Yes, OK. And in fact, coming back to my other context, my page, I went from a bunch of, yeah, 500s internal service errors to 200s, and that's what you like to see. Oh, good, OK. So we're really excited about this, because this allows us, yeah, sure, yeah, it got a clap on the 200s. We're excited about this, because this allows us to use a single DevTools and speak to both the front end and the back end at the same time, keeping your attention in one place while managing multiple contexts. It's just good. All right, moving on. I've heard a bit about progressive web apps today. And there's some nice tools in the DevTools to tackle that. And briefly, just review some of them. Over in the application panel, there's some great stuff. First up, the manifest view will tell you what's in your manifest. And in fact, if the browser finds anything that's not so sure and it issues a warning or an error, you'll see them shouted out right up here at the top. Then the service worker pane tells you everything. The state allows you to manipulate your service workers. And then I really like this. The clear storage pane allows you to not only unregister your service worker with one click, but take care of your cache storage, your app cache, your any of your local storage. Just wipe it out and kind of start fresh. I use that all the time. I do want to spend a little bit more time on the service worker panel itself. And there's two things that I want to point out for you. Really helpful tips when you're doing this debugging. Up at the top are some checkboxes. The checkbox in the middle, update on reload. This is a super helpful guy. You can think of it kind of as like a disabled cache, but for the service worker JavaScript itself, it's great for when you're working on sw.js, the service worker.js, and you're just making changes to it. And you want to make sure that you load in the new version every time. It'll just make sure that as you reload, it pulls in the new version. You don't have to worry about some of the caching stuff. The other checkbox, bypass for a network, basically says, hey, service worker, you love to intercept requests and serve from the cache and all this stuff. But I'm working on my site right now and I'm updating my styles and my pages JavaScript. And so I really don't want you to be serving things from the cache and intercepting. So just chill with the network stuff. So this allows you to just iterate on your pages content, your styles, and JavaScript without the service worker getting in the way. So definitely check those out. And as you keep on, as you work with these tools and find things that are like, mm, making your question stuff, feel free to just holler at us and ask us if there's a better way that the tools can represent what's going on because we'd love to make sure we can help. Now, there's a lot of things in doing progressive web apps that you kind of have to keep track of. And especially if it's your first time just getting your manifest and your service worker set up the right way is a little tricky. And so we've thought of been working on better ways for us to understand if we're hitting all the right marks. And if there's anything else that we can do to make sure that what we're building is great. A lot of that work and that investment has gone into a project called Lighthouse. And Lighthouse is a guidebook for helping you turn a web app into a great progressive web app. And more than that, it analyzes any web page and any website and not only collects performance metrics but helps identify all sorts of developer best practices that you could be doing and making things better. So like, as an example, it audits for a number of different things as far as can the user be prompted to add it to home screen? Does it have a custom splash screen? But other things like, are you using passive event listeners when you should? Are you avoiding mutation events and document right? And over 40 different audits checking for just developer excellence. On the other side, it also does a great job of having performance metrics that capture kind of the user perceived performance in the most accurate way possible. So you've heard a little bit about first meaningful paint and time to interactive and Lighthouse measures those and helps illuminate what is actually happening when things are slow. So Lighthouse is available as a Chrome extension. You can see a little bit over here. See over here, yeah, I can run it from the command line. It'll just kick off a new version of Chrome itself and just run all of its tests, the same tests there. And this works well. Lighthouse is just a node module. And in fact, a number of other tools are already using Lighthouse and building on top of it. So feel free to check it out like that. It works well with a headless Chrome in a continuous integration environment. So if you want to set up regression tests for performance or audits, you can definitely do that. And the other thing is that we've really been happy with how doing these checks to see like this along the right path. This has been working out for us. But we want to make sure that it's even more available. So I want to show you another new thing. I'm going to come over to our Caltrain schedule and I'm here in the DevTools. And we're like, maybe we should have it available not just here as a Chrome extension, but what if we just open this up and more tools and we have a new Audits 2.0. So this Audits 2.0 is powered by Lighthouse. So as I, I'll just make this, yep, there we go. So I'm just going to go ahead and this is using the same Lighthouse that is in the extension, the command line, running all the same checks. So it's looking for things like usage of document write, usage of blocking style sheets and helping you understand what's going on. So pretty soon it'll give me a report. I'll be able to browse that. And yeah, okay, looks pretty good. Fast, site is fast. Good job, Sam, okay. But scrolling down, this was, this is interesting. Check this out. Site opens external links using realm.nope. And in fact, there's, we have two links on the site which are external, open in new window and not using this guy. You'll have to read about this. And this, like, I saw this and I was like, honestly, we really need to do this. So this is super. Yeah, so I'm going to fix that like right after I get off stage. But yeah, I encourage you to check this out. And the nice thing here is that because this is using Lighthouse, Lighthouse is just sitting on GitHub. It's a bunch of JavaScript. So if there's anything that you're interested in auditing for or just want to check, just please come by, drop by. We've had a bunch of people collaborating on the project so far. So come check it out, talk to us. If you have any ideas, we just love to work on it with you. So what do we see here today? A few things. We walked through looking at stronger debugging with modern JavaScript and I got to show the inline breakpoints. Ooh, love it. The parallel of debugging with Node.js and the browser at the same time, a single window. The persistence saving to disk really painlessly, automagical mapping between everything. The CSS coverage defined what CSS you are not using in new auditing functionality available in all the right places. If you're not, follow us on Twitter, our docs are there. And just, yeah, please grab Canary, turn on some of the DevTools experiments if you want. And if anything, bugs certainly, but even just feedback or ideas, go to CRbug. It'll be like, do you want to report a bug? Don't file feature requests, but just ignore that. And just like, file a feature request or just like, hey guys, what about, you know, what do you think? That's fine, we'd love to hear from you. That's it from me, thank you very much. Thank you.