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:

Advertisements

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

Tips for printing from web applications


Web developers usually have to format user content for printing; for example, accountants might want physical copies of online ledgers while teachers might need lecture note printouts.

The challenge lies in getting consistent print output across a range of browsers and their never-ending stream of subtle nuances.

This post approaches printing from three viewpoints: tooling, JavaScript and CSS. It also describes the pitfalls and quirks to watch out for when printing across the big 5 browser platforms (i.e. Chrome, Edge, Firefox, Internet Explorer and Safari).

1. Tooling

Quick question – what does this page look like when printed?

Did you do a CTRL + P to figure that out? Print previews work excellently if you want to ‘see’ what a page looks like when printed. But what if you wanted to interact with the page and change it? Say you wanted to toy with the CSS or even debug JavaScript. Clearly, the preview option comes short; even if it doesn’t, going to preview mode every time you make changes is not fun.

Good news, Chrome provides print emulation tooling which allows you to style a page for printing. To activate the print emulation mode, do the following:

  • Press F12 to bring up the Chrome dev tools
  • Press Esc to bring up the extra tabs
  • Select the Emulation tab
  • Select the media option
  • Check the CSS media check box
  • Select print (or any other media target you desire)

chrome tools

The Chrome emulation mode should reveal the major print issues however, you should sanity check other browsers’ in print preview mode. This should catch the few remaining quirks, things like forgetting –webkit prefixes for Safari.

JavaScript

Media Listeners

The big 5 browsers all have media listener support, this allows detecting media properties such as orientation, resolution and viewport dimensions. For example, the snippet below will be triggered when the browser width falls below 960px.

var widthHandler = function(mql) {
    if(mql.matches) {
        console.log('Viewport width is <= 960px');
    } else {
        console.log('Viewport width is > 960px');
    }
}

var mql = window.matchMedia('(width: 960px)');
mql.addListener(widthHandler);

Chrome and Safari

The interesting aspect is the print media query option; Chrome and Safari can detect print events via these listeners. Unfortunately, IE, FF and Edge, even though they support other media queries, do not offer print media support.

Safari tends to fire the media listener event ‘after’ the print dialog appears. This effectively renders any desired print pre-processing useless – what’s the use if the print dialog is already visible?

Chrome offers the best support, modification of print options (e.g. paper type or layout) will still trigger appropriate print events; this is very useful if you want to restyle your page dynamically based on print options. Alas, only Chrome gives this option.

Here is how you attach handlers for the Chrome/Safari scenario.

var printHandler = function(mql) {
    if(mql.matches) {
        console.log('Print');
    } else {
        console.log('Not print');
    }
};

var mql = window.matchMedia('print');
mql.addListener(printHandler);

When you are all done, remember to clean things up by calling mql.removeListener(printHandler).

IE, FF and Edge

These 3 browsers expose the onbeforeprint and onafterprint events.

window.onbeforeprint = function () {
    console.log('Print started');
};

window.onafterprint = function () {
    console.log('PRINT DONE');
};

You would expect the onafterprint handler to be called immediately after the print dialog is disposed right? Nope, it is nearly always invoked immediately after onbeforeprint. Invocation order: onbeforeprint -> onafterprint -> print dialog opens.

Print events have a mind of their own…

Cross-browser printing

Merging both approaches gives a combination that should work well in most scenarios. See below:

function beforePrint () {
    console.log('before print');
}
function afterPrint() {
    console.log('after print');
}
window.onbeforeprint = beforePrint;
window.onafterprint = afterPrint;

var printHandler = function(mql) {
    if(mql.matches) {
        beforePrint();
    } else {
       afterPrint();
    }
};

var mql = window.matchMedia('print');
mql.addListener(printHandler);

CSS media

CSS media queries provide very powerful print styling capabilities. You should handle most of the styling issues with CSS and wrap up the thornier edge cases with JavaScript.

The introduction of the print media block allows you to control and override existing DOM styles. This makes it possible to hide certain elements on print, elements to new positions or even change the entire page’s layout.

@media print {
    body {
        width: 960px !important;
    }
}

Now in print mode, your page will have a width of 960px. Go ahead, go toy and play with this.

Note that you might need to add !important to make sure print styling overrides existing styling. For inline styles, !important might not work however increasing the specificity of the CSS selectors would eventually work.

Happy printing!

Related

Detecting Print Requests with JavaScript

MDN documentation on CSS Media

How to set up a print style sheet

7 Cool tricks with Chrome DevTools


1. $_

$_ re-evaluates the last expression and is similar to the ‘_’ command in python’s REPL. However _ prints the last ‘non-None’ value while $_ prints the value of the last evaluated expression even if it is undefined.

$_

2. $() and $$() selectors

$() selects the first matching DOM element while $$() selects all matching DOM elements. Quite useful if jQuery is missing.

$$ selectors

Tip: $() and $$() are aliases for document.querySelector() and document.querySelectorAll() respectively; if any of them gets overridden, simply re-assign the function references. You can even create your own shortcuts!

$ = document.querySelector;
slct = document.querySelector;

3. Console.table

Very good for generating a nice view of an object in the console. Saves you from having to click about. It works with non-uniform object types too.

console.table

4. DOM Element event listeners

There are two ways to do this:

1. Select an element in the elements view and then go to the event listeners tab in the elements view.

2. Select the element in the console and call getEventListeners on the object

eventListeners2

5. $0 – $4

This  refer to the first through fifth last selected items. These shortcuts are handy references to pre-selected DOM elements.

$0

6. Drag Drop in Elements View

It is possible to re-order the DOM layout structure using drag drop gestures in the elements view. No need to get your hands dirty anymore – just drag/drop.

7. copy

Useful for directly copying JavaScript objects to the clipboard. Call copy on the object (as shown below) and paste wherever you want it.

copy

And that’s it! Hope you learnt one or two new tricks to enhance your development.