Chrome dev tools deep dive : Network


1. Throttling

A web application might work beautifully on fast networks but stutter and even throw up bugs on slow connections. Fiddler used to be the go-to tool for simulating delays and adding latency during testing; the good news now is that Chrome provides throttling too.

There are preset profiles available (e.g. GPRS, 3G, etc.) but you can define custom latency and throughput profiles if you want. Something for those of us who want to simulate network connections to IoT devices.

throttle

2. Replay requests

At times, there is a need to replay an isolated request several times. Refreshing the page works but brings down the entire page payload again.

A better alternative would be to find the request in the network tab, right-click on it and then replay it. Note that if you want more control, for example, if you want to replay a  request 10,000 times, you might have to look at other tools like fiddler or curl.

replay

3. The network panel headers

The default tabs that appear on the header row can be changed. For example, you can display the Method, eTags or even cookies columns.

Clicking on a tab header sorts all the rows by that column. Unfortunately Chrome doesn’t allow you to reorder the header ordering; a pity as I would love to customize tab ordering.

tabs

4. Network performance and content compression

This is one useful tool that is not so obvious. If you have the ‘small request rows’ option set; then you’ll have to switch to ‘large request rows’ (See the gif below).

  1. Size and Content: Size shows the magnitude of the downloaded file over the wire while content shows the real size of the contents. Ideally, size should be smaller than content since browsers can handle gzip-compressed files. If you see requests that have the same size and content value; that’s an optimization hole to plug.
  2. Time and Latency: The time row shows the request’s entire round trip time while the latency row shows the time it took to set up a connection and process the request on the server. If request latency times consistently take about 80 – 90% of the total time, there might be server processing or network connection investigations required.

optimize

5. Debugging with HARs

A customer living in Antarctica reports a bug in your web app. Obviously you can’t go to Antarctica, yet you need a dump of the customer’s state. Don’t fret it; HARs provide a way out.

HAR means HTTP Archive – a JSON file containing all the information necessary to recreate the network tab experience.

So, you tell the customer to open up the Chrome network tab, export the HAR file and send to you. There are lots of HAR readers available or you can set up your own via npm. Problem solved!

hars

6. Examining HTTP traffic

Clicking on a request in the tab opens up a new panel which allows you to examine the request’s details. You can see all the headers; responses, cookies timelines etc. The preview option offers a nice prettified output for response data and if you prefer the plain view; that does exist too.

examine

7. The Filmstrip

The filmstrip generates a frame-by-frame sequence of screenshots showing the page render process during load. It also includes timing information so you can figure out what the bottlenecks are.

For more accurate results; disable the cache and then refresh the page. You can read more about the filmstrip here.

filmstrip

8. Others

  • Disable the cache: Disables the cache to ensure a fresh load
  • Filter: Allows you to type expressions to filter network request rows. There are also out-of-box filters for XHR, JS, etc. I like the websockets (WS) option a lot.
  • Preserve log: Don’t wipe the log on refresh
  • Copy support: Allows you to copy  a request; exposes cURL as a copy option too. Yay for cURL users!

Here are other posts in this series:

Chrome dev tools deep dive : Sources


The Sources tab provides the ‘IDE’ experience. It provides a wide variety of features ranging such as live editing of code via workspaces, debugging and snippets.

Some tips and tricks follow:

1. Pretty print

Want to prettify that minified JS or CSS? The format button works ‘pretty’ well (pun intended).

prettyprint

2. Snippets

Although it is easy to just type away quick implementations in the console tab, the console has poor editing capabilities. A typo or single change necessitates editing the entire typed code.

Another approach involves creating a scratch file and copy-pasting changes to the console for execution. It works better than console editing but still requires some work.

The snippets tab offers the best solution. You edit, save and run code from one spot. Even better still, there is a curated collection of useful snippets; why not stand on the shoulders of giants?

snippets

3. Shortcuts

These are a couple of shortcuts to make debugging much more fun.

  • CTRL + D: Finds the next occurrence of the selected text in that window. Useful during search as an alternative to CTRL + F. Also useful for multi-editing all occurrences simultaneously.
  • CTRL + M: Useful for jumping between matching function braces.
  • CTRL + O: Opens up a file drawer that you can search for specific files using a ‘sublime-like’ fuzzy matching interface. CTRL + P also works.
  • CTRL + SHIFT + O: Opens up a drawer for all the functions in the open file. Useful for jumping between function definitions in a file. CTRL + SHIFT + P also works.
  • CTRL + SHIFT + F: Searches across all files. Exposes regex + case sensitivity options too.
  • CTRL + F: Searches current file
  • CTRL + G: Jump to line number

4. Conditional Breakpoints

