What do you want to learn? Leverged jhuang@tampa.cgsinc.com Skip to main content Pluralsight uses cookies.Learn more about your privacy Using The Chrome Developer Tools by John Sonmez An exploration of every one of the 8 panels that exist in the Chrome Developer Tools toolbar. Start CourseBookmarkAdd to Channel Table of contents Description Transcript Exercise files Discussion Learning Check Recommended Overview and Console Introduction Hi, this is John Sonmez from Pluralsight, and welcome to this course on Chrome dev tools. Most web developers and Chrome users are at least somewhat familiar with Chrome's developer tools. But not many developers take the time to really learn how to use the tools. This course is aimed at giving you a comprehensive look at all of the major features of the Chrome dev tools and showing you step by step how to use each tool. By the end of this course, you should feel pretty comfortable using the Chrome dev tools and have a good idea of what exactly each of those tabs on the Chrome dev tools toolbar does and how to use them. Who This Course Is For You don't have to be a web or JavaScript ninja to benefit from this course or to understand the content in it. I'll be keeping the examples we'll be using pretty simple so that we can focus on what the Chrome dev tools do instead of relying on the deep knowledge of JavaScript or web development, but we will be diving pretty deep into the functionality of the Chrome dev tools, leaving very few stones unturned, so even if you are an experienced web developer or JavaScript guru, you'll find this course will give you that in-depth understanding of Chrome's dev tools that can really aid you in your web development activities. All you really need to know to get started with this course is the basics of JavaScript, HTML and CSS. If you aren't at least familiar with those technologies, you probably won't find much benefit from the Chrome dev tools anyway. Course Overview We'll be systematically going through each of the various panels that make up the Chrome dev tools. But before we go over each panel in-depth, we'll start out with the module you're currently watching where we'll be covering the basics of the Chrome dev tools and looking at one of the most powerful features of the developer tools, the console. In module two, we'll take a look at the elements panel and learn how we can use it to inspect and manipulate the DOM or document object model directly on the page. Then in module three, we'll look at the resources and network panels, which will give us access to all kinds of information about what resources are being used, where they're coming from and how long it's taking to get them. Module four will brings us to the sources panel where we'll cover doing some JavaScript debugging in Chrome, and we'll also take a look at the useful audit panel. We'll wrap things up by tackling the most complex of panels, the timeline and profiles panels. We'll see how to use these panels to really performance tune a web application and figure out what is going wrong. We've got a lot to cover, so let's get started. What Are The Chrome Dev Tools? I found that many web developers are only aware of a small amount of the functionality the Chrome dev tools provide, perhaps part of the reason for this is how much they have grown over the last few years. The Chrome dev tools are basically a collection of tools that are integrated into the Chrome browser, which allow you to manipulate, debug and profile web pages with a very responsive feedback cycle. Have you ever wondered exactly how much time it's taking to download that JavaScript file you're using in your application, or if the JavaScript you're writing might be causing memory leaks? Chrome dev tools can answer both of those questions for you once you know how to use them. Have you ever opened up a CSS or HTML file and made a slight change to an element or a property, then reloaded the web page and repeated the process over and over again till you get your layout just right? With the Chrome dev tools, you can avoid all that by changing the page right in the browser and even exporting the changes you made to a file when you're done. The Chrome dev tools are basically a set of tools that offer solutions to many of the most common problems other web developers have faced, some of which are the ones I just described to you. Opening The Dev Tools Now, if you haven't used the Chrome dev tools before, you may be wondering how to get to them. Well, it's pretty easy. If you click on this icon that looks like three bars inside of Chrome, you can go to Tools, and from here, you can either click Developer tools or JavaScript console, and you can see that their shortcuts, Ctrl + Shift + I for developer tools and Ctrl + Shift + J for the JavaScript console. I'll click Developer tools, and you can see that it opens up a window at the bottom of the page that has some tabs that contain each of the tools. We can also undock these tools by clicking on this icon. You can see that it's undocked this and put this in a separate window which can be useful to put this on a separate monitor if you have multiple monitors, and you can redock it by clicking this. Then we can also configure the dev tools with this little gear icon here, if we click that, you can see that there's different configuration that you can set, for example, you can show the toolbar icons if you'd like, and then when you go back in here, you'll see the icons on the toolbar. Most of the time, I open up the dev toolbar by hitting Ctrl + Shift + J or Ctrl + Shift + I when I'm working on a particular web page, I find that that's just an easy way to get directly to the console which I use most often by hitting Ctrl + Shift + J. Panel Overview The Chrome dev tools are divided in functionality by a set of panels that are displayed when the dev tools are opened. The panels can be displayed with icons or just text, but I prefer the exciting icons. You can configure this option in the dev tool settings. We'll be covering each of these panels in more depth as we go through each module, but I want to give you a quick overview first so that you'll have at least some sense of what is available, and since many of the panels interact with each other when you're working with them, you'll probably want to at least know what panels there are. The first panel on the left is the elements panel. This panel allows you to see the HTML for the page and manipulate it directly, as well as to select elements visually on the page. You can also see exactly where CSS styles are being applied from and modify those styles. Next is the resources panel. This panel gives you a view of everything your page is using, including things like local storage and cookies. The network panels shows you what resources were downloaded over the network and gives you information about how long they took and when they downloaded. The sources panel lets you see all of the scripts your page is using, debug them and even modify them on the fly. The timeline panel gives you detailed information about what exactly is happening when your page is being rendered, the profile panel lets you profile your web page and get information about execution time and memory usage. The audits panel lets you run an audit on your web page and gives you some tips to improve the performance or fix possible errors. Finally, the console we'll be covering shortly. It allows you to directly run JavaScript and manipulate your web page through a command line. The Console The console is one of the most powerful tools in the Chrome developer tools. I find myself almost always turning to the console first when something is not working right in one of my web applications. The console is basically an interactive command console where you can directly execute JavaScript expressions and interact with the DOM for the web page you have loaded. It's also a powerful debugging tool that can give you information about what it happening in various scripts on your page or let you look into the values of certain JavaScript objects or DOM elements at different points in the execution of your page. The console's divided into two parts, the console API, which gives you access to console commands like logging and inspecting elements, and the command line API which lets you execute JavaScript, select elements and monitor events. Opening The Console Getting to the console is pretty easy. You can hit Ctrl + Shift + I to open up the developer tools, and then click the console tab, or you can just hit Ctrl + Shift + J to jump directly to the console where you can type your commands. You'll also find that, when you're in other tabs, for example, the element tab, that you can show the console and it'll come up about halfway up the screen so you can still interact with these other tabs and use the console at the same time. This comes in very handy when you're trying to debug something and you need to look at the source code in order to determine what commands you need to type in the console. We can hide the console again just by clicking this hide console. Console Logging One of the most useful features of the console API is the ability to log messages or even hold JavaScript objects to the console window. You can insert console logging commands directly into your JavaScript in order to troubleshoot issues and get insight to what is going on without having to painfully step line by line through JavaScript with the debugger. Have you ever written JavaScript debugging code using the alert command to find out why your JavaScript wasn't working? Me too, but after learning about console logging, you shouldn't have to ever do that again. Project Setup Now, we're going to take a look at how we can actually implement logging and use it in the console. You can see here that I have a very simple web page, just a local version of this web page, I'm not serving anything over the Internet, I'm just hosting it completely locally from the local file system, and all that I have is an HTML page, a simple JavaScript page and a simple CSS file, and then a few elements that are in here. In my JavaScript, I have just one function defined called DoStuff, and you can see that I've created this console.log. And what this will do is it will log to the console whenever this executes. And if we look at the main HTML page, you can see that it's going to have all of these elements on the page, and then it's going to execute this script which will call DoStuff which should end up logging to the console. And we're just going to keep things very, very simple here so that you don't have to know a lot about JavaScript, we're going to try to avoid any JavaScript libraries so we can focus just on the functionality of the Chrome dev tools and not get lost in all the other things that are going on. Using Logging So I've gone ahead and I've opened up this page. You can see that it's a very simple page, just has this title, an image and then some text below. And we're going to go ahead and hit Ctrl + Shift + J to jump straight to the console. Now that we're in the console, you can see that we already have this message hi that's been printed out. And that's because, when we look at our source, if we look at that JavaScript source, when we executed this DoStuff, it showed this console.log hi. We can also do a log, we can say console.warn, which will produce a warning message, let's say we'll do warn hello. You can see that it puts out a message to the console, but it has this little warning icon. In addition, we also have a console.error. If I put down something like stop. Then you can see that we get a red X. We can expand this, and it tells us where this was called from, gives us a bit of a stack trace so that we can determine where the error is. This is very useful to put inside of your application when you're trying to debug things. For example, we could go back to our code. And inside of our JavaScript function, instead of just doing hi, we can do a console.warn, we can say uh oh, and then we can do a console.error and say it broke. Now, if we save this. We go back to our page, we reload our page, you can see we get all of those messages, we get hi, uh oh, it broke, that gives us this stack trace where we can see actually where this occurred, in fact, all of these give us this information about where this occurred. We're going to look more at the sources tab in a later module, but just to give you a quick preview, if we were to click on this, it will take us to exactly where that occurred, and you can see it even shows us right here in some nice colors where each message came from, at least the warnings and the errors, so this is very useful for debugging your JavaScript. If you're used to debugging your JavaScript by adding alerts all throughout it or just setting break points and then trying to step through it, you'll find that putting these log messages in is a lot more helpful and is a lot quicker instead of waiting and stepping through each line, trying to figure out what's going on. You can usually get to the bottom of a problem much quicker just by throwing a bunch of logs in there and seeing what's actually happening. Filtering And once you have some logs in your console window, you may find that it's useful to use these filters at the bottom. It's set to all by default, but if I click on errors, you can see it's only going to show me the ones that are error level. If I click on warnings, it'll only show me warnings. If I click on logs, it'll only show me the log. Then we have this debug, which it's not showing me anything, and that's because I haven't put out anything with console.debug. We can use console.debug just like we use log and say debug message. And then that will actually show up as a debug, doesn't show up as a log. We can also do an info as well, we can do console.info, also works just like the log. And we can say info, and you'll see that that one does show up with logs, it doesn't show up with debug or errors or warnings, but does show up on all, just like everything else shows up with the all. And you'll probably notice when I have got the All clicked that you don't see those old messages. If I reload this page, you'll see them all show up again. The reason why you didn't see those old ones was because in between showing you the debug, I'd actually executed this clear command, and this is another useful command that you'll find in the console to clear that window to get rid of that stuff so you don't see all those old log messages and get confused if that was happening on this current load of the page or the previous load. Using Assert Another really useful thing you can do with the console is you can do an assert. If I do console.assert, it's going to evaluate whatever is in these parentheses. If it's equal to true, nothing will happen, but if it's equal to false, then it will work just like an error. So for example, I could say console.assert 10 is equal to 5 times 2. And when I run this, nothing happens, but if I say that 10 is equal to 5 times 3, you get this assertion failed, it gives us that stack trace just like it does with the error. So this is a very useful thing if you have some hypothesis of why your JavaScript is failing or why something's not working, put some asserts in there and you're only going to get some output if there's a problem, if one of your assertions fails, this is a good way to sanity check and make sure that what you think is happening is actually happening. For example, if you say, "Hey, this JavaScript object should never be null," you can check an assertion at that point to make sure it's not null, and if it is null, then you'll find out pretty quickly. Grouping And Formatting The Chrome dev tools console can do more than just log simple messages. It can also format them and group them together to make them easier to understand. Using the group command, we can group together messages into a collapsible titled group that can even be nested. And using formatters we can format messages just like you can do in most programming languages. You can even apply CSS styles to your formatted messages, if you really want to. Using Grouping I went ahead and modified our simple JavaScript. Didn't add very much complexity to this, it's still very, very simple, but what I've done here is I've made it so that our DoStuff function will actually do a few things, it's going to call some methods, the FirstStep, SecondStep, ThirdStep, then it'll call LoadBanners and SoundTrumpets. But the other thing that I've done is I've set it up to use grouping for the logging. So if you look at the way that this is working now, we have this console.group and we have a group name of Steps. After that, we have our first step, the second step and third step calls, and then this console.groupEnd. What this will do is it'll make it so that everything in between this group and this groupEnd will be considered a part of this group named Steps. This means that anything that we log to the console is going to fall into this group, and you'll see it visibly as part of this group when we look at the console view. The other thing that I've done is, inside FirstStep, I created a nested group. This group is called First Step, and then we have some logs, we have finding ants, building ant farms, feeding ants. Then in SecondStep, we're doing some logging, in ThirdStep, we're doing some logging. For LoadBanners and SoundTrumpets, we're also doing some logging. And you can see that there's another group for this group of finishing part that has the LoadBanners and SoundTrumpets call, and then this groupEnd. The net effect of all of this is that we'll have our log messages grouped together. And this can be really useful when you're debugging a complex JavaScript application, because you can utilize these groups to group some common functionality together, without the grouping, you might just have a lot of messages written to the console you can't really make sense of, where did these things belong, what order did they fire, but by using the grouping, you can really group together the things that go together so you can more easily debug that output. Let's go ahead and take a look at this page now that we have logging in place. I'll go ahead and reload this page, and you can see what it's done is it's grouped this together. We have the Steps group, in fact, I can collapse these groups so that they take up less space, and we could expand, for example, the steps, and we have this first step, our second step and third step. If I expand first step because that was a subgroup, we have the messages that are inside there. Inside this finishing part we have some messages as well. And the other nice thing about this is you can see exactly where these messages are coming from, so if we wanted to say, well, where is the building ant farms message coming from, we could click here, it will show us in the source where that came from. Using Formatting Now let's see how we can use formatting. I'm going to create a global variable called stepNumber, I'm going to set it equal to 1, then after every step, I'm going to increment this number, so we'll just do stepNumber++, and then after the second step, we'll do stepNumber++, then what we'll do is where we put out our step, instead of saying first step, we're going to say Step, and then we're going to do this %i for integer to do formatting, and then we're going to format stepNumber. We'll do the same thing for our log messages, we'll take the same exact code, we'll put this for the second step. And for the third step. The other thing that we'll do is we'll make a string and we'll call it ants, we'll say var thing equals ants. Then we'll change this, instead of saying finding ants, we're going to say finding %s, we'll just put in that thing variable. Building %s farms. We'll put in thing, and then for feeding, we'll put our %s and then thing. Now, let's save this. We'll go ahead and reload up our page. And you can see now if we go to the console view, we get this Step 1, Step 2, Step 3, we still get finding ants, building ants farms, feeding ants, and we're using this formatting to do this. So this is a useful thing that you can do inside of your JavaScript in order to be able to use variables and to be able to format that, just like you can do in many languages like C# or Java when you want to format a string. We can even get fancy if we want to and use a style. So for example, let's say for this finishing part, if I put in a %c, then I can specify what the style should be, let's just make a simple style, we'll say font size equals x-large. This style is going to get applied when this runs. If I save this and then we reload this page, you can see that it says finishing part, but that's in some extra large text. Logging Objects Another neat thing that we can do with the logging is we can actually just log a JavaScript object or a DOM element. For example, if I just do console.log, we know that every HTML page has a document object, so I can just say log document, you can see it auto completes for me as well, which makes it pretty nice to use. If I run this, then you can see that I can expand this out, it shows me the actual HTML inside the document, and I can expand out each one of these elements. But let's suppose that I don't want the HTML, I don't want this default. Well, I can use console.dir, and if I pass in document, what it will do is it will give me the JavaScript notation, so now I'm looking at this as if it were a JavaScript object and I can expand all the properties that exist off of document instead of viewing it as an HTML view. And this is a really important trick to remember so that you don't end up writing console.log and then trying to get particular properties of an object, it's just a lot easier to just go ahead and log that whole object or that whole element, and if you want it in the HTML view, you can just use the console.log, but if you want it to be this JavaScript notation, you can just do console.dir, and that will save you quite a bit of time since you don't have to go hunting for the element that you want to log, you can just log the whole thing and then you can navigate it through the console window. Timing Another common scenario in JavaScript is to try to figure out how long something takes. Fortunately, the console in the Chrome developer tools makes it very easy for you to do that as well. For example, let's say that we wanted to know how long it was taking us to get through our steps. All we have to do is call console.time, and then we specify a label, let's say steps time. When we're done with our timer, we just call console.timeEnd and we specify that label again, we'll say steps time. It will keep track of how long it look to get from here to here, which should be pretty fast because we're not really doing anything major in between these, but it will give us the difference between these two and put this out as one line in our console output. Let's go and look at our page. We'll reload it. You can see we get the steps time, eight milliseconds. This can be really useful for debugging your JavaScript to figure out what's taking a large amount of time. And by having just this one message making it simple like that, it makes it a lot easier than sorting through and trying to figure out where something started and what time it was and where something ended, or writing your own code to do that. Debugger We're not going to go into a full discussion of debugging at this point, but I do want to show you something that you can do using the console API that makes it easier to debug as well. So if you know that you want to start debugging at a particular point in your JavaScript, one thing that's really nice that you can do with the console is you can just tell it to enter the debugger. So for example, let's say we know there's some problem in our second step. Well, we can go in here and we can just say debugger, and then what will happen is, if we run this now, as soon as this page loads, when it hits that spot, it'll instantly bring us to the debugger, just like we had put a break point here, and we can start debugging from here directly. And of course, you can set breakpoints which we'll talk about more when we talk about this sources panel, but this is a handy thing to do when you're on the other side. When you're in here, you could of course find your source and you could set your breakpoint and then break in there, which we'll talk about a little bit more when we get to the sources panel, but it's a little bit trickier to find your scripts in here when you don't know where they are or you are using multiple scripts than it is if you're already doing some editing in whatever editor you're using and you know that you want to do some debugging when you hit a particular point, you can just put it right in there in the code, and then you'll automatically load up the debugger when this JavaScript executes. Command Line API So far all the features we covered are part of the console API. But the other side of the console is the command line API. You can think of the command line API like a JavaScript interpreter that is able to interpret JavaScript code as you type it. The command line API also has built in support for a powerful selection engine that makes it a lot easier to select DOM elements than using the select element by syntax. It works pretty much like the jQuery selectors. Finally, we can use the command line API to monitor events on JavaScript objects. This can be very useful for figuring out exactly what is happening in circumstances where it's difficult to set a breakpoint. Javascript Expressions Using the command line API, we can execute any JavaScript that we want right here inside of the console. This is basically like having a JavaScript interpreter that's going to run live on the page. In fact, that's exactly what's going on in this case. And this is a very useful feature. Let's say that we weren't sure what our step number variable had got set to. We can go in here and we can type step, and you can see it's automatically auto completing because it knows about that global variable called stepNumber. If I hit Tab and I hit Enter, you can see that it gives me the step number of three. Or I could even increase this, I could say stepNumber++. And right now it's set to three because that's what the value was, but now if I call stepNumber again, I can see what it's set to and it's set to four. I can also even call our DoStuff method right in here. And you can see it's still hitting that debugger because we have that debugger statement in there. I'll go ahead and hit resume so we get past it and go back to the console window. And you can see that it ended up going through and logging everything that's in the DoStuff method, and I could basically use any JavaScript expression inside here that I wanted to, I could examine DOM elements, manipulate them, anything that you can do in your JavaScript you can do here and try it out, this is really, really useful for debugging, if you ever get to that point where you're not sure what variables are being set to what values and you want to figure out what's going on, you can use a combination of using the console command line API to evaluate JavaScript and breakpoints to find out exactly what values are being set at particular times in your JavaScript. It's also really useful for just testing things out if you want to try some JavaScript because you want to make sure that it's going to work before you actually put it in your page, you can just try it out here, type whatever you want and verify that it's going to do what you expect live on that page, this is a very fast feedback loop for experimenting. Selectors One of the most useful features in the Chrome dev tools that is often overlooked is the ability to use jQuery-like selectors directly from the command console. There are three main selectors you can use to select DOM elements in the console window. First, you have the single dollar sign selector that will select an element based on the CSS selector. Just add the CSS selection in quote in the parentheses after the dollar sign, and it will select that particular element if one matches. The double dollar sign selector will select the collection of elements that matches the selection criteria, and the dollar x selector lets you select an element using xpath, which is really useful for troubleshooting automated test tools like Selenium where you often have to use xpath to select an element. Using The $ Selector We're going to look at a couple examples of using the single dollar selector. We have our HTML page, and there's a few things we could select. We could select basically anything that you could select with a CSS selector. We have our h1, we'll try selecting that. We have our image, let's give our image an ID just to make this a little bit easier. We'll call this chromeImage. And we could select our h2 if we wanted to, any other elements that are on this page. Let's go back to our page, we'll do a refresh. We'll hit play to get through that debugger part. Let's try doing a selection. I'm going to do dollar. I'm going to put in quotes, let's start with just h1. And you can see that I ended up selecting this h1, and I have the text of the entire element here, The Unofficial Chrome Dev Tools Rocks Home Page. We can also select that image that we'd given the ID to, if I do dollar, then I do in quotes pound, and then chromeImage, you can see that I'm able to get that image. This makes it very easy to select elements that exist in the DOM, and then you could of course call methods on those or any JavaScript on those and manipulate those elements directly from the console. Inspecting We can also utilize a command called inspect, and if we combine this with our selector, then what it will allow us to do is to be able to find the HTML in our page for that particular DOM element. For example, if I say inspect and then I do our selector, let's do our selector dollar chromeImage. What will happen is you can see that it selected this chromeImage, it's brought us to the elements panel which we'll discuss more in the next module, but the key thing is that it selected this image, so we can find this in the source of our page and it's highlighted for us, we could then work from here. And you'll find that the console works along with some of the other panels to allow you to do things, you can put your command in the console like we did here, it'll take you to that element where we have this image, and then we could do some work with this, manipulate this. I find that many times when I'm using the Chrome dev tools, I'll do a lot of work in the console and select elements and do things like that from here, and then go to the other panels as needed or when something in the console takes me there. Monitoring Events The last thing that we're going to look at for console is using event monitors or monitoring events inside of our page. This is something that's a pretty neat feature that is something that's really difficult to do with regular JavaScript debugging. For example, let's say that for this h1 element, we want to know exactly when the mouse events occur on this, when we get a click event, when we get a mouse in and a mouse out and a mouse move so that we can design some JavaScript to work with this element and to just better understand how this interaction is happening. One thing we can do is we can say monitor events, then we can use our selector, we'll do dollar h1, and then we have to specify what type of events that we want to monitor. We're going to monitor mouse events. And I'll show you a list of all the event types in a minute, but let's go ahead and see what happens when we set this up to monitor mouse events. Now, if I move my mouse over, you can see all these mouse events start firing. The first one we see is a mouse over, we can look at this and we can actually expand this and get all the data about that event. Then we see some mouse move events, we have the coordinates of where the mouse was. We have a mouse out when I move my mouse out. If I do a click, you can see we get the click events. Then we can expand any of these and get the data from that event, this is a really useful feature. You can set this up on any DOM element, and you can monitor different event types. And here's a list of the different even types and what they do, you can see we have the mouse, key, touch and control. And by the way, what I'm looking at here is the Chrome developer tools documentation which you can find at developers.google.com/chrome-developer-tools. If you just put in that address, it'll take you to the main page and you can navigate this to find out more information and find out more about the APIs that we've been talking about so far. Up Next Hopefully you now have a good understanding of the basics of the Chrome developer tools and are familiar with using one of the most powerful features of the dev tools, the console panel. I've covered the console first because even if you just learn how to use the console, you are likely to save a large amount of time debugging web pages using its interactive parser. But there are still a lot more goodies to come. Up next, we'll be looking at the elements panel and seeing how it can be used to greatly reduce the roundtrip time from making changes to a page and seeing the results. Thanks for joining me and take care. Elements Panel Introduction Hi, this is John Sonmez, from Pluralsight, and in this module, we'll be going over the elements panel. Most developers that use the Chrome Developer Tools have at least seen the elements panel, but you won't want to skip this module, because we'll be going in-depth, and learning about some tips and tricks that you might not be aware of. Learning the tricks of the elements panel can save you time in getting your design just right, and troubleshooting tricky layout issues. In this module, you'll learn everything you need to know to start using the elements panel like a pro. View, Edit, Reload How do you edit web pages now? If you're like many developers, you might go through this all-too-common cycle of seeing a problem in your web page, in the browser, then opening up the page in your editor, making the changes, and saving them, and finally, reloading the page in the browser to see your changes. It might not seem like a large amount of wasted time or extra work, but it can be expensive to keep doing this cycle over and over again, especially when you're trying to get an element positioned just right, and have to keep on going back and forth between browser and editor. The Solution The element panel provides a solution to the view, edit, reload problem. Using the elements panel, you can avoid having to flip back and forth from editor to browser, and can instead make HTML and CSS changes in the elements panel itself, and those changes will be instantly reflected in the browser. Want to change the text of an element? Add a class, remove a style? The elements panel can do all that and more. I've personally found that once I started using the elements panel instead of switching back and forth between editors, it became a much more pleasant experience to get my page layout just right. Elements Panel Overview You might be wondering, what exactly can the elements panel do? You can use the main panel here, to modify just about any part of the DOM that makes up your loaded page. You can add new attributes to elements, move elements around, delete elements, or even completely change the underlying HTML. The elements panel also has a handy inspector mode, which lets you instantly view the DOM representation of any element on the currently loaded page. In addition to modifying the HTML and DOM directly, You can also view all the styles that affect an element on your page, and see where the styles came from. The styles can also be directly edited, added, or removed, from the styles panel. You can also modify things, like padding and margins, for elements visually, actual JavaScript properties of DOM elements, and even add break points to DOM events. The elements panel looks pretty simple, but it has a large amount of functionality baked into it. Using Inspect Element Probably, the most prominent feature of the elements panel is the inspect element. Using Chrome, we can right-click on any element, for example, this H1 header, and choose inspect element. It'll bring up the elements panel automatically, and the elements panel has quite a bit of information here. You can see that it's selected this H1, it's shown me, in the source, basically, where this H1 is defined, or rather what it looks like in the DOM, currently, and if I hover over this, you can see that it highlights the H1. In fact, if I hover over this image, it highlights that. It also shows me some information; you can see that it's giving me the ID of the image, up on the screen, and it's showing me that it's a 500px by 500px. Same thing with H1; it tells me the height and width of it. Also, we have this navigator at the bottom, which shows me where I am. I'm under HTML, body H1. I can also click on any of these to go back up the tree, or down the tree, and find out information about each one of these elements. They're all collapsible, inside of here, and images even give us a preview; if I hover over this Chrome.png, I can see what the actual preview image looks like. Adding And Editing Suppose you were looking at your web page, and you decide, below this Chrome image, we want to put some text that says: this is the Chrome logo. Normally, you might go to your editor and change the HTML there, to add that new element, then refresh this, in Chrome, to see the result. But, using the elements panel, we can easily just add an element, to see what it would look like, and get everything right before we go back to our editor and make the final changes. I can just inspect element, on this image, which is going to take me right to the image location. If I right-click here, you can see that I can choose edit as HTML, and from here, I can just add a new element. I can just say, P, and then we'll say this the Chrome logo, and we'll end our paragraph. Then, if we click out of here, you can see it's added this right to the DOM, and we can see, it's showing up directly inside of the browser. We can also edit elements directly, inside of here. If you double-click, you'll notice that it brings up the editor, for the text inside this H1. We could change this from unofficial to the Chrome Dev Tools Rocks Home Page. You can see that change is reflected immediately, and if we double-click in something like an image, you'll notice that this ID becomes editable. If I hit tab, it'll let me edit the next attribute. This way, I can change any attributes, I can also add attributes, I can say add attribute, for example, add a class, we could say class equals Chrome image, or whatever class we wanted, and now you can see that that's been added to the DOM. Now obviously, changes that you make here aren't going to automatically be saved back to your source; we don't know where your source is coming from, it could be an ASPX page, it could just be some HTML, like it is in our case, that's sitting on my file system. But regardless of what the source is, you can make your changes in here, to see what it's going to look like. And then, towards the end of this module, I'll show you a way that you can export these changes back out so that you can change the original source, once you're done making all the modifications. Doing things this way makes things a lot faster, because you can just do the modifications right here in the browser; you don't have to go through that cycle of editing, saving, viewing it again. Instead, you just make all your changes here, until you get the page how you want it, and then you can go back and change it one time, in your original source. Moving And Deleting Another useful thing that we can do very easily is to move elements around. Let's say we didn't like where this text was, and we wanted to move this. Well normally, we'd have to edit the HTML, or delete our element and add a new one, and that can be a little bit time consuming when we just want to move something around. Instead, in the elements panel, we can drag, and we can take this paragraph, for example, we could put it above the image. You can see that the node automatically moves. Now we can see that the text is up here. In addition to doing that, if we highlight this line, we can, of course, hit the delete key, and it will delete that node. Pretty simple and basic features, but many developers don't know about these, and these are real time savers, especially when you want to move elements around instead of having to manually edit that HTML. This can come in pretty handy. Inspect Mode I find sometimes, that it's a little bit difficult to find the exact element that I want to click on, inside of Chrome, because there might be some other elements that make it up, there might be a span, this might be inside a DIV, and perhaps if I want the DIV that this H1 is in, inspect element is not going to be exactly the tool that I want to use in order to get there. But, fortunately, the elements panel has another handy tool, which is this little magnifying glass here. If you click on this, it'll put you in inspect mode, and you can see that as I'm moving my mouse around on the page now, it's showing me, and automatically selecting whatever element I happen to be hovering over. You can use this to really figure out exactly what elements are on the page, and get an idea of what their sizes are, but you can also select an element, for example, if we select this, we have cookies, you notice that it shows up directly in the elements panel, and it's highlighted for us. Recently Selected Another handy little trick that I didn't show you in the console module, even though it relates to consoles, is the ability to select a previously selected element, with a console command. If we use dollar zero, what this will do, is it will give us whatever element we had previously inspected. So, in the elements panel, when we had right-clicked and chosen an element, it ended up storing that in the history, in this buffer of elements that we've previously selected. This makes it a little bit easier than having to try and come up with a CSS selector, or the jQuery style selector, if you aren't sure of it, or you just want to do something a little bit quicker than having to type that out. It has a buffer of up to five elements, so we can do from zero, one, two, three, and four, and it's going to give us all those. You can't go past this dollar four, but usually, this is going to be enough of a buffer to be able to do what you want to do. So this is just a quick way to get a previously selected element, for example, let's say that you didn't want to type out the jQuery, but you wanted to get this image, we could just do inspect element, quickly come over to the console, and do dollar zero, and there we have that image. Styles It can be very hard to figure out exactly what CSS is causing an element to be displayed the way it's being displayed on the page, or to behave the way it behaves. Using the styles section of the elements panel, you can not only see exactly what CSS rules are being applied, and where the rules are coming from, but you can also modify those rules, and even add new rules, live, in the browser. Examining Styles You may have noticed already, that on the right side of the elements panel, we have the styles section that shows us the styles that are being applied for the currently selected element. For example, when I have this H1 selected, we have this element style, which is the style that is directly inside this element; we don't have anything specified, so there's nothing showing up here, and then it shows us where each style matches. So for example, we have a style that is the user agent style, or the basic browser default style; you can see that it styles H1 with display block, font size 2EM, a couple of these web kit specific ones, this font weight of bold. Then we have some style that's coming from body, which is coming from this mystyle.css, on line two, you can see that we have this text align center, and if we were to click on this, it would take us to the sources tab, and show us this mystyle.css, so we can see exactly where that CSS is coming from. We'll get more to that later, when we talk about the sources tab. And if I click on the image, you can see the same type of thing; we have the images styles, that you can see that it's getting that text align center, because it's inheriting it from body, on this mystyle.css line two. Let's look at a more complicated example; if we go to the Pluralsight homepage, if I right-click on this element, for example, and say, inspect element, the styles here are a little bit more complicated. We have some styles that are coming from this #panels.column.mobile. You can see exactly where it's coming from, and what styles are being applied, and then you can see that there's this psminified.min, that is applying some styles to a large number of elements. You can see what those styles are. You can see another one, and these lines through mean that whatever the style that was being applied here, is being overridden by some other style above it, that's being applied later. So this is pretty useful for figuring out when a style is being overridden, because many times, you'll apply a style and then wonder, why doesn't this style show up? Well, if you see a line through the style, you know that something else is overriding whatever value you specified. Computed Styles Another useful part of the styles section is this computed style. If you expand this computed style, and you have an element selected, you'll notice that it'll show you exactly all the styles that are applied. It'll basically take everything that's below, in this styles section, and put it all together to show you exactly what styles are being set on an element. This is very useful, because it can tell you exactly what styles are being applied, and you can even see where they're coming from, just by expanding any of these nodes. You can see that these are coming from this user agent style sheet, but if we go to the text align, it's coming from this mystyle.css two. You can really see the use of this when we go to something more complex; if we go to that Pluralsight example again, and we're looking at the computed style on that element, you can see there's quite a bit of information here, which can be really useful to know about when you're trying to troubleshoot why an element is not showing up correctly. In addition, if you notice, anything that has a color, we can click on this color picker, and we can actually change colors, by selecting a color, inside here. We'll talk about this more when we look at editing the styles, but this is a very useful feature as well. If we go back to our page, you can see that there's this show inherited box; if we click this, what's going to happen is it's going to show us all of the styles, even the ones that weren't explicitly set. This would be all the defaults that just exist for that element. This is useful for troubleshooting if you're trying to figure out, well, does this have a padding box for the background origin? Or, what is the box flex? Any of these weird values that you may not have set explicitly, but somehow they're being set on your element, you can see exactly what they are here. Most of the time though, you do want to have this turned off, because that's quite a bit of information. Enabling And Disabling In addition to being able to just look at the styles and see where the styles originate from, we can also enable and disable the styles, right here in the elements panel. If we go over to our styles, and if you look at, for example, this image, you can see that we have, on our body, this text align center. If I uncheck this box, it's disabling the style. Now this is really useful for figuring out what styles are causing what changes to occur on your page. You can just re-enable that style again by checking the box. You'll notice some of the styles, for example, if I click on this H1, we can't disable; these are the ones that are the user agent style sheet, because we're not actually setting these styles, these are just the defaults. And another important thing to note: when we disable the style, for example, this text align center, notice all the elements are shifting. That's because we're not disabling the style specifically for this element. We're disabling this style in general, that's defined in this mystyle.css. You can see, since this is defined for body, it's going to apply to all the elements on the page. Therefore, when we disable it, it's going to disable it for all of those elements as well. Editing And Adding We can also directly edit a style. For example, if we wanted to change our body style, instead of text align center, we could change this to text align right, and now you can see, everything is aligned to the right side, and this affects all the elements that are in body CSS rule. If we look at the CSS now, it's changed the CSS on the sources tab, and a little bit later, I'll show you how you can utilize this change in order to see all the changes that you've made, and make those changes to your original CSS files. But for now, let's take a look at another thing you can do, which is to add a style. For example, let's say that on our H1, we want to change it so that this text is red. Well, we can just do a color, and then choose red. You can see that we have this auto-complete, if you hold down control and hit space, or you start typing a word, it'll bring up this auto-complete; I can hit the right arrow to auto-complete this, and then if I click out of here, you can see that it's changed the text to red. And if you look at the HTML, on this side of the elements panel, you can see that it's added this in-line style for the color red. I'll go ahead and change back that text align to be center, but we'll go ahead and leave the red. Pseudostate Styles Now, suppose we wanted to make it so that when this H1 is hovered-over with the mouse, that the text changed to blue. We can do that using the elements panel, under styles, pretty easily. All we have to do is go to this toggle element state, and here, we can toggle hover, visited, focus, or active. By checking this, it's going to add this little orange dot; this orange dot, if you hover over it, will tell you what the element state is. In this case, it's set to hover. If I set it to active, you can see, it'll say that it's set to hover and active, and what we can do, is we can add a style for hover. So for example, I can do a new style rule by hitting this plus, and then I'm going to say H1, colon, hover. Now, I'm going to add a rule that's going to apply to any H1 element, whenever it's hovered over. I'm going to change the color to blue, and you'll notice that this is crossed out. That's because this element style is overriding this. If we uncheck this, then you see that the text changes to blue; the reason why the text changes to blue is because it's acting as if this is hovered-over already, because I have this checked. If I uncheck this, you'll notice that it's back to black. This is a quick way to check any of these states, instead of having to move your mouse over, and you can see when I do move my mouse over, it does change to blue. Instead of having to do that, you can just check one of these, to set that particular state. This allows you to be able to create styles right here, to test out how they're going to work on active, visited, focus, and hover, and change them around. And this part's a little bit tricky; you'll notice that you have to keep that hover checked, otherwise you're not going to see matched CSS rules, because it doesn't actually match a rule, so you might not be able to find, where is that hover coming from. But when it is checked, and it does match, this does show up, and it shows that it comes from this inspector style sheet. This is a special style sheet that gets created, that's part of the Chrome Dev Tools, that, whenever you make changes like that, or add a style, it doesn't really have a place to go, so it goes to this inspector style sheet, and we'll talk about this a little bit more when we look at the sources tab. Box Model One of the things I hate the most about working with HTML and CSS is getting the paddings and margins just right. I can never remember which is which; I frequently have to stop and draw myself a diagram to figure out what's going on. Fortunately, the elements panel includes a section called metrics, which lets you visually see the margin, border, padding, and size of an element, and then modify them directly. This is another hidden gem of the elements panel that I find immensely useful. Editing The Box Model Before we look at the metrics panel, let's create a border around our image so that we'll be able to check out all of the properties that we can change, in that box layout. If I go to my image, under element style, I'm going to say border style, we're going to set this equal to solid. Now, you can see that we have a border showing up, with the default width. And if I go into this metrics panel now, we have this margin, that's not set, we have a border that is showing up as three, we have our padding, and then we have the size of our image, 500 by 500. Each one of these, you can see, visibly, on the screen, when they're set to a value. For example, let's say I changed the top margin to be 10px. When I hover over this, you can see that orange on the screen that indicates that 10px margin, that's showing up on the top. If you look over on the left-hand side, over here, we have this style applied; it basically just added this in-line style to make the margin top 10px. This is really useful for figuring out exactly where you want your elements to show up, and messing with the margin and the border, and the padding. We could also change the padding; so make the padding be five, and now when we hover over the padding, you can see there's a top padding of five. This makes it really easy to see what each one of these does; if you've been confused before, about the difference between margin and padding, you can clearly see it right there, and you can see where border fits in as well. I could change this border, for example, to five, now you can see that that top border is set to five, and when I hover over it, the border turns to that brown color. I can also even change the image size within here. Let's say I wanted to make this 250 by 250, I'll just change this to 250, and then, the other one is changing to 250 as well. And you'll see that all the changes are reflected on this left-hand side; they're being reflected as in-line styles. So you can make any modifications here, as well, but remember, with these in-line styles, it's going to behave just like an in-line style. Setting something in here doesn't necessarily override something that wouldn't be overridden in an in-line style. If we went and added to our element style, a border property, and we set the border to two px, for example, you'll notice that that border has disappeared, and the reason for that is because we have some conflicting styles. If I uncheck this, that border comes back, it's using the settings that are showing up in this in-line style. But you just have to be careful of things like that, that could cause some confusion. This is not doing any magic, all this is doing is giving you a visual way to see these properties that affect the margin, border, padding, and the size of the element, and then putting them in-line, here, in the DOM. Editing Properties Another section on this right-hand side is this properties section. Inside here, what you're looking at are the JavaScript properties of the particular element that you have selected in the DOM. You're actually looking at what the JavaScript object looks like. It has properties for the various levels. Some properties are going to come from object, because, in JavaScript, everything is coming from this object prototype. The particular element that we're looking at is a node; it's also an element, an HTML element, an HTML image element. And it also has its own specific set of properties. If I were to expand this one, I could actually change any of these properties as well. Let's say we wanted to put alt text, we'll say Chrome logo; now you can see that the alt text has been set to Chrome logo, and this is a pretty useful feature, especially if you're using JavaScript to modify elements, perhaps you're putting some data inside of the element, if you wanted to check that property, or you're adding some properties to your JavaScript objects in the DOM, you could see them here, you could manipulate them. This can aid you in debugging any kind of problems with your code, that might be manipulating these JavaScript objects directly. DOM Breakpoints I'm inside the JavaScript file for our page; I'm going to modify some of this JavaScript in order to show you the next thing you can do in the elements panel. I'm going to go ahead and do document.getelementbyid. I'm not using any jQuery, because I'm trying to keep things simple; we're not importing any libraries. So we're going to do this the old-fashioned way, and we're going to say Chrome image. This is going to get us that Chrome image element, then I'm going to say class name equals small image. So basically, what we're going to be doing is modifying this Chrome image element, and changing the class name attribute to small image. Now this can be a little bit difficult to debug, if you're wondering why is this element's class name changing, or why is some attribute on an element changing. When we talk about the sources tab, you'll see that there's lots of ways to debug JavaScript, but, just setting a break point in your JavaScript isn't going to tell you when something changes, or what caused it to change. The other thing I'm going to do here, is, I'm going to get rid of this debugger so we don't hit this. Now we'll go ahead and reload up our page, and I'm going to show you how you can actually set a break point, in the elements panel, so that it will break whenever a particular attribute of an element changes. Back on our page, I'm going to reload our page. Now, you can see that this is set to small image already, this class name, because we had changed this, but let's say that I want to know what is causing this image element to change. This is a frequent problem, is that, something is modifying an element on your page, and you don't know what it is or where it's coming from. If you right-click on this image, and you say break on, you can check this attributes modifications. You can also break on subtree modifications, or node removal, but let's look at this attribute modifications, because this is one of the most useful ones to break on. Now what's going to happen is, if I go to the console, and I do the do stuff method, you'll notice that we immediately break where this is being changed. And I find this extremely useful, because I'm always having problems where I have a lot of JavaScript that's modifying elements on my page, and I can't figure out what is changing it. In fact, sometimes, I'll look at some web page that I haven't even built myself, but I'm trying to figure out how it works, and I can't figure out what is exactly changing an element, when I do a hover-over, or I click a button, or something like that. And what I can do is, I can go in here, I can set that on the element, I can just right-click on that element, do a break on, set this attributes modification, and then, any time any attribute gets modified, it's going to break me into the debugger, and I can see exactly what is causing it. Event Listeners It can also be a little bit difficult to figure out what event handlers are hooked up to what elements, especially when you use a library like jQuery, and you're adding event handlers dynamically, you're not embedding them in your HTML. But, Chrome Dev Tools allows us to check this. You can see this event listener section; we don't have any event listeners, but I can add one, if I go to our H1, I can right-click and choose add attribute. Here, I can say, on click, and we're just going to say, console.log hi. What's going to happen now is, when we click on this, and I've clicked a few times, go to the console, you can see it's put out hi five times. In fact, it collapses when you put out the same exact text, so that you just have a count, which is a nice feature of the console, by the way. Now, if we go to our elements, and we look at event listeners, if I click back on this H1, you'll see that we have this click, and I can expand this; it shows me what element it's on, where that element's declared. I can expand that further, and I can see some attributes. For example, for the listener body, I can see the function on click, I can see that it has console log hi, in there, I can find out some useful information about that particular event, that's listening to that click, including the type, this happens to be a click event. Searching We happen to have a pretty small web page for our example, but if you have a large, complicated web page, it can be difficult to search that and find what you're looking for. You can use the search functionality, by hitting control-F. That'll bring up this find window, in the bottom. Inside here, you might think this is just a normal find window, and it will operate as one, for example, if I search for unofficial, it highlights it, and shows it on our page, but, in addition, it can understand CSS selectors, and XPath. For example, I could use the CSS selector for our image element, by doing pound Chrome image, and you can see that it's matching the ID of Chrome image, and it highlights this entire element. I can also use XPath, for example, I could do slash slash HTML, if I add another slash for head, it'll take me to the head. From inside there, I could've went body instead, and then H1, and you can navigate directly to that. So this is a very useful search feature that can help you to navigate the elements on the page, and also just to test XPath. I frequently use this to test an XPath expression, on my page, because if I can get it to show up highlighted here, I know that that XPath is correct. Saving Modifications The last thing that we're going to talk about in this module is local modifications. Let's suppose that you've been playing around with your page and you've made some modifications to that page; well, you might want to get those modifications back out, and put them into your original application. After all, the whole point of making the modifications in the Chrome Dev Tools was to save you the round trip of having to go back to your editor, and back and forth, but when you're all done making those changes, and you've got everything working how you want, you might want to get those changes back to your original source. There's two main scenarios for doing this: the first is if you've modified your HTML. For example, let's suppose that we went into here, and instead of unofficial, we change this to say the Chrome Dev Tools Rocks Home Page, and perhaps we made some more modifications in here, like we had done earlier. Well, there's not an easy way to just get the changes. The best thing to do, that I've found, is to just collapse this entire HTML node, right-click, and say copy as HTML. Then, you'll notice that you can just paste that anywhere. So for example, I have a text editor open, and I'm just going to paste this, and it gives me nice, formatted HTML, that I can then use to make any modifications to my original version. Now obviously, if you've generated your HTML from an ASPX page, or some other server-side generation tool, this is not going to be exactly what you need, but it should help you to figure out what changes you might need to make, in your original source that generated this HTML in the first place. The other scenario is when you have modified a style, as long as you haven't modified the element style. What I mean by this is, for example, let's go to our H1, and for our element style, let's say color equals red. You can see that this puts this in-line in the HTML. For this, you would want to just copy this HTML, like I had shown you before. But, if you even add, for example, if we add a new style rule, for H1, and we say color is red, then you'll notice that it creates this inspector style sheet. And then also, if we modify any style sheets, let's change this mystyle to text align right, then what's going to happen is, we can get these changes. For example, this inspector style sheet, if I click on this, it takes me to this page that is created, which is just a style sheet; all my changes that were added, as styles, that weren't specific to a style sheet, will be reflected here. I can just right-click, choose save as, and I can save this as a style sheet. Also, I can go back to my elements tab, and let's take a look at this mystyle. Here, if I click this one, I can save these changes as well. You can see the text align right, has been set. I can just do a save as, and save that to save and update my style sheet. We can also revert changes, but we're going to look at more about that when we look at this on the module, on the sources panel. But just as a real quick overview, if you right-click, and then you choose local modifications, it'll show you what modifications you've made, and you can even revert those modifications, or go back to the original version of the page. Up Next Okay, so now you have no excuse for doing that miserable cycle of viewing your page in the browser, then making changes in the editor, and reloading it again. The elements panel gives you the ability to edit your web pages directly in the browser, so you can get everything right, and then export those changes back to your original page one time instead of 100 times. There's still more goodness to come though, as we'll be looking at the resources and networking panels next, and learning how to figure out exactly what resources our web page is using, and where they're coming from. Thanks for joining me, and take care. Resources And Network Panels Introduction Hi, this is John Sonmez from Pluralsight, and this module we'll will be digging into HTML5 features as we explore the Resources panel and checking out exactly how resources are being loaded in the Network panel. We'll be learning some good techniques for determining exactly what data is being used in your web pages as we check out the Resources panel. And even though we won't be digging into the specifics of HTML5 features like IndexedDB and local storage, we'll see how the Chrome DevTools allows us to see exactly what data is being stored without having to write debugging code to get that data. We'll also learn how to make sense of all the data in the Network panel in order to figure out exactly what data is coming over the network and how long it's taking to get there. Resources Panel Overview The Resources panel is your central location for looking at the data your application is using and storing. From the Resources panel, you can see basic information like what HTML pages, images, scripts and stylesheets are being used by your page, but you can also see information that is not as easily accessible like local databases, local storage, cookies and even the application cache. Don't worry if you don't know what all these things are, we won't be going into detail about them in this course but I'll briefly explain them as we cover them in the Resources panel. Modified JavaScript Files I went ahead and made some modifications to our webpage in order to add some JavaScript to be able to populate some data that we'll be able to use to explore the Resources panel. If you look at this MyJavascript.js file, what I've done is I've created this LoadResourcesData function. Inside here it calls a few functions to create the Web SQL data, create IndexedDB data, local and session storage data and cookie data. The only data that I'm not creating in here is the application cache. We'll look at a different website for that part because it's a little bit difficult to get that working from a webpage that you're loading up from a file, and I wanted these examples to be able to be something that you didn't have to use a web host to serve up that you could just open up directly from your file system. A quick note about the code. We're going to briefly go over some of this code, but we're not going to go into the details of exactly how the Web SQL database works or IndexedDB data or the local and session storage. I'm mainly creating these in this example just so that we can look at this in the Resources panel. But if you want to go back and understand exactly how these things work, you can check out some tutorials on HTML5. Pluralsight has a couple of courses on HTML5 that talk about some of these different technologies. Chrome Version Another thing that you might notice is that I'm using the version of Chrome from the dev channel for Windows. And the reason for this is because I found that the IndexedDB and a couple of the resource's features weren't quite working in the stable release of Chrome. By going to the dev channel, I was able to get a later version of Chrome. Now by the time you're watching this course, you might just be able to use the regular version of Chrome that's out there as a stable release. But just in case, you might want to go ahead and download the dev channel version. And the good thing about this is that it installs this side-by-side so that you can have your regular Chrome, you can still have the dev channel, you can choose which one that you want to launch. And you can find these release channels just by going to chromium.org, or you can just search for Chrome release channels and you should be able to find this pretty easily. Frames Okay, so now let's head and load up our sample page. I'm going to hit Ctrl + Shift + J to open up our Chrome developer tools. And this time I'm going to be clicking on the Resources panel. The first thing that we're going to look at is this frames, and this is pretty basic. This is about what you would expect. Under frames, what you'll see is the different frames, if we had different frames for your webpage, which most modern day web pages don't utilize frames. But if you are using frames, you'll see a different folder for each frame, and there'll be a top-level folder for the domain. In our case, we don't have any frames, we just have the single page so you can see that we just have this MyPage.html. If we look at this, under this folder is the things that make up this HTML page or what is referenced from it. You can see that there is an image, this Chrome.png. We can click on that and see some information about that image, including the URL, the MIME type, size, dimensions. Then we also have the scripts. We can see what scripts are being used. We have this MyJavascript.js. We can look at it here, it's nice and color coded for us with line numbers. We have our stylesheet, we have our MyStyle.css. That doesn't have much in here. And then we have our MyPage.html, the HTML page that is causing all of this to be referenced, we can view the HTML there. Not a whole lot to this, but this is a nice easy way to be able to break apart a webpage. When you look at a more complicated webpage, let's go ahead and go to, for example, Pluralsight.com, you'll notice that with these resources, there's quite a bit more going on and it's nice to be able to break this apart. You can even see that there's fonts that are being downloaded, it shows you the fonts, and we can really figure out exactly what's happening by looking at this and seeing exactly what components, what scripts are we pulling in, what style sheets, what is the main HTML page, what pages are being referenced. I like to use this just to get an overall idea of what my page is loading and what resources it's using before I start digging into more things, especially when I'm looking at a page that I'm trying to duplicate some functionality from, that this is a good tool to dissect that to figure out exactly what's happening. Oftentimes, many developers will go to the elements tab or they'll view and right-click source, and then they'll try to sort through this and figure out what scripts are being used and where are all the images coming from. This is a less efficient way to find things when you can just click on the resources tab, you can click here, you can see the scripts right here, you can see the style sheets, you can see the HTML, anything else that's coming from that page. Web SQL The next thing that we're going to look at is Web SQL. Here you can view the Web SQL databases that are used on your page. Now Web SQL is a standard that was in HTML5 that's discontinued. So you might not see too much Web SQL anymore. It's a little bit unfortunate because Web SQL ended up using a SQLite backend, which was a very simple way to create databases for local storage. But it's pretty much been replaced by IndexedDB, which we'll look at next. Regardless though, you may want to use Web SQL. Some browsers support Web SQL, others don't, so you may need to look at Web SQL data. If you do, the Resources panel is a very easy way to do that. Let's take a look at the JavaScript that's going to add a Web SQL database for us. And this is pretty simple code here, it's not exercising much functionality for the Web SQL database. You can see that just on this open database which is built into Chrome and it's creating a testdb, then it's using this transaction function to create a table called test to insert one row in there that has a value of one for the ID and then the data will be test. If we go ahead and go into our browser and to our console and we run this LoadResourcesData, what it will do is it will load all that data, including the IndexedDB and everything else that I specified in there. But for now we're just going to look at the Web SQL part. Now if I expand this, I have this testdb database. Here I can expand this and I can see this table in there called test, it has an ID and some data. You'll notice that you can't directly modify the data inside here, but what you can do is at this testdb level, you can actually do select statements for example, and it autocompletes. Select star from test, you can see that I'm getting the data. So you can basically do SQLite commands directly from here in order to manipulate that data, to format that data, to figure out what's going on inside here, or you can just view it directly. This is pretty useful for working with the Web SQL data. Another reason why I'm a little bit sad that Web SQL went way because this is a very nice easy-to-use interface, and many developers are already familiar with SQLite. Indexed DB Next we're going to take a look at IndexedDB, and this is the newer standard that is supposed to replace the Web SQL. As it's newer, there's not as much support for this. This is one of the reasons why I had to go to the Chrome dev channel in order to do these demos is because when I was running the code to create some data in the IndexedDB on the regular Chrome channel, I found that it wasn't showing up. There was some problems with the implementation. But those seemed to be fixed in the dev channel. Let's take a look at this code. Unfortunately, creating the IndexedDB is a little bit more complicated. If we look at this CreateIndexedDB data, I've added some console messages as well just to debug this because it is more complicated and you can see, what we have to do is we open this IndexedDB, then we have some on error and on success messages. And what happens is this request onupgradedneeded has to be called in order to modify the structure of the database. So it depends on what version. For example, I've got version seven in here. If it detects a higher version, then it will call this and then you can modify that data. And you can see that, I'm just checking to see if there's an object store called customers. If there is, I'm deleting it before I recreate it, and then I set an index, set what the keyPath is and I add some data to this. And don't worry if you understand exactly what all this is, this a little bit more complicated of a data structure than the Web SQL, but it's basically an object store, just like many other object databases that you might be familiar with, but it's stored locally. Now if we look at this on our webpage inside our Chrome tools, you can see that if I expand this IndexedDB, that it's got a couple of database files here. And the reason why is because this test data that I've created before, there's not really a good way to delete this. You have to go to the file system and delete this. So you do have to be a little bit careful when you create these databases. They tend to stick around. But you can see, this Index Test DB that I created, you can see that I have this object store called customers. It's going to store our customer objects. Inside here you can see what objects are stored. And the value, if you expand this, it'll give you the representation of that JavaScript object. Again, you can't modify it directly in here. This, you can type in the key to start with. This is, if you have a large amount of data, for example if I put in two, it's going to start with two and we're not going to see any results before that. If you put in one, of course it's going to start with one, which it's already starting with. I find this feature not to be that useful since it's not really a filter, it's more of a where do you want to start. Then we can also click on name directly. You can see this index basically is going to give me the data that it maps to. And I can expand these values. Again, I can't edit anything directly in here. The start from key works exactly the same as it did at the higher level. The only other thing you can do is refresh the IndexedDB from here. Not a huge amount of functionality. I'm imagining that Chrome will later add more functionality to this, just like you have that functionality with the Web SQL, but we'll see what happens. Local and Session Storage Now we're going to take a look at local storage. Local storage is actually pretty easy to use. I can explain to you right here in this demo without taking up much time. In fact, if we look at the code, I'm creating a local and session storage data in the same place and all you have to do to set some data for the local storage is just call setItem, you pass in the key, you pass in the value. It's just a simple key value storage. Same thing for session storage. We'll look at that next, but it's the basic same idea, is that you're just going to pass in a key and a value. The only difference is the local storage is permanent, it's going to persist even when the user leaves your webpage. And the session storage is just going to be for that session. This tends to replace cookies in a lot of modern web application. Let's take a look at Chrome support for this. If we go into our webpage, I've added that data for the local storage. When I click on this, it's going to show me the keys and values that I have in here. It also gives me the ability to modify them, which is pretty nice for testing. If you are adding some data to local storage and you're using that in your page, it's really nice to be able to just go right in here, change this value and then see the result without having to modify your JavaScript code or to go into the console and try and do it that way. And you can of course delete data from here as well. And that's really all there is to it. Let's take a look at the session storage and you'll see the same exact thing. You can modify your key or value from here. You can of course edit and delete, and this is just the exact same thing, except you're looking at the session storage on this. This is also very useful for modifying this data instead of having to go into the console or change your JavaScript, you can do it right here inside the browser. Cookies The next thing that we're going to look at is cookies. And before we get into cookies, there is a change that we do have to make in order to be able to see cookies and use cookies with a local webpage. Now when you serve a webpage over the network or even through your own localhost, it's fine, you don't have to do anything because Chrome, by default, handles that. But when you do load it from the file system, you do have to put a flag. I've added to my Google Chrome properties shortcut this --enable file cookies. You do have to enable that. In order to get this to run, you'll have to shut down Chrome and relaunch it. And you may have noticed also that I am actually on the Canary build. I said that you could use the dev channel, which is true. I happen to be using the Canary channel, which is actually the latest Google Chrome. It actually pushes out every night or multiple times, so it's really the bleeding edge. You don't have to use the Canary if you don't want to. That's why I recommend the dev channel because the Canary may break you pretty often. But all this functionality should work in the dev channel as well. Now once you have that, if you look at the JavaScript that I created, it's pretty simple. The CreateCookieData, I'm just saying document.cookie, setting equal to cookiekey equals cookievalue. If you've used cookies before, you're probably somewhat familiar with this. This is the standard way of creating just a very simple cookie. And if you want to look at that, all you have to do is go to cookies under local files. It's got the name, the value, domain, path, expires, size. We've got HTTP information, whether or not it's secure. All of the data about a cookie you can go in here and you can refresh, delete it or clear it all, but you can't modify this. That's the one drawback of this tool, it doesn't give you that ability to modify the cookie. Now there are different Chrome plug-ins that you can use to modify your cookies. I'm guessing that the reason why they didn't put it in the dev tools directly is because there's a lot of trouble that you can cause by modifying cookies, and they didn't want to make it so easy for you to do that kind of thing. But if you're looking to modify cookies, you can find some plug-ins that will allow you to do that. But this is still a handy tool for development and just seeing what cookies are set and seeing what the values of those cookies are. Application Cache The last thing that we're going to look at for the Resources panel is the application cache. And you'll notice that this one I'm not using my own code for, and that's because you can't really get application cache to work with the local file, and I wanted to make sure that the examples for this application could work from a local file. But I went to this Microsoft site, this ie.microsoft.com/testdrive, and from here there's this cookbook demo. Inside here, it has a great example of using application cache. It also has some good IndexedDB data, but let's go ahead and go in here, I'm just going to click start. It has some recipes, you can navigate through here. But what I'm really interested in is seeing this app manifest. And we're not going to go into all the details of how application cache works, but basically it allows you to locally cache some resources for your webpage so that you don't have to have them be requested from the server each time that page loads. You're using this to cache quite a few different files. You can see what is cached, how it's cached, the type, the size of the file, and you can also see some status information like if you're online or not. For example if you went offline, this would turn off and you should still be able to load that pages using the application cache. This is a great tool for troubleshooting because working with this application cache can be a little bit difficult. You have to set up an app manifest that is going to define what things are going to be cached. And if you want to really make sure that it's working, it can be a little bit hard to figure out when you're just reloading a webpage. Instead, you can look in here and you can see oh, all these things are actually being cached, it did get the commands correctly and the size is right. Network Panel Overview The Network panel is a great tool for finding out exactly what resources are being downloaded over the network and seeing what order they're being downloaded and how long it's taking to get there. You can use the Network panel to quickly determine the slow loading parts of your webpage and to get a better idea of which of those resources might be slowing things down. The Network panel also allows for seeing the exact requests and responses that are happening when the resources are loaded and even allows you to see what HTML or JavaScript caused the resources to be loaded in the first place. Reading The Timeline We're going to start with a very basic simple example, that page that we had created this MyPage.html. We're not going to be able to see a lot of the Network panel with this page, but I want to start out simple just so we can get an idea of what we're looking at before we look at a more complex example. What it shows is all of the resources that got loaded for the page, including this MyPage.html, the main page. It tells you how you got that resource using a GET, the status for that resource. For example, if you had an invalid link or an invalid image, it would show a failure here. The type, we have text, html for our main HTML page. You can see that the application JavaScript type or the image png type is used for JavaScript or our image. And then we have this column that shows us the initiator. For our first page, it shows other, and that's because we initiate this by running this from the browser, by loading up this page. But for the other resources, this is a very useful feature which is that you can see exactly where it came from. For example, where did this MyJavascript.js get requested to be loaded? We can look at MyPage HTML on line eight, you can see that we have the script tag that has this source. That's where it came from. You can see the same thing if we look at this MyStyle CSS. It shows us where that one came from, and even the image was at this part of the page. We can also see here the size and whether or not the resource was loaded from the cache. You can see that the three resources are actually loading from the cache, therefore it's not taking them very much time to load. We can look at the latency and the time that it actually took. The first number is the actual total time. The second is the latency. In order to get this MyPage HTML from the local file system, it took two milliseconds, the latency was one millisecond. Probably not a very valid measurement considering we're loading directly from the file system. And we also have this timeline where you can see exactly what's happened. If you look at this timeline, it has some millisecond markers that are showing what's happening over time. Everything fits in here. The first thing that has to be loaded is this MyPage.html. You can see exactly how long it took. And then from there, it loaded up the JavaScript then the CSS and the png about the same time. Even though they came from the cache, it required us to get this page up before these other requests came out. There's also a line here that shows when the DOM context event was fired. And so you can tell when things like page load happens, and you can tell whether or not you're loading the page before everything is loaded up and you can troubleshoot some problems or perhaps you're having intermittent issues where your JavaScript is executing but it's trying to execute on some resource that isn't available yet. Some other useful information is at the bottom. There's a summary, tells you how many requests, how much bytes were transferred, what the time took total, the four milliseconds in this case. Our onload was at nine milliseconds, DOMContent load was at nine milliseconds. Both of these have occurred at the same time, that's why we have a single line showing that. In most cases, that isn't the case. And we can also change this. We could say disable cache in the settings. What will happen now if we load our page is it won't load these up from cache. Now it is still loading them up from disks, so this isn't still a great example. I'll show you a more complicated example in a minute, but now you can see what's actually happening. This is more realistic. You can see that it took two milliseconds to get our main page. From there, there was actually a little bit of latency, which is surprising, but it does take some time to start getting the thing from disk. But it didn't take very long to load that JavaScript up from this, basically no time at all. And then we had some latency on our stylesheet, and then we had our image took the longest amount time of latency. That's probably because it required this page to load up. These two other things were in the head part of the page, therefore this image ended up loading up only after the entire page loaded. This image was the thing that was preventing this DOMContent event from firing. Once that had happened, we quickly, after that, got this load event to fire. More Advanced Timeline Let's look at a more complicated example. I'm going to bring up the Pluralsight page, just that Pluralsight.com. You can see now that there's quite a few more resources that are loading in this Network panel. You can see that they are loading mostly from cache. Let's make sure that we have our disable cache set. We'll reload this page and we'll get some real information about what's going on. Now what you'll find often when using a real big page like this is that you're going to have a little bit too much data for you to comprehend. It's color coded by the different types, but it still becomes a little bit difficult to sort through all this. One thing that you can do is you can go to the bottom and you can filter. You can actually choose multiple filters by holding on Control and clicking. By default, it's showing everything. But if I click on document, for example, there's only one document that's coming back. You can see where in the timeline that this happened. And when you hover over this, you can also see how long it took for even DNS lookup. It was one millisecond, so that's pretty quick. Connecting took 80 milliseconds. So there's some time wasted there. Sending, there wasn't any because we didn't send any data. Waiting, we waited 148 milliseconds before we actually start downloading this page. That seems like there's some time wasted there, and then we have 171 milliseconds for actually downloading the page. So that was relatively quick, but we spent quite a bit of time before we even got the page. This is really good for troubleshooting because you can figure out exactly where is that time being spent? Many times, developers will optimize the page content or the size of the page and not realize that you just have this built in latency, the time to connect and waiting that you might not be able to do as much about. We can also filter by stylesheets. We can see there's three stylesheets. We can see where they loaded up in the timeline. Images, there's quite a few images. And you can see that there's this breakdown here where we have a bunch of images loading about the same time. Then this other set of images starts loading up. And the latency is actually decreasing each time. And then finally we have another set of images and then this final set down at the bottom. In fact these images are loading after this load event fired, which is something to know about as well because when you have certain things that don't need to load up right away, you can try to optimize your page so that this load event is allowed to fire and things can start going before everything is rendered. We can look at scripts, there's quite a few scripts that are showing up. Then we have this XHR. We don't have any XHR requests right now. These are basically Ajax requests that will be made by the page. This page isn't making any. We have some fonts. Web sockets, we're not using web sockets. And then other, there's a few other things that are showing up on this page. Another little handy trick is to hit this button down at the bottom, which will collapse these to use smaller icons. And you can see a lot more data, it's a lot more manageable. We can also sort by these columns. We can see the status, the type. What's really useful is to sort by the size. You can see what's actually taking up the most size, what's your biggest thing that you're downloading. And then the time, what's taking the most time? Well it looks like the main page is taking the most time to load. That's probably because it has to pull in all those other things and it has a lot of content on it. Sorting The Timeline Another useful feature of the timeline is the ability to sort by the timeline itself. If you click on the timeline, you can see that you can sort by a few different things. By default, it's the timeline itself. It's going to show us the sequence of events that occur. If I reset this, you can see that this is going to progress by what order the things happen, when did they happen in time? But I can change this to start time. This gives us pretty close to the same sorting order but it's going to tell us when the thing actually started downloading. You can see that the sort order is based on that. Then we have the response time, which is also very useful. It's sorting now based on how long it took to respond or rather what the response time was once it had started. Then we have the end time, when did the things end? You can see this is at the very end of the request. We have the duration. Now we're going to see how long did the different things take? What is the duration of these? This is going to be pretty much the same as sorting on time, but this is interesting to look at, to see what resources are the most expensive that you're pulling in, especially when you look at how much of it is the latency part and how much of it is the actual downloading part. That can tell you whether or not you need to reduce the size of your resource or if you need to figure out why are you having such a big latency in actually getting the resource in the first place? Then finally, we have latency itself, which is useful for figuring out things like maybe you should use the CDN to get your resources because it's taking a long time just to initially start the download of the resource, and the CDN might make things faster. There's quite a bit of information packed in here. We're not even done yet. But it is very useful information for troubleshooting webpages. I've seen many developers trying to figure out a lot of these things on their own, putting debug statements in JavaScript and it's really just a waste of time when you have a really good tool for doing this right here in the Chrome DevTools. Request Data The last thing I want to show you in this module on the Network panel is the ability to actually look at the request and response. Let's say that we want to know what's happening when this training page downloads. We can click on this here and you can see that we have this area where it tells us exactly what the request was and the response. In our case, we made a request to Pluralsight.com/training, used the GET method, we got this 200 status code. Okay, here's all the headers that we had sent and this cookie information. And then all of the response information as well. We have the response headers that come back, you can see that it's gzipped, so we're compressing that data that's coming back. If I look at the preview, I can see the actual HTML. They came back, same thing is going to show up on the response. We can look at the cookies explicitly here and then we can also look at the timing. This gives us a nice color-coded view of the timing for that particular resource. If I look at something like an image, this gif, you can see that this one actually had a status code of moved permanently. When we look at the preview in response, we can see that there is nothing because it gave us this 301. But I look at a png and you can see that we were able to get this one. We can look at the preview and it'll show us the actual image. The response is not going to have any response because it shows up in that preview, which is an image. And then we can see the timing as well. Up Next By now you should be familiar with how you can use the Resources panel to make it much easier to implement HTML5 features like local databases. We covered a pretty wide range of technologies as we looked at the Resources panel. And even though you may not be familiar with all of those HTML5 features we talked about, if you use them in the future, you'll know exactly where to look to debug them in the Resources panel. We also took a look at the Network panel and learned how to do some basic performance troubleshooting to reduce the cost of loading resources. Up next, we'll be digging into one of the most widely used panels, the Sources panel, which allows us to debug JavaScript. We'll also see how we can use the audit panel to get some useful suggestions for improving a webpage. Thanks for joining and take care. Sources And Network Panels Introduction Hi, this is John Sonmez from Pluralsight, and in this module, we'll be going over the sources and audit panels in the chrome dev tools. With the large amount of JavaScript that is used in web applications today, it's very important to be able to quickly troubleshoot and debug JavaScript issues. In this module, I'll show you how to get the most out of using the sources panel to debug JavaScript, and make it easier for you to get to the bottom of JavaScript problems. We'll also cover the audit panel, which is a handy tool for getting some tips for improving the performance of your web pages, or correcting other issues. By the end of this module, you'll know what all those options in the JavaScript debugger do, and hopefully learn a few new tricks that will save you some time. Sources Panel Overview The Sources Panel is the central location in the Chrome developer tool for debugging JavaScript code. You can easily see all the scripts that exist for your webpage, and edit any of those scripts directly in the browser to save you the round trip of having to edit and reload a JavaScript file. The sources panel also allows you to set JavaScript breakpoints, create watch expressions to keep track of JavaScript object values, and to see important information like the call stack. We can even set up detailed break points that break only on certain conditions, or just when exceptions are thrown. It can be frustrating trying to set breakpoints at just the right time to debug an ajax call, or some dom event, but in the sources panel, you can set breakpoints to explicitly break on those conditions. Let's take a look at some of this functionality. Viewing Sources The first thing that you're likely to want to do with the sources panel is view the sources that are associated with your page. If you click the sources panel, you may have this collapsed by default, if you click on the show navigator, it'll open this up, you can pin this here to make it easier to do some navigation, and you can see where the sources come from. And in our case, everything is coming from the same location on my hard drive, and you can view the different sources. We have a JavaScript file, an html file, and a css file. Now you can view more than just JavaScript in here, but primarily you'll find that the sources panel has features and functionality that's related to JavaScript. One nice feature that we can do, is if we have a JavaScript file, especially if one is in the minified state, where it's all on one line perhaps, we can click this pretty-print, and what it does is it will format the JavaScript nicely to make it easy to read. We can turn that on or off if we want to. The other thing that you'll probably notice here is this content scripts tab. When I click this, inside of this browser, you're not seeing anything, and that's because these content scripts are usually scripts that are running from a Chrome plugin that you have installed. If I go ahead and bring over my main browser, where you can see that I do have quite a few different Chrome extensions installed, and then we bring up the window in here, when we go to the sources and click on content scripts, you can see that there's quite a few different scripts. This is just something to be aware of, and it's useful for figuring out exactly what's running on your pages, because many times we tend to forget that in addition to what is the sources for the page, we have these extensions that are running. This JavaScript is actually running against our page, and this could be slowing down our page, it could be causing different behaviors on the page as well. That's why many times when you're debugging a web page you might want to go to incognito mode, then go to whatever page that you're trying to debug, and you'll see that when we open up the panel inside of incognito mode, under sources, we don't end up loading all those content scripts. So we're just getting the JavaScript and the sources, that are related to that page. Modifying The Scripts We've already seen how to modify CSS inside of the browser to see the results instantly, for example if I just change this so that there's no center, it automatically updates, but we can also do the same thing with JavaScript in the sources panel. For example if I change it so this DoStuff function will start off by making the step number be equal to 10, and then I hit control S to save this JavaScript, when I go to the console and I type, DoStuff, you can see that it start at step 10, because that JavaScript was updated. This is pretty handy when you're working with your JavaScript so you don't have to go back to the source, you can do a debug session, find out what's wrong, try putting in your fix, and see that that fix is working, modify your JavaScript, do whatever you're going to do to get your page working the way that you want it to work, and then take that modified script and put it back to your original. If I right-click on this JavaScript I can go to Local Modifications, here you can see all of the changes that I've made. In this case it shows me that I've changed step number equal to 10, from here I can also revert anything, if I want to, by clicking on the revert button. Now you can see that if we go back to this view, the step number equal 10 is gone. We can also go back to the original, if we look at our local modifications, if I were to expand this MyStyle CSS, I can just say apply original content, it's going to apply whatever that original was, or I can select apply revision content, we can do the same thing with the JavaScript and then we can always revert this back. And remember just like we could do with the CSS files, we can also make modifications to the JavaScript and then right-click and do a save as to save our JavaScript if we want to as well. Basic Debugging Now perhaps the most common thing that you'll do in the sources panel is to set breakpoints and do some debugging in your JavaScript. This is pretty easy to do. All we have to do is click over in this margin. If I click here you can see that it's created a breakpoint, in fact the breakpoint shows up on this other side, shows me exactly where that breakpoint is, what line it is, and what the text of that line is. Now if I were to go ahead and execute this script, it will break on that line. And you can even refresh the page, and it remembers that breakpoint, and breaks on that particular line in the code. From here, we can use these controls on the right-hand side in order to navigate through the code, just like you can do in many IDEs. We can choose to step over, which will just take us to the next line, we can step into a function call, which will take us into that actual function. If I step over, I can step into first step, now I'm inside here and able to step through this code. We can also step out, which will take us back out. Then this last button will disable all breakpoints, and we can use this if we no longer want to hit any breakpoints in the remainder of our code. This is handy when you have multiple breakpoints set up and you figured out the problem, or you just want to bypass the breakpoints and continue. We can hit this resume script execution button, to go ahead and continue, and all of these have hotkeys. You can see that this is F8, this one's F10, F11, shift plus F11, and I recommend that you learn these hotkeys, because it does make things simpler when you're trying to step through some JavaScript and work efficiently. The other thing that you'll notice when you're debugging is that you can hover over one of these JavaScript objects and see what the current value is. For example we can see that the step number is set to one, we can see what this first step is, it tells us exactly what this function is, we can see where it's declared and go directly there, this makes it a little bit easier so we don't have to go to this code and jump around, we can just see what is in there, and we can decide if we want to step in or if we want to step over it. It's also pretty useful to combine this with the console. What I'll often do when I'm debugging JavaScript in Chrome is I'll set a breakpoint, I'll get to some point, and then I'll open up the console, I can choose to open up the console right here, where I can still see my JavaScript, in fact if you make this bigger you can have an easier time working with this, and I can do something like step number and see what the value is, I can modify the values here, I could say step number is equal to 10 and now this value is set to 10. This allows me to have some flexibility when I'm trying to debug my JavaScript to be able to change values, to see what the values are, and to manipulate things at various points in the execution of the script instead of trying to add new JavaScript code and re-run it I can just make those changes right there. Watch Expressions Another really useful feature that's available in most debuggers is this Watch Expression. We can use this watch expression to watch certain objects that we want to keep track of. We could highlight the step number for example, right-click and say add to watch, then it shows up over here. We can also manually add an expression by clicking this plus, and then choosing what we want to use as the watch expression. We could use 'thing'. You can see that it does some auto-completion as well, that makes things a little bit easier for us. And right under the watch expressions, we also have this call stack session. If we were to step into this second step, inside here we can see the call stack that took us there. We can see that what's happened is we started with our DoStuff, we're up at this level, and then if I were to go up one more level, it's an anonymous function that's inside our html. This is pretty useful for figuring out exactly how did you get to this point. Many times when you're debugging JavaScript you might wind up hitting a breakpoint and then wondering exactly how did you get there. You can just follow this call stack up, in fact it tells you exactly where the call stack is, and what line, just like many popular IDEs and debuggers inside those IDEs do. Scope Variables And let's not forget the scope variables. This is also very useful for debugging, most debuggers have some way to view what the scope variables are. Inside of Chrome we can view them and let's create a few variables so that we'll see something, we'll say var a equals a, var b equals cat, var c equals one. Then if we set a breakpoint and we execute this DoStuff, we'll open up our console, we'll say DoStuff, what'll happen is it'll break here, but if we look at our scope variables, you can see that these local variables show up we can very easily see what's in scope and what the values are. This is pretty handy for doing some debugging, so you don't have to put everything manually into the watch expression, it just gives you a very quick view of seeing what's going on. You can also use this global one, but it's not quite as useful, because there's quite a bit of things usually in the global scope, but you can check this out. You can see that we have our step and thing at the global level, therefore they'll show up here, if you can find them, we have step number set to three, we have thing set to ants. Conditional Breakpoints One feature that's really useful for debugging JavaScript is the ability to set what's called the conditional breakpoint. This means that the breakpoint won't be triggered unless some condition is true. This is very useful for debugging loops or debugging only in certain instances. Many times we'll have JavaScript code that will loop through some data and do some functionality, and we're only concerned about looking at the data, or actually debugging it when the data meets some certain criteria, or we're in a certain iteration of a loop. Let's modify our DoStuff, let's make this be a loop. We'll say four, var I equals zero, I is less than five, I plus plus, then we'll put this whole section inside of a loop. Now if we run this inside of the console, let's save this first, what you'll see is that it's going to run this a bunch of times, our step is incrementing every time that we're running this because we're inside of this loop. Let's go ahead and set our step number back equal to one, and what we'll do is we'll set a breakpoint. Let's say that we really want to break when the step number is actually set to the value of three. Set this breakpoint, we can right-click on the breakpoint, say edit breakpoint, then this will only stop if a particular expression is true. Let's set up this expression of step number is equal to three. Now you can see this shows up in a different color, if we run our DoStuff, it's hit this breakpoint, but you'll notice that at this point, step number is equal to three. It didn't break on the first time through the loop when step number was equal to one, or two, only when it was equal to three did it actually hit this breakpoint. I've seen many developers debugging JavaScript and they'll set a breakpoint inside a loop then they'll hit this play button to resume over and over again until they get to the right iteration of the loop, and then they'll accidentally click it one too many times, and have to start over again, and I've done that myself, but using these conditional breakpoints you can avoid having to do that because you can just break on the third iteration of the loop if you want to, without having to keep hitting resume and risk going too far. Caught Exceptions Another common point where you might want to break into your JavaScript code for debugging is when an exception is thrown. And there's two scenarios in which the Chrome dev tools allows us to very easily debug, which is when an exception is thrown in general or when an exception is thrown and not caught. Let's add some code into our JavaScript we'll say try, and inside this try block we're just going to do a throw, and we'll just say exception thrown. Then we'll add a catch, we'll say catch e, inside this catch we're not going to do anything. Now what will happen is if I just execute this code, normally it's just going to throw this exception and catch it, so we'll just say, DoStuff, and you can see, nothing happened. But if I click on this pause on exceptions, you'll see that it turns blue the first time I click it. Now what'll happen is, if I run the DoStuff method, it breaks here where this exception was thrown. Even though we're catching it, it's going to break on any exception being thrown. This is useful for figuring out when something is being thrown but it's being swallowed up by a catch block, like it is in this case, so you're not seeing the actual error. Uncaught Exceptions We can also set this state to break on uncaught exceptions only. In this case, when it's blue, it's going to break on all exceptions, but if I click it one more time it'll turn purple, and it will break on just the uncaught exceptions. And I've found that when you use this break on uncaught exceptions, it will only work when the page is being loaded or the JavaScript is coming from the user interface. If you do this from the console, you can see that it doesn't actually break, but if I were to re-load this page with this modification that I made that will throw this exception, then you'll notice that it does break, because this is an uncaught exception. When I run this to continue, you can actually see the exception shows up in the console. Here it does give us a stack trace, which you can debug to see where the calls came from. It gives us the exact location where the call originated that ended up throwing this exception. XHR Breakpoints It's often difficult to debug ajax calls, to set a breakpoint that will fire when an ajax call happens. And often you need to figure out what's happening when an ajax call is not working correctly, but using the Chrome dev tools, we can do that pretty easily. I'm back at the Pluralsight site, and I'm at this C sharp fundamentals course, which is an excellent course by Scott Allen, in here if I load this page, you'll notice if I go to the network tab, that if I look at the xhr, which are these ajax requests, we see a few of them. This page is actually using some ajax calls. Well what if we wanted to figure out exactly what was happening when this strange call was being made. What we can do is set a breakpoint. If we look at the name of this, it has cb equal, then we go to our sources tab, we can go to this xhr breakpoints, hit plus, we can put this cb equal in place. Now what's going to happen is whenever the url contains cb equal, and it's making an ajax call, it's going to break automatically for us. Now what we can do is we can reload this page, which will cause those ajax calls to be made, and you can see that it's automatically breaking where this ajax call happened. In fact I have the pretty-print turned on, if I were to turn this off, you can see that this is some minimized JavaScript this is another place where that pretty-print comes in very handy. Now I can see exactly what's happening I can debug this call to see exactly what data is being sent, what's sending it, I can even go up this call stack and figure out exactly where this is coming from. Since most of this JavaScript is minified, it makes it a little bit difficult to figure out what's going on, but in your application when you're doing debugging, you probably want to use a non-minified version of JavaScript for debugging just to make things easier. But it's very nice to have this xhr breakpoints feature so that you can break when those ajax calls are being made. Event Listener Breakpoints To demonstrate this next way to break, I've went ahead and added a button to our html and some JavaScript for this on-click event. So when this on-click event is triggered on this button, we're going to call load resources data. We'll have the load resources data button on the page that we can click to do that. I'll go ahead and open up our page. You can see that we have this load resources data button. If I bring up the Chrome dev tools, and go to sources, under here, you'll notice this event list near breakpoints. This is very useful for figuring out where events are hooked, and breaking automatically. Many times you'll find that you don't know exactly where some event listener is in the JavaScript and it can be hard to sort that out, but you do know when you click something, when you do a mouse over, when some event fires, that some code is responding to that. This is a good way to figure that out. In our case, it's pretty simple, but we can expand this mouse event, we can look for the click event, and now what's going to happen, is whenever anything is hooked up to a mouse-click event, it's automatically going to break when that fires. Now if you just check this, it's not going to do anything if you don't actually have an event handler, that's why I modified our code. But when you do have an event handler, and you click something that is going to trigger that event handler, it will automatically break. If we click this load resources data, you can see it automatically went into the debugger, and it broke on the exact line of code that handled this on-click. You'll notice there is quite a few different choices almost all the events exist on the dom you can set breakpoints for and be able to break whenever those events fire, another very useful way to use this is with the page load. If you want to set a breakpoint when something's responding to the load or unload, which is a common place where JavaScript inserts itself or hooks into the page life cycle, this is a really useful way to break there automatically. Web Workers The last thing that we're going to look at for the sources panel is breaking on web workers started. If you're not familiar with the idea of a web worker, it's basically a background thread so that you can create multi-threaded JavaScript applications. What we can do is we can set Chrome to break automatically when a worker starts, which can allow us to debug these worker threads that would be difficult to debug otherwise. I've modified our MyJavaScript.js, and I've added at the end of this DoStuff some code to create a worker, we specify what JavaScript the worker will use. In this case I've created this task.js file, that basically just has this one handler for on-message, it will post back a message to whoever called it. Inside here, you can also see that I have a handler set up for receiving a message from the worker, in this case it will just log to the console, whatever the worker sent. Basically this will be some very simple communication between our main process and the worker, by sending a message, we'll post this message 'joe', then what will happen is the worker will get it, it will say 'hello joe', returning that as a posted message, and our handler will pick it up and log it. There is one other thing that I had to do, since we're using a local file system version of our web page, and I had to go into the properties of Chrome and add this allow file access from files. Now I do want to give you a warning, you probably don't want to set this on your main Chrome instance, I have this on my Google Chrome Canary, if you want to use the dev channel you could set it there as well, but you do have to be careful, because when you set this up, it does open up some security vulnerabilities. That's why I'm only using this for my Canary version that I'm using for debugging my web applications. Once you have that set, if we then open up our browser instance and go to our page, it will automatically put out that text to the console. We can see that it says 'hello joe,' so we know that our worker is working. If we go to the sources tab, then we go to workers and check pause on start, you'll notice when I load this page now, it actually opens up a second set of the Chrome dev tools, and that's so that we can debug this second thread that's running in our JavaScript. You can see that this is set to task.js, it doesn't have all of the tabs that the other one does, it just has the sources, timeline, profiles, and console, but here we can step through, we can do anything that we could do in the regular sources to debug this separate thread that's running. Audit Panel Overview The audit panel is a very useful tool for getting a quick idea of problems with your page. You can run the audit panel to see issues with network utilization, or webpage performance, and view suggestions for how to fix any of the problems that are found. It's not a comprehensive tool to diagnose all of the possible issues with your page, but it does have some good advice, and it's baked right into Chrome, so it's pretty easy to use. You can even save a history of audits so you can see if the changes that you're making are reducing the suggestions. Running An Audit There's really not a lot to the audit panel. It's pretty simple, there's not a lot to say about it. If you click on the audit panel, you should see a page that looks like this, where you can select what audits to run. You can select all to run the network utilization and webpage performance, or you can just choose one of those if you want, and then you can either choose to audit the present state of the page, or to reload the page and audit on the load. If you choose this reload page and audit on load, it's going to reload the page when it runs and then do the audit at that point, as opposed to auditing what's existing on the page currently. If you really want to make sure that your results are accurate, you probably want to use this in most cases. I'll go ahead and select the reload page, and audit on load, and then run. You can see for our simple page, there's not a lot. There's really no point in going over all of these specific things that it's going to tell us about, because it's going to vary depending on what your page looks like but in our case it has two hints. It has one for network utilization, it says that width and height should be specified for all images, in order to speed up page display. That's a pretty good suggestion, so we could specify the width and height for our image. And it also tells us that we should optimize the order of styles and scripts. Let's take a look at that. What it's asking us to do is, it's saying we should load the style shoot before the JavaScript. If we go to our source, we can make that change pretty easily. Instead of loading the JavaScript first, I'm going to move this and load it after the CSS. Now if we go back to our audit, then we reload this. You can see that that webpage performance disappeared. We still have this specify image dimensions. And we can also check to see what we've changed by looking back at these results. We can see that our first set of results was complaining about optimizing the order of styles and scripts, but the second set of results does not. And when you're done you can always click this button to clear the audit results and start over if you want to as well. Up Next This module may not have made you a JavaScript ninja, but now you should at least have the skills to be able to debug JavaScript like a JavaScript ninja. You should know how to set up breakpoints for all kinds of scenarios in your web application and be comfortable with navigating around the script's panel. We also took a look at the useful audit panel for getting some quick suggestions and improving our network utilization and page performance. Up next, we'll be finishing up our coverage of the Chrome dev tools as we look at the timeline and profiles panel. We'll learn how to really dig into the performance of our browser and find out when our webpages are consuming too many CPU cycles or leaking memory. Thanks for joining me, and take care. Timeline And Profiles Panels Introduction Hi this is John Sonmez from Pluralsight, and in this module we'll be wrapping up our coverage of the Chrome developer tools as we tackle the two most difficult panels, the timeline and profiles panels. These panels can be used in conjunction to really help us fine tune our web pages, and find out exactly what is happening inside the browser. The only problem is both of these panels can be a bit difficult to use, because they contain so much data, and what all that data is is not always apparent. Don't worry, though. I'll be giving you the best bang for your buck as I show you the things you should know about these panels that will benefit you the greatest, without requiring a degree in memory management. Timeline Panel Overview We'll start off by looking at the timeline panel. This panel is a very useful panel for finding out exactly what is happening in the browser when your page loads, or when you perform some actions on your page. The timeline panel has three main views. First, you can view the events that have taken place. It will show color coded events on the timeline so you can see exactly where each event took place, and how long it took. Next, you have a frames view that you can use to see how long it is taking to render each frame, which is basically a display update in the browser. This can help you debug performance issues that could lead to choppy animations on your page. Finally, you have a view where you can see the memory usage of your page over time. This view helps you correlate what events happened with how much memory was being used at that time so you can pinpoint what operations are costing memory, and possibly not ever letting go of it. Don't worry if you don't get everything the first time around. I found that you'll have to use the timeline panel a bit before you really start to get what you're looking at. Recording a Timeline When you first open up the timeline panel, you'll notice that it's blank. You actually have to record in order to get some timeline data. In order to do that, you can simply go down to the bottom, and click this record button. When you do this, it's going to record anything that's happening from that time forward. You can see some GC events have occurred while we're just sitting here talking, and even though we haven't loaded the page, it's still able to record that information. If I hit stop to stop recording, it'll stop recording and we can see what has happened during that time frame. Now, it's not very useful to record a page not doing anything. In most cases, when you record information what you want to do is to reload the page. Let's try this again. This time I'm going to click record. Then, I'm going to reload the page. I'm going to be hitting shift while I click this refresh button just to make sure that I'm getting all the resources, and I'm not caching anything so that I can get fresh copies of anything that I'm loading, and this is a habit that you'll probably want to get into when you're working with the Chrome dev tools, especially when you're working in the timeline and profiles panels. Let's go ahead and check this out, and now you can see that I have a recording that has populated this timeline. Now, let's look at what data we've captured. Events View - Top Bar You can see in our timeline that we have three different views. Events, frames and memory. We're going to start off by looking at events. The events shows us what is happening in a specific period of time. You can see that at this top section we have our time chunked into 254 millisecond chunks, and on this timeline we can see what is occurring and how long it's taking to occur, and you may have noticed that it's color coded. You can see at the bottom a legend, which you can actually use as a filter, as well. We have the blue sections which are loading, or basically network transactions that are happening, like loading a page. We have the yellow, which is scripting, which will basically be your JavaScript. Then we have purple, which is rendering. This is usually going to be something like CSS, or some type of animation that's occurring on your page, and then we have painting, which is just painting the screen, and we can use this filter to filter these to turn off or turn on so we can look at exactly what we want to see. You can really think of this top part of this event view as the big picture, the map of what we're looking at. We can drill down into a specific slice of time by changing these bars. If we move these bars in, you'll notice that the bottom part is changing. It's adapting to whatever this time frame is, and while this top part is chunked into 254 millisecond sections, you can see that the bottom part changes based on how far apart these markers are. Events View - Records Now, the easiest way to make sense of the data that we're looking at is to pick a spot where some action is happening. In our case, we have some action that's occurring in this area right here. I'm going to move the timeline so that we're just viewing this particular area. Then, in the bottom section, we can see exactly what's happening based on these records. These records are collapsed by default. So it's going to group things together that initiate other actions, but you can't expand them to see more detail. Let's take a look at this left hand side. Here you can see what each record is, and again these are color coded based on this legend below. You can see that we start off by sending a request from my page HTML, and if you hover over this section, you can see some more details, like the duration, the self time, the CPU time, aggregated time, the actual resource, and what the request method was. It was a get in this case. The way to decode what you're looking at with this bar is that the darkest section is basically how long the actual event took. Then, after that, that next lighter section is how long the CPU took, or how much CPU processed time it took for that action to occur, and finally the lightest bar is the beginning to end of when this event started, and when all of the nested events that occurred underneath it, which we'll take a look at in a minute, actually ended, so it completed this full request. Let's expand this bar for the send request for my page HTML. If I click this arrow, you can see that this is actually more than just this one thing. We had a send request, which gave us a receive response over the network. You can see that was pretty quick. We have this receive data. Then we have a recalculate style, which occurred in the rendering, because when we got the page, it needed to do some rendering on that page. Then we had a parsing of HTML that occurred. We triggered our finished loading when this page finished loading. You'll find when you're looking at this timeline also that some of these things might not be all that apparent. For example, why are we recalculating style here after we receive the data, and why are we doing it twice? I can't really answer that question, and you don't have enough information from here to be able to answer that question, but the good news is in most cases you won't really need to find the answer to that question. If you see something weird that's happening from some JavaScript that you have, then you're more likely to need to know what's going on, and you can experiment, and try to figure out exactly what's causing a recalculation of style, or causing something to take a long time. In most cases, I found though that unless it's something that's taking an excessively long time, it's usually not going to make much of a difference. The things to watch out for are things that you don't understand that are repeated multiple times. For example, we have two recalculate styles, but we don't have 50 of them. If we had 50, I'd be a lot more concerned, or if one of these bars was way over here, very long, I'd also be concerned and want to try to figure out exactly what's happening. Another thing that you'll notice with this events view is that we have these light bars. You can see that this blue one is for the DOM Content Loaded event. This red one is for the load event. So, we can see where these events are firing in relation to everything else that's going on. Let's go ahead and collapse this first one for the my page HTML. Then we see that there's three send requests. It has this times three, which means that they're grouped together. If expand this, you can see that this is where our style sheet, which can also be expanded, is being fired, and then we have one for our JavaScript, as well. You can see that some of these are taking longer, because there is some delay here between when it first requested this, and when it actually got the data and finished loading. It's a very small amount, though, because we're not getting this over network. We're just getting this from the local file system, and if we expand one of these JavaScript ones, you can see what's happening with this time and time end. Remember we had put this in our JavaScript, and when we hover over this, we can see where it's coming from. I can click on this to see that this is coming from this console dot time. It marks it there as a record. If we expand this paint, you can see that you can even find out about how long it takes to decode a PNG image. It's right here on that timeline as part of the painting operation. It can also be useful to use these filters below to filter on everything that's taking a certain amount of time. Right now we're viewing everything, but we could say if it's greater than one millisecond, show it. That eliminates quite a few records, and if we say if it's greater than 15 milliseconds, show it, and that 15 milliseconds wasn't chosen just by random. It happens that each frame, which we'll talk about when we look at the frames view, takes 16.6 milliseconds, and that's because there's 60 frames per second that could conceivably be rendered. Frames View In addition to the events view of the timeline, we can look at the frames view. This frame view is going to show us what's happening with a vertical view of the time that's passed. What I mean by this is that if you look at these bars, each one of these bars represents a frame that was rendered by Chrome. Now a frame is simply just a display update. So, when you render a frame, you're going to be refreshing the drawing on the screen, and Chrome is capable at doing this refresh at 60 frames per second. What this means is that if you're able to get your frame ready to go to the display faster than 60 frames per second, it's still going to be at 60 frames per second, because that's the max speed that Chrome goes at. It is also probably the same speed at which your display operates. So, that should be optimal. Now, if you have a frame that is going to go out at the 30 frames per second mark, it's going to be a little bit slower, but it shouldn't create a noticeable difference. Anything worse than 30 frames per second, though, is going to be noticeable, and it could cause your animation to drag, and seem like it's choppy. Using this frames view, you can determine what's happening and see if you might be in danger of having some slow frame rates on what you're displaying. You can see that each bar represents a frame, and the height of the bar represents how long that it takes for that frame to be displayed. If you look at this line, you can see there's a line that says 30 frames per second. This indicates any bars that are below that line are going to be faster than 30 frames per second. Any bars that are above that line will be slower. Now, if we didn't have these big bars at the end, we'd probably have a second line that would show 60 frames per second, which is the optimal speed, but you can see that most of the work that's being done is happening at the beginning, and these are color coded again. It's a little bit hard to see, because we don't have data that's taking a very long time, but let's go ahead and change these sliders just like we did for the event view so that we can see this data a little bit better, and if we look at the bottom part, the first thing that you'll probably notice is that this is broken into time segments. Let's zoom this in a little bit more, and what you can see is that there's this 18 milliseconds. Then 16 milliseconds, 92 milliseconds. These are lengths of each frame. You can see that the first frame that we have rendered is taking 18 milliseconds. That would make it just under that 60 frames per second. Anything that is going to be faster than 16.6 milliseconds will be faster than 60 frames per second. Anything over that will be slower. So, it looks like we don't really have much of a problem here. The next frame is 16 milliseconds. That means that it will actually be over 60 frames per second. So, we don't have any problem there, but the next frame after that is 92 milliseconds. If we expand this out a little bit more, we can get a better view, and we can see this is the frame that we're talking about, but there's nothing really going on here. In fact, if we look at what's happening, we have another that's 1.2 seconds, and there's not much going on here, as well. Let's expand this out a little bit more. You can see that we have this garbage collection event, this GC event that is causing us some problem, and wasting some time, but it's not really affecting our page. Really when you look at this, you can tell that what's actually showing our page is up to about here. These frames, this frame and this frame, and a little bit into this last frame, but everything should be pretty much displayed at this point. If we look and see what's happening, we've got the image decoding of our image. We've got our composite layers. We've got this final paint that is happening right here, which is pretty much inside of our frame, and it can take some time to get the hang of decoding this and figuring out exactly what's going on. You might want to load up a few different web pages and check this out. For example, let's trying going to Pluralsight. Here what we'll do is we'll take a look at what the timeline looks like when we load this up. We'll do a record. We'll load up the page. Then we'll stop recording, and you can see we have a lot more data to work with in this case. These bars make a little bit more sense. You can see that we have a 30 frames per second bar, and a 60 frames per second bar. So, we have some bars that are taller than the 30 frames per second, which means that they're going to be slower than 30 frames per second when the page is first coming up, but then most of these bars afterwards are under the 60 frames per second. So, they're faster than 60 frames per second. So, we really shouldn't see any problem. Once the initial page loads up, then any of the JavaScript that's running here that's going to be displaying the rest of the elements is not going to be choppy. One last useful thing with the frames view is this summary. If you hover over this section at the bottom, you can see that it gives you quite a bit of information about the range that you have highlighted. It tells us exactly how long that range is, and how many frames are in that range. It tells us what the average time is, which is pretty valuable. Tells us that the average is coming to about seven frames per second, but that's taking into account some really slow frames into there. The maximum time it took, what the standard deviation is, and then the time by each category. So, this gives you an overall feel for what the page is going to feel like for that particular time range. Memory View - Top Frame The last view that we can look at for our timeline is the memory view. This is going to show us what the memory profile looks like at a given time. When we start recording, we can see that we weren't really using much memory. Then we refresh the page to reload it, and you can see that our memory spiked up, but not too high, and it slowly went down, and then you can see right at this point something interesting must have happened. Well, we see that there's a garbage collection event, and then at that point it went up again, and then it ended up going back down to almost no memory being taken up. Now sometimes this data isn't going to make a huge amount of sense. What you can really use this for is looking for big spikes, or areas where it just looks like it keeps growing so you can find something that might be a memory leak in your JavaScript. We can't really predict the behavior of the garbage collector. So, we can't know exactly what's happening past this point. What we're really concerned with, though, is what's happening up to this point. We can see where we end up using a lot of memory, and then we can see that that memory should be going down eventually when we hit a garbage collection event. Just like we can do on the other views, we can zoom in. Remember this is going to be a top level view. So, we can hone in on the area that we're concerned with, and then you can see that this is actually a zoomed in view of this slice in the bigger timeline, and we can get more accurate measurement of what's happening during that time. If we zoom in a little bit more, we can tell exactly what's allocating the memory. We can see that the memory got allocated before this request even happened, and then during this request process, right about when the page loaded up, that's when the memory started to go back down, and you can see if we expand this out where some of these things might relate to memory. Oftentimes if you see a big spike that's going to tell you that something that you're doing is using up a large amount of memory. Memory View - Counters We also have this section at the bottom called counters, and I like to turn these off, because it's a little bit hard to read when you have them all on, but you can turn on which one you want. Let's say we want to look at the document count. We can see that there was one document up to the point where really our page loaded. Then we had two documents, and I can also click anywhere on here to get a zoomed in view of that particular section. Then let's look at our node count. We can see that we had only 32 nodes. Then as our page was loading up, you can see that node count increased where it finally ended up topping off at 64 nodes. Then after that, we can look at our event listener, and this is pretty interesting. You can see we had one listener. This was before we reloaded the page. Then when we reloaded the page, there was a little bit of time when the page was loading up where we didn't have anything hooked up, but then when we got our new page, we ended up getting our listener hooked up again, and that's that listener that's attached to this button. Troubleshooting Slow JavaScript Now that we have a basic idea of what the timeline does, and how it works, let's put this knowledge to use. I went ahead and I inserted some JavaScript that's going to slow down our page quite a bit. Let's see if we can find it, and troubleshoot the problem. I'm going to go ahead and reload our page, and let's do a record and reload to capture the changes. You can see we have this section where everything is happening. Let's zoom into there. Now, when we view this, we can see that these bars are pretty long. We have this send request is fairly long, but there's not a lot going on here. We can see that it's grabbing the style sheet. We're getting this JavaScript JS. In fact, this is taking awhile to get this, and remember this light blue bar is indicating how long it took from the start to when that event finished, or when that event considered itself to be done. So this doesn't tell us a huge amount. It doesn't mean that it's spent all this time doing this send request. We can see, in fact, that there was a receive response, and receive data, but it was associated with the send request. Whatever is slowing things down originated from this JavaScript. If we look here, we have the send request on the Chrome PNG. It was also waiting for whatever is slowing things down to happen before it was considered done. If we scroll down a little bit further, there's this parse HTML. Inside here we see some JavaScript that's taking a very long time to run, and the way that we can figure out what this is is if we look we can see that each one of these little blocks is not taking very long, but then we have this little block, followed by this big gap before we hit another little block. So, whatever is happening between here and here is what's slowing us down, and we can check this by looking to see what script is executing here, and what script is executing here. If we look at this first script, and go to this JavaScript, you can see that that's the second step. Okay, so between second step and this script, which if we click on this one is the console log from the third step. Ah, well what's happening in-between those? You can see that I created this loop that's looping from zero to 10,000 and setting a local storage item. That's going to slow things down quite a bit, and you can see it clearly on the timeline. You just have to know to look between these gaps, because not everything that's running is going to be marked on this timeline. For example, that loop doesn't show up, because that loop is not actually a JavaScript function call like these ones are here. If we look at the frames view, we can also see it from here. You can see that it's slowing down that frame, and we could have found it that way, as well, when we cut through here and found this JavaScript that's taking a long time. When we look at the memory, there's not a huge indication of what's happening. In this case, you can see that the memory level's off. So this view doesn't really show us. We can still look at the records and figure this out, but in many cases to figure out how long something's taking, you want to use a culmination of the events in the frames view. Marking The Timeline We can also mark the timeline ourselves. This is very useful for debugging to figure out where events are happening in time visually on that timeline. We can of course log things out using the console log, but that's going to show up in the log, and it doesn't give us a visual indication of when things are happening. If we go into our loop, I can uncomment out this line where I'm doing a console.timeStamp, and timeStamp will actually put something into that timeline view. It'll make a line that we'll see in a minute, and you can specify a label for this. I'm putting a setting plus I. Let's make it so that we don't do this every single time, because it'll be a little bit hard to see, but let's say if I mod 100 equals zero. So every hundredth time, then let's go ahead and do this. Now, if we save this, and we go ahead and do a record. Reload our page. Stop recording. You can see when I move our timeline over that there's a bunch of ticks on this timeline. In fact, it's easier to see it from the event view, and I can see here. Let's zoom this in so that we can get a good view of this. We can see where these ticks are happening. You can see the setting zero, setting 100, setting 200, 300, 500, and so on, and you can see that this gives you a real good indication of when events are happening, when things are slowing down. You can see almost a pattern to how this is happening, and you could imagine that you could use this for debugging. You could mark different points in the timeline when different things are happening, and this would show you exactly when those events were occurring, because you could hover over and see where the marks are in relation to other things that are happening to these records here, and to things that are happening up here, and even on the frames view when you zoom it in, you can tell where during a frame are these timeline markers happening, as well. Profiles Panel Overview Now we get to the fun stuff. The profiles panel contains a large amount of data. I'm not kidding. Using the profiles panel, you can find out what parts of your JavaScript code are using the most CPU, determine if your CSS selectors are slowing down your page, and find out all you would ever want to know and more about Chrome's use of memory. There are three kinds of profiles we can utilize on this panel. CPU, CSS selectors, and memory. CPU and CSS selectors aren't too difficult to make sense of, but the memory snapshots can be a bit difficult to understand. The good news is, though, you don't need to fully understand everything going on with memory snapshot view in order to make good use of it. I'll show you how you can get some basic information that can help you identify problems in your page, without having to dig too deep into all the nasty details. CPU Profiles Let's go to the profiles panel, and here you can see there is three options. Collect JavaScript CPU Profile, Collect CSS Selector Profile, or Take Heap Snapshot. We're going to start off with the JavaScript CPU Profile, and I went ahead and left in that code that was slowing things down so what we can see it when we do this profile. I'm going to go ahead and click start, which will start the profile. Then, I'm going to reload this page, and I'll hit stop. Now you can see that there's a profile that shows up on the left. If I click this profile, it'll show me the details of what was happening with the CPU usage. You can see by default it's going to be sorted with this tree top down, which basically means we're looking at the top down from where the calls originated to see what was being utilized, and you can see that most of the time the CPU was idle. Then we have program. Then we have garbage collection, and then we have this V8I18N, which is the Chrome engine. Finally, we have this file, which is our my page HTML. If we expand this, you can see we have our do stuff JavaScript method. Inside here, we can see that most of this was not significant, but this third step was significant when you compare it to how long do stuff took. It took most of the time that do stuff took. This tells us that there's a problem in here. If we were to click on this, we can see obviously this is the problem that we knew about. So, this view is actually pretty easy to understand and read. What you're really looking at is the JavaScript. You can pretty much ignore this stuff up here, because it's not going to pertain to you, and just look at your own HTML page, and your JavaScript that originated from it. We can also sort this by heavy, or bottom up. When you look at this, what it's doing is it's looking at the lowest level calls. So, this is why a third step shows up on here, and this gives us an indication of exactly what's slowing us down from a very low level. It's the third step function that's causing it, and when we expand this, you can see it's actually showing us the parent. Well, the parent is do stuff, and then the parent of that is our file. So, it's pretty much upside down, the opposite of when we do this tree top down. We can also do some things here like toggle this percent to be the actual time in milliseconds, which can be useful, and also we can focus on a selected function. So, we can choose this my page HTML. If we click this, it will make everything else go away. Another way that we could have done this is if we click on restore all functions. Let's say we don't care about idle. We can exclude that one. So, you have some options for viewing your CPU profiles, and getting rid of the noise. You can also save and load CPU profiles just by right clicking. You can choose save. You can save a profile for later. Perhaps you're going to make some changes. You want to see how the performance of the application is doing over time. So, you could save off a profile, and load it up, and compare it later on. CSS Selector Profiles In addition to running the CPU profile, we can also go back to profiles, and we can choose to collect the CSS selector profile. This profile is going to show us how long it takes to match on any CSS selectors that we have. It'll also show us what those CSS selectors are, and how many matches there were for them, which is some useful information. Let's go ahead and click start. We'll reload our page. We'll click stop. Now you can see we have a CSS selector profile. If I click on this, you'll notice that most of this isn't relevant. The only ones that are going to be relevant are the ones that have an actual source. The rest of this is default stuff that Chrome is doing. So, we don't really have much control over that, but you can see that we have a selector for H2. In fact, we can click on the source and see yes we do. It sets the font style to italic. If we go back into our profile, you can see that it ends up matching one element, just this one H2. This total is the total amount of time. You can see that nothing is really taking any time, because this is a very quick operation matching with the CSS selector. We also have this body one, which just matches one. Now, let's take a look at this on the Pluralsight page. If we go to our profile, collect our CSS selector profile. We'll reload our page, and we'll stop it. Now, if I take a look at this profile, you can see there's quite a bit more interesting information. It becomes a little bit more useful when you have a lot of selectors. Now still, you can see that this isn't taking much time. We're actually using a star selector, which is going to select everything. It's going to apply the style to every single element. If we click on this, you can see what it's doing. It's applying this default set of styles to everything on the page to make it have a common starting point, and you would think that that might be expensive, but when you look at it in the profile, you see that it's only three milliseconds. Even though it matches 542 items, it doesn't take very long to do that. We have another match here that matches quite a few items. It only takes one millisecond, and it matches 508 items, and everything else is pretty much insignificant, even the ones that match a big number of items, they don't even take a millisecond to execute, and of course we have this percentage toggle, as well, where we can see what the percent of the total was, which isn't really that useful in this case, even though this took up 75% of the time. When you look and see how much time it is, you can see it doesn't really matter. Memory Overview Before we get into using the memory snapshots in the profiles panel, let's take a moment to briefly go over how memory works in Chrome. Chrome uses garbage collection to manage memory. So, you don't need to explicitly ask for memory or release it. One side effect of this is that Chrome has a garbage collector that needs to determine when it should release memory associated with some object. The basic idea is very simple. All objects have to be referenced from some root that must always exist. From there, every object that needs to stick around should be accessible by following some path of objects and references. If an object can't be reached from a root, then it must not be needed, and can be collected. In our diagram, you can see that object B is referenced by object C and object A. This means for object B to ever be collected, both object A and C must either be collected themselves, or have their references to be removed. There of course is much more than this to garbage collection and memory management in Chrome, but having this basic knowledge will go a long way to understanding the snapshots we'll be looking at next. Memory Snapshotting Let's go back to our original page. We'll go to our profiles. This time we're going to say take a heap snapshot, and what we'll do is we'll just click this take a snapshot. It instantly takes a snapshot of the memory, and we can view this. Now, this gets a little bit confusing. We're not going to go into all the details here, because it's not really going to benefit you much, unless you're doing some heavy JavaScript work that's going to be very memory intensive, which is pretty unlikely, unless you're actually working on the Chrome browser itself, but I do want to give you a basic overview so you can at least understand what you're looking at, and get some benefit from this. What we're looking at is this constructor view. What this is showing us is what objects were constructed from which constructor, and we have a lot that's compiled code, which is basically just our JavaScript that was just in time compiled, or is already compiled, and remember that JavaScript is going to take up memory. So it does show up here. This is something that you can pretty much ignore. Object, we have things that are just of the object type. You can see that we have quite a few different types that are usually created by the constructor of that type. For example, if we take a look at string, this one we can see that we have two strings, and these ats, followed by a number identify that object uniquely so that you could track that object over time. We can look at that particular object. In memory we can see some information about it. Some things that are useful are the shallow size and retain size. The shallow size is how much actual memory this particular thing takes itself. The retained size is how much memory it ends up preventing from being collected. So, if our object references other objectS, it's going to tie up whatever the amount is here, because until it's collected, whatever it's referencing can't be collected either. At the bottom, we're looking at the retaining tree for an object that we have selected. What this basically is is the tree that would take you to the root. So anything in this path would need to be eliminated or collected in order for our object to be collected. You can think of this as saying what is causing my object to stay in memory, and not be collected. The answer is down here, and don't worry if you don't quite understand what this means. This isn't the easiest thing to read, and in fact because there are some objects that you don't really see in JavaScript that still exist inside of Chrome, you're not always going to be able to really map this to objects that you are aware of inside of the browser. There is a legend for deciphering what some of this is. If you click on this question mark, you can see this legend that shows you what the different symbols mean, or what the different italics, or highlighting, or colors mean, and there are a few different views that you can look at, and we're looking at the summary view. There's also a comparison view, which we'll look at in a minute. This lets you compare two snapshots. We'll see how we can actually detect when memory's increasing greatly, or when something is causing a great increase in memory, possibly a leak when we take a second snapshot, but we're not going to do that right at this moment. Then we have containment. Containment shows us basically from the roots the map of the memory. So you can see there is a few different roots. We have this garbage collector root. We have our window. We have our page, and we have our dom tree. We could expand our dom tree, and see what is basically the map of the memory. You could follow this down through all the objects. This is a handy way of looking at and seeing what the object tree structure looks like inside of memory. Then we have this dominator view, and what this is is this is showing us what objects are basically preventing other objects from being collected. This one's a little bit hard to understand, but basically a dominator is any object that exists in all the paths to another object from the root. So, what this means is that if you take out the dominator object, then whatever other object it was referencing can be collected. The dominator object for an object is one that when it's removed, that means that that object can be collected, and this view can be useful if you're trying to figure out what is keeping something around. Although, it is pretty hard to navigate and make sense of a lot of this. So, it's not something you're going to be using, unless you really need to, and we're not going to get into the complexities of this, because it is quite complex, and really someone who's very familiar with the inner workings of the garbage collection and memory in Chrome is going to find this more valuable than your average developer will. Comparing Snapshots Now just to demonstrate the snapshot, and how you could detect a problem, let's create a problem in our JavaScript. We have this loop already that we left in here. Let's get rid of this timeStamp bit, because we won't need that, and we'll get rid of this localStorage bit as well, and what we're going to do now is instead we're going to create new div elements, and we're going to find on our document the body. We're going to get the first element from there, and append the div. So, we're basically going to create a bunch of divs, and let's not create 10,000, because that'll be a little bit too much. Let's just create 1,000. That's still going to be a lot of memory that we should be taking up. Let's go back to our page. We'll reload our page, and this time I'm going to take another profile. I'm going to do another snapshot. Now, this snapshot is going to be a snapshot that has a lot of those new elements added. If we go to that snapshot, then we switch to this comparison view, and we compare it to snapshot one, we can see some big changes here. Now, we're looking at changes from two loadings of the page, so things are not going to line up perfectly. If we wanted to just see what was happening, for example when we clicked a button, we could do that to see if when we're clicking this button are we causing a large amount of memory to be allocated, but in our case we're comparing two different views of the page, or the reloading of the page between when we had that script in that was generating those div elements, and when we didn't, but even here you can see that there's some pretty obvious things that are happening. We end up getting quite a few new objects, just because we ended up flushing out our existing page, and loading up a new page, and we also have a bunch of deleted objects. For the same reason, these things should pretty close to match up, except that we have one big difference, which is between this new and deleted on this HTML div element, which is what we expect, because we put in a loop to generate 1,000 div elements. Well, we did do that, and you can see that here's all those HTML div elements, and when we click on these, you can see that the retain tree is that document dom tree. So, you'll probably find that using this profile, taking the heap snapshot is a useful way to figure out what's happening memory wise, especially when you can do the comparison. Probably the most useful part of this part is using this comparison view to compare between different snapshots so you can see what's changing between them, and we reloaded pages, but oftentimes you can also use this, like I said, for events on the page. If you had some JavaScript that was executing when you clicked this button, for example, you could take a snapshot, and you could see what was happening between when you didn't click the button, and after you clicked the button, or perhaps you have event handlers for hover overs, or some animations that are occurring. You could check to see what was happening before the thing that you wanted to check occurred, and then compare it to the snapshot of memory afterwards. The End Well, we've finally come to the end of this course as we've run out of panels to talk about. You should now have a fairly thorough understanding of the Chrome dev tools. We covered just about every inch of the tools in this course, at least every inch that existed when this course was created. Don't worry if you don't remember everything we've covered. I found that you'll have to start using the dev tools more to really get a feel for the power, and fully understand when to use what panel. I recommend playing with some of the features we've covered in your own web pages, or looking at simple web pages with the tools to get some experience and practice using those tools so that when you have a problem with a webpage that you're working on, you feel comfortable enough to be able to use the Chrome dev tools to help you debug it. Thanks for watching this course, and take care. Course author John Sonmez John Sonmez is the founder of Simple Programmer (http://simpleprogrammer.com), where he tirelessly pursues his vision of transforming complex issues into simple solutions Course info LevelBeginner Rating (532) My rating Duration2h 50m Released24 Apr 2013 Share course