I hate debugging, and have never met any developer who argued otherwise. It's a drag to have to go through your code and figure out why it's broken. And most importantly, it's an admission that my code is broken and that I'm not infallible! Heresy, I say!
Seriously though, bugs are simply a natural part of the web development process, and, while we may hate them, we certainly have to deal with them. Front-end developers haven't always had rich debugging tools like other platforms and languages. In the good ‘ole days, alert() was your friend and an important method (excuse the pun) for troubleshooting code. And debugging client-side code has its own unique set of challenges because of the variety of technologies that are in play. If you think about it, debugging pages, especially dynamic ones involves so many moving parts that could affect the rendering. You have the the Document Object Model (DOM), JavaScript, CSS, network traffic, HTTP headers, and many more technologies that all work to produce a page and in many cases interact and affect each other.
Thankfully, times have changed and all the major browsers have built-in tools that greatly increase the troubleshooting features for developers. I give a lot of credit to Joe Hewitt for pushing the tools landscape forward. He created Firebug in 2006. In my opinion, it broke ground on what real browser tools should be.
Since then, we've seen Firebug evolve tremendously and serve as a baseline for others to work from and we now have powerful tools in Chrome, Internet Explorer, Safari and Opera as well.
For this article, I'm going to focus on Internet Explorer's Developer Tools and the functionality it provides. The functionality I'll discuss will be very familiar to anyone who's used a browser-based debugger but I want to bring focus to Internet Explorer's tools to ensure that there's a good understanding of what's actually available.
Where Are We?
Let me begin by admitting that I know that IE is the browser you love to hate. I get it. The fact of the matter is that it's a major browser that's important to many site visitors and that means you'll be targeting it and also need to debug code in it sooner or later. What's kind of surprising is how many developers don't know that IE ships with developer tools or worse that they think they still need to download the Internet Explorer Developer Toolbar.
The developers tools are commonly called the "F12 Developer Tools" because pressing the "F12" key on your keyboard will open them up while you're in Internet Explorer (interestingly enough, pressing F12 also launches Firebug and the Chrome Developer Tools).
The developer tools are also accessible via the "Tools" menu under the label "F12 developer tools".
The key thing I was to stress is that they're included with Internet Explorer (and have been since IE8) so there's no need to install a plugin to get dev tools. Also, while they're called the "F12 Developer Tools", for the purposes of this article, I'm going to drop the "F12" and save me some keystrokes.
The developer tools provide developers and designers with a rich set of tools that can tackle many of the common debugging and inspection use cases they'll face during their work. Capabilities like:
- JavaScript debugging
- DOM inspection and manipulation
- On-the-fly updating of CSS styles and page layouts
- Networks traffic logging
- Script profiling
These are features that are par for the course nowadays and essential to determining what ails your pages. On top of this, the developer tools provide the ability to test your site in different versions of Internet Explorer by changing the browser mode:
Testing for multiple versions of IE has traditionally been a royal pain in the tuckus; this feature aims to lower the friction of ensuring that your sites work across the various versions of IE.
Additional capabilities include such things as:
- Validating markup against the W3C's validation services for HTML and CSS
- Prettyfying minified or obfuscated JavaScript code for readability
- Color picker
- And more…
- There's a lot of stuff available so let's review many of the key features.
JavaScript Debugging
I focus a lot on helping developers use standards-based development techniques to ensure their sites work great on IE. As you can imagine, I spend a great deal a time analyzing code, especially JavaScript. So, in order to trace down an odd bug, I need a JS debugger that can let me analyze the code in variety of ways.
Making Code Readable
One of the most important features for me is the ability to prettify JavaScript. I don't know any developer who is not minifying their production code nowadays. And that's absolutely the right thing to do, but, when I need to debug something on a production site - especially where I don't have access to source code - being able to prettify the code is invaluable. Yes, there are online tools like JS Beautify that can do that but it would force me to copy and paste code into it in order to deobfuscate the code. Having this capability built right in saves me a ton of time. For example, say I'm looking at a minified version of jQuery:
Via the tool icon, I can access the "Format JavaScript” option which will deobfuscate the minified jQuery source code and provide me with substantially more readable code:
As you can see in the image above, the code is certainly easier to work with. The other cool thing about this feature is that once you've enabled it, it will continue to deobfuscate your JS files during your session.
One caveat is that the deobfuscation process won't revert jQuery to its original source. No service that I know of can do that but source maps will solve that problem going forward. Be sure to read the article on source maps by Sayanee Basu that I just linked to for a great intro on the topic.
Stepping Through your Code
Once the code is readable, it makes it easier to determine the flow of the source. At this point, I can set breakpoints at logical spots in the code to isolate problems as you step through it. And of course, you can set multiple breakpoints across multiple source files.
You can also specify conditional breakpoints allowing you to break the code flow based on a specific value.
As expected, you can step into, out of, or over any method you're in providing the granular control you need to check out code and also not waste valuable time. What's important to note is that as you're traversing your code, a call stack is accessible that allows you to see how you got to a specific method or JavaScript file and go back to that method or file to inspect the code:
In addition, it helps to isolate unexpected code paths that may be the problem point.
Information is key to understanding what's happening and the developer tools works to give you the options to define what you want to see. So along with the call stack, you get information about variables in the current scope via the "Locals" tab:
Or, you can define your own watch list (via the Watch tab) so you can track how variable values change dynamically based on code execution. The great thing is that the tools give you the flexibility to change the values in either list so you can see how it affects your application.
And let's not forget the Console. No debugger would be useful without a console to output errors and allow you to debug interactively:
The console will display common errors associated with your page including JavaScript and markup issues. You can also enter commands to interact with the page as well as use the console object within your JavaScript code to display messages to the console.
Evaluating Code Performance
All of the above is great and certainly valuable. An often overlooked aspect of debugging is code performance. Rarely do I talk with developers who mention how they've evaluated their code to determine bottlenecks in slow running methods, especially from third-party frameworks.
The developer tools provides you with a JavaScript profiler that will analyze your code as it's run, providing a wealth of information to use to optimize your code.
Key bits include:
- Total # of times a function was called
- How long the function took to run
- How long child functions took to complete
- Type of function (e.g.: DOM or user-defined)
- The source file where the function is defined
Armed with this information, you can determine whether your method needs to be refactored, if a 3rd party library is causing issues or if a browser-specific method is a bottleneck. To me, the combination of Inclusive and Exclusive Time would be important metrics to evaluate because it would tell me how long a specific method took to run including the time it took child or external methods to complete. From there, I can start drilling down further to nail down the problem code.
Inspecting Network Requests
I'll never forget when I coded my first Ajax request. It was such a small bit of code but it honestly felt magical (yeah I'm weird that way). Doing dynamic DOM updates based on pulling back data from a background HTTP request was incredibly cool and a powerful capability. I'll also never forget the first time I tried to send a result back which ended up generating an error and leaving me dumbfounded. Thankfully, Firebug had a network request inspector that let me check out what my server-side code was returning and troubleshoot it.
The "Network” tab in the developer tools provides this very functionality. It shows traffic related to the page being loaded and exposes details you can use to troubleshoot network-related issues.
By looking at the traffic captured you can see the type of request being made (e.g.: a GET or POST), if it was successful and how long it took to complete. The network inspector also provides important details about the type of asset you requested (e.g.: CSS or an image) and what type of code initiated the request. This is all provided in a summary view that offers quick details about the requests.
By choosing to go into detailed view, you're able to glean granular information about a specific request. Being able to look at the response body was what allowed me to resolve the problem I mentioned before with my XHR call. But that's only a small bit of the overall data that you get by dropping into detail view. Apart from that you get the request's headers (request & response), cookies that were sent and even timing information that tells you how long the request took.
The timing display in the summary view is really important because it's a clear visual of which request are long running and might be a problem.
Making Markup Look Good
I'll be the first to say that I HATE testing for multiple versions of Internet Explorer. I'm mainly annoyed with the older versions and I'd be happy if developers could simply worry about IE9 and IE10. But it is what it is and there's a couple of ways of addressing this. You could use multiple virtual machines for each version of IE you're targeting. You could use Browserstack.com to virtualize IE versions in the browser. Or, you can use the developer tools' browser mode switching capability to have IE10 emulate IE7 through IE10.
This tool allows you to change the way that IE renders a page so that it emulates a specific version's capability, thus ensuring that your site should work for that version. Not only does it allow you to specify the browser mode (which determines feature support) but also the document mode (which specifies how a page will be interpreted). This gives you a lot of flexibility to test various versions of IE from a single browser. Just note that the IE team does their best to emulate versions. If you want full-proof testing, then VMs are the way to go. I typically start off with the last option because it's by far the easiest and the rendering is very close to actually using a specific native version of IE.
Inspecting markup is one of the most common tasks for any web professional. It's great to be able to look under the hood at how something is built without having to do a "View->Source”. The "HTML” tab in the developer tools shows all of the elements on a specific page along with their related styles and attributes. This allows you to inspect and update values in real-time and get immediate feedback. You can click on, say, a paragraph element and it becomes editable so you can change the text and see the results immediately. The same applies to the styles and attributes of that element.
Attributes can also be added inline by right-mouse clicking an element and choosing "Add attribute” from the context menu or by selecting the "Attributes” tab and adding it to the list. The following image shows how I added a color and font attribute to the emphasis element, displaying them as inline styles in the markup and individual attribute lines in the Attributes tab:
The page's markup is represented in a treeview-style so you're seeing a top-down view of the DOM tree and are able to expand elements to see their children.
CSS also has its own tab, however, it's meant to manage global styles typically stored in stylesheets. Selecting a stylesheet shows all of the selectors, rules and properties defined and allows you to tweak them as you please. In this case, simply unchecking the text-align property dynamically shifted the text to the left:
It's not only editing existing rules. You can also add new selectors, rules or properties:
More than a Plugin for IE6
The primary reason why I wanted to write this piece is because I was genuinely surprised by how many developers I've met, who had a misconception about the F12 Developer Tools - or didn't know that they even existed! My hope is that it helps developers get a feel for what's available and makes their troubleshooting a little easier.
I also hope that it generates feedback for future features that developers need. While the existing functionality is good, I'm sure there are a number of new things that you, the readers, would find essential to your debugging experience. Let me know what those are!
Comments