Setting a breakpoint is straightforward but what if you only want execution to stop when certain conditions are met? Easy-peasy, right-click on the breakpoint and write an expression. Whenever the expression is truthy; the breakpoint will be activated.

The chrome engine evaluates the expression to determine whether to break or not. What happens if there is a falsy expression that changes the live code?

There! That’s a trick for modifying the live production code during debugging – you can overwrite variables, change functions or even throw Exceptions. Just make sure your expression is falsy (or truthy if you want to break at that point). Want to turn declarations into expressions? Read about the IIFE.

breakpoints

5. Function definition

Do you know you can jump to a function’s definition directly? Before discovering this feature, I used to use invoke toString as a poor substitute for reflection or do a global find.

Chrome has a good solution to this, right-click on the function and jump to its declaration – very useful when navigating around in big huge code bases. It also works for functions that appear in the stack window.

fxnDef

6. XHR Breakpoints

This class of breakpoints allow you to set specific breakpoints based on the endpoint URL which is very useful when debugging code involving endpoints.

Also remember to check the Async option so the call stack includes asynchronous operations e.g. AJAX calls, timeouts.

breakpoints

7. Exceptions

You know there is a bug somewhere but can’t find it. The ‘Pause on exceptions” option is very useful for exactly such scenarios.

Checking the “Pause on caught exceptions” checkbox means that even properly handled exceptions will still trigger a debugger stop. This has been very helpful for tracking down hard-to-find bugs.

exceptions

8. Blackboxing

Black boxed code will be ignored and hidden during debugging. Stepping into functions defined in blackboxed scripts is a no-op. This saves you time from walking into the pits of external library call stacks.

I nearly always blackbox external libraries (e.g. jQuery, AngularJS etc). Otherwise, the debuggger  is activated for exceptions thrown in external code. And as we all know, if there is a bug, it is most likely from our code.

tldr: use the blackbox to hide external scripts.

blackbox

Enjoyed this? Here are some more posts in this series:

  1. Chrome dev tools deep dive : Elements
  2. Chrome dev tools deep dive : Console
  3. Chrome dev tools deep dive : Network

Chrome dev tools deep dive : Console


The console is one of favorite places. The REPL environment is a quick way to validate JavaScript expressions. However, there is a lot more it can do. Read on.

1. $0 – $4 selectors

The last inspected element is always available in the console as $0. $1 points to the next most-recently element and so on. AngularJS developers can leverage this to retrieve the scope of elements by invoking angular.element($0).scope().

Want to inspect the DOM element? Right-click on it and select reveal in ELEMENTS panel.

selectors

2. Monitor

The monitor function is useful for tracing function invocations and parameters. Note that for reference types (e.g. objects), the logs show [Object object] – probably due to calling toString on values. Primitive values are all good.

monitorTurn off tracing with unmonitor or by refreshing the page.

3. MonitorEvents

Allows you to monitor events that happen on particular DOM elements. The first parameter is the DOM element to log event information for while the second parameter is the event (or array of events) to track. If this is undefined, then all events on that object will be logged.

As usual, deregister with unmonitorEvents.

monitorEvents4. Debug

Calling debug on a function would break invocation as soon as that function is invoked. This is very useful for those one-liners or for debugging external libraries. Calling undebug removes the breakpoint.

Note: What if some external library overrides debug? Ideally namespaceing should be used to avoid overriding globals; however, all the command line API functions are accessible via the __commandLineApi object. Try examining the object in your console.

debug

5. Table

console.log works great but makes it difficult to view tabular information. Enter console.table (table)  to the rescue. It accepts property names as extra parameters for filtering out unwanted columns.

table6. Keys and Values

For accessing the keys and values of objects. Combine with table for even more fun!

keys

7. Others

Want to preserve logging even when you reopen the tab? Check that box. Want to target a specific iframe? Select it from the drop down. Want to clear the log? Click the Ø button or use CTRL + L.

MISC

And that wraps it up!

Enjoyed this? Here are some more posts in this series:

  1. Chrome dev tools deep dive : Elements
  2. Chrome dev tools deep dive : Sources
  3. Chrome dev tools deep dive : Network

Chrome dev tools deep dive : Elements


1. Search

CTRL + F allows you to search for strings in the DOM but you can also search using CSS selectors and XPath expressions.

searchElements

2. Color picker

Ever wanted to figure out what colours exist on a web page? Or prefer some other colour format?

Here comes the color picker:

  • Shift click on the color box to change colour formats (e.g. hsl, rgb)
  • Pop up the color picker by clicking on the box

colorPicker

3. Force Element State

You want to inspect the hover style of some DOM element – you can hover over it but you lose the pseudo-state as soon as you exit the element boundaries. A better way is to force the element into the desired state.

There are two ways:

  • Right-click the element
  • Using the styles panel

forceState

4. Drag / Drop elements to new positions

Want to quickly move some element to some new location? So drag drop it. This comes in handy for issues relating to z-indices and ordering.

dragdrop

5. Debug on DOM modifications

This allows you to break whenever a DOM element or its children are modified. Very useful for debugging dynamically-injected DOM elements. There are three possible options:

  • Subtree modifications – DOM hierarchy changes under the chosen node (e.g. child insertions and deletions)
  • Attributes – inline style changes, attribute changes, animations
  • Node removal – when the node is deleted

You can use the DOM breakpoints tab to view all such breakpoints.

When an event triggers the breakpoint, the browser will stop at that point. This is nearly always jQuery; you can then walk up the stack to find the code that triggered the DOM modification.

DOMBreak

6. The Styles tab

Allows you to edit existing CSS styles, add new ones and also view the source. CTRL + Click on a particular rule will open it up in the sources definition. Clicking on the full style too will open up that file.

styles

7. Computed Styles

This shows the active styles applied to an element. It also comes in handy for figuring out what rules come from the browser’s default stylesheet.

To see all the applied rules on an element, check the show all checkbox and it expands. It’s also a very good way to learn more CSS.

computed

Enjoyed this? Here are some more posts in this series:

  1. Chrome dev tools deep dive : Console
  2. Chrome dev tools deep dive : Network
  3. Chrome dev tools deep dive : Sources

The Art of Debugging


I recently wasted a lot of time while attempting to use the amazing Dropzonejs image uploader. I left out a function call in an overloaded function and this broke every subsequent call. More annoyingly, I could not pinpoint the cause of the error as Dropzone was failing silently.

Close to giving up, I decided to give it one more attempt and went to my sandbox – I create a safe area in all my projects for doing ‘risky’ stuff. Starting afresh there, I was amazed to see that everything worked fine. A close comparison of the code samples revealed the bug’s origin – the left out function call. I double-checked to confirm this and that was all about it. Sadly, the documentation does not mention that a failure to call done() in the accept function will break the code silently.

Programmers usually spend a lot of time debugging and it can be a painful experience;  some feel like tearing out their hair in exasperation, smashing their poor computers or even believing that their computers really ‘hate’ them! 🙂

Actually computers do not hate people and the operating system is not conjuring bugs – the most likely reason is buggy code. Here are a couple of tips on debugging; hopefully these will help to reduce time spent, frustration and annoyance levels.

The Inefficient Way of Debugging: Trial-by-Error

Random guesses? Print statements littered around? Fast fixes that ‘appear’ to work? Do these ring a bell? Welcome to the bad bad way of debugging.

This approach is fraught with a gazillion issues. The worst being the potential introduction of new bugs into the codebase. Lucky bug discoveries offer little learning opportunities and it might be difficult to reuse knowledge gained from such fixes in the future.  Also, such run-of-the-mill fixes tend to be inelegant and stand out like a sore thumb when compared to earlier designs and architecture.

The Efficient Ways of Debugging

1. The very first thing is to create a list of the likely causes of the bug; this usually involves thinking deeply about loopholes and design flaws. Studying program error dumps and buggy behaviour might also help.

2. Go through the list while eliminating disproved hypotheses. Once a likely cause is found, a verification needs to be carried out; this can be as simple as proving that the bug appears only when that cause is activated.

3. Don’t just rush to write a fix – I bet you would not want your ‘super-fix’ to mutate into a monster ‘bug’. Think deeply about the bug and what potential ripple effects a fix could have. Also think about how the proposed fix would work, how it blends into the system’s architecture and possible design impacts.

4. Yes, you got it!! Go ahead and squash that bug! Yuck – I dislike bugs.

5. Not finished yet, you need to go through your code armed with your newly acquired bug-terminating powers. Find and ruthlessly sanitize code likely to suffer from such bugs. Rinse and repeat – always leave code in a cleaner state than before.

Extreme Approaches: When the Efficient Ways Fail

You might apply all the above and still be stuck in a rut; this might occur if you have extra-terrestrial bugs (quite popular in multi-threaded environments).

6. Total examination

The brute force approach is bound to work insha Allaah although it involves painstaking work. You go through the code thoroughly (a debugger should come in handy); this might involve examining all execution paths if possible and trying to pinpoint the issue. Hard work…

7. Start afresh

When everything fails, why not throw out the old code and write it again?

Some other tips

6. Very important, set a time limit

Do not spend 3 days hours trying to fix a bug if you can re-implement the same feature in 2 hours. If you are sure you can rewrite a bug-free version of some buggy code, go ahead with a rewrite and spare yourself the trouble. Time counts.

7 Learn to use tools

Debuggers, memory examination tools and profilers. They will help point out to what might be causing the issue. I once had a really really nasty bug while using jQueryUI, the bug only showed up on a particular browser and only when the page was accessed over the local network; otherwise all was fine.

I eventually had to use a profiler after several failed debugging attempts, I  then discovered that a function was being called several hundred times. Bug case solved!

8. Discuss with a buddy

Find a programmer / buddy to discuss with, discussing your ideas with someone will help you to find design gaps and flawed assumptions; you might be surprised that you get the error spot on without any contribution from your buddy.

Now go ahead and eliminate some bugs :).

Taking the PAIN out of coding


Over the years, I have learnt some tricks and picked up some lessons while writing code. Most were learnt the hard way, so I decided to share a couple of tips on how to avoid development pitfalls.

Meticulous Planning and Design

One of the most difficult lessons I learnt in software development was not to rush into code; I used to jump impulsively into software projects and start hacking away at code without planning fully. And as you can bet, the thrill of coding soon evaporated when I got bogged down by messy code. Sadly, many projects of mine met their nemesis this way.

Now, I am just too lazy or maybe too battle-scared to do that; I mostly write out a high level system design document (usually a single page or two) describing all the major features. Next, I run through everything to know that the various components and interfaces are logically valid and try the edge cases. Only when I am satisfied with this do I start writing code.

Alhamdulilah, I think I write cleaner, more modular and better designed code this way. For example, I recently had to extend an experimental framework I wrote a couple of months back; surprisingly I was able to make all major changes in less than two hours. Better still, nothing broke when I ran the framework again!

A dev lead once told me coding is the easiest part of software development… I think I agree with him…

Do it fast and dirty, then clean up

I started using EmberJS last year for a web project. EmberJS is a really cool framework and reduces the amount of boilerplate code you have to write: it’s so powerful that some things seem magical. However, EmberJS has a really steep learning curve.

As usual, I was trying to write perfect code at my first attempt, did I succeed? Your guess is as good as mine. I got so frustrated that I started hating EmberJS, the project and everything remotely related to the project. 🙂

Before giving up, I decided to have one more go at it; my new approach involved ignoring all standards and good practices until I got something to work. And that was it, I soon got ‘something’ that looked like a working web application running. One day, while working on the ‘bad’ code, I had an epiphany. In a flash, I suddenly knew what I was doing wrong. Following standards and practices was relatively easy afterwards.

Looking back, I realize that if I was bent on doing it perfectly at the first go I most probably wouldn’t have gotten to this point. Oh by the way, EmberJS got a new release so my code is obsolete again. 😛

Clean up the code from step 2 above X more times

This is a part of development I don’t think I really like but it is essential for maintenance. You have to go back through the code (yes, your code; you ain’t gonna make life miserable for the developer inheriting your codebase). Refactor all duplicated, extraneous and obscure pieces of code ruthlessly. Most importantly, improve the readability of the code (yes, readability is REALLY important – make it read like a good novel if possible à la Shakespeare or Dickens).

I also keep a running list of all the hacks I make as I go about writing code in step 2; this list comes in handy at this stage and enables me to go straight to the substandard code pieces and fix them up.

Use a consistent coding style

I recently noticed that my coding style was inconsistent across my projects: variables names were either under_score or camelCase while method declarations used brace-on-new-line and brace-on-same-line approaches.

The problem with this approach is that it breaks up my flow of thought and makes speed-reading code difficult. Now, I choose a single style and stick to it throughout a project – any style is fine provided I use it consistently.

Scientific Debugging

I came across the term ‘scientific debugging’ while blog-hopping and it has stuck in my subconsciousness ever since. Identifying bugs can be a challenge: for small projects, I just try to figure out where the bug might be and then check for this. However, this approach does not scale, I wouldn’t randomly guess on a 5000 line project.

Scientific debugging is a systematic process: you make hypotheses about the likely causes of the bug, make a list of places to check and then go through this systematically while eliminating entries. You’ll most probably find the bug with less effort and without running through the entire list.

Project Management

I rarely used to track how much time and effort I put into my projects; I would just code and code and code. Now I know better, I estimate how many hours I can put in before, during and after each project. I try to use Agile (although, I use a simple list + pomodoro too) for project planning, task management and effort estimation. It is now trivial looking up my project status: implemented features, issues list and proposed features.

Testing

I tried my hands at TDD last year and I felt it was just a way of doing too much work for coding. While I might be wrong about TDD, I think it’s essential to have a solid testing process in whatever project you’re doing.

Test, test and test: run the gamut (if possible): unit, integration, functional, stress, regression etc.

Enough said… I have dirty code to polish. If you did find some of the points useful, please share your thoughts and ideas.

Related Posts

  1. Symptoms of Software Rot
  2. So you want to become a better Programmer
  3. Clean code, Dirty code