Home Java Chrome DevTools Superpowers

Chrome DevTools Superpowers

by admin

Chrome DevTools Superpowers
I work on the Online team.We do web version 2GIS directory. This is a long-lived, actively developing project that uses JavaScript as the main language on both the client and the server.
Analysis and debugging tools are an important part of the application. Popular JavaScript frameworks usually have their own toolset, tailored to a specific ideology. Our situation is complicated by the fact that under the hood of Online, we have our own framework, Slot, which is also under active development.
In this article, I’ll cover how we use standard browser-based developer tools to effectively debug and explore. These recipes are primarily aimed at exploring the application from outside to inside, so they will work for any project.

Problem

The dynamics of development do not allow team members to fully immerse themselves in the details of each other’s tasks. The context of a particular component quickly slips away; returning to a piece of code a month later may not recognize it. In addition, the team is constantly replenished with new recruits.
In such a situation, it is necessary to quickly regain an understanding of the logic of what is happening in the code. Given the variability of the project, this task is more of an exploratory one. Once you understand the general principles of operation, you still become a discoverer of specific aspects of the implementation every time.

Debug

The price for speed of development is the presence of bugs. This class of tasks requires a quick response, and therefore an input into the context of what’s going on.

Incorrect output result

Often, the bug is triggered by some unexpected external event: an unexpected DOM-tree change, an asynchronous request with invalid data, etc. In this case it’s convenient to consider the application code as a black box, the input of which is a use case and the output is the result of a bug.
In addition to the standard breakpoints on a line of code, DevTools (here and below we are talking about the Google Chrome browser tools) has an option to stop execution on a certain event.
The DOM Breakpoint is set to a tree node in the inspector. You can stop when you delete that element, change its subtree, or change its attributes (recall that style and class are also attributes).
Chrome DevTools Superpowers
XHR Breakpoint is set to the entire document and allows you to find the line of code from which a pattern-sensitive request is sent.
Chrome DevTools Superpowers
These breakpoints work well in conjunction with the asynchronous call stack mode ( Async call stack ). It doesn’t break on asynchronous operations and gives you the ability to go from the setTimeout handler to the code that set it, for example. This way you can look much further back in history and find the roots of even complex bugs.
Chrome DevTools Superpowers
Example scenario :
1. An unexpected change occurs in the DOM tree.
2. The behavior is reproduced.
3. Set the right type of DOM breakpoint.
4. Turn on Async mode in the debugger.
5. Replay the bug and travel through the call history until we find the root of the problem.

Incorrect internal representation

Not all bugs are visible to the naked eye. During execution, only the internal state can change, which will affect the behavior of the system as a whole later on. You can use your imagination to catch invalid changes of this state.
Suppose the state is a global object. Then the following code can be used to track it :

var watchMe = {};Object.observe(watchMe, function() {debugger;});watchMe.foo = 'bar'; // Execution will stop

Using advanced console features (explained in detail later), you can add logging of changes without having to stop execution at every sneeze.

var watchMe = {};Object.observe(watchMe, function(options) {options.forEach(function(option) {var groupName = option.name + ' changed';console.groupCollapsed(groupName);console.log('Old value: ', option.oldValue);console.log('New value: ', option.object[option.name]);console.groupEnd(groupName);});});

This example will output to the Chrome console a compact group of logs when the object properties change. There is a lot more code now, and it’s not convenient to write it every time by memory. So you can save it as a snippet and run it as needed.
Chrome DevTools Superpowers
Of course, this code will have to be adapted to the project and the task each time. Rarely is all state stored in one global object. Sometimes you will have to edit the source code to fit into the execution context. But the benefits of this approach are worth the effort.
Use Scenario :
1. If the observed object is global, just run a snippet on it.
2. If the object is only available in the local scope, add the required code to the application while debugging.

Research

A programmer’s job is not limited to fixing bugs. Understanding how the application as a whole works in complex scenarios is important for adding new functionality.

Console as a source of knowledge

The Console in DevTools is more than just a way to quickly run a small script. It has a powerful API that implements convenient functions and links to other DevTools that are not available in the language.
For example, to display a DOM element in the console, you don’t need to use complex selectors. Instead, the stack of elements selected in the inspector is implemented within the console. It is accessed via $N command, where N is the indent from the end of the stack. Thus, accessing $0 in the console will return the last DOM node selected in the inspector, $1 will return the penultimate node, and so on.
Use this feature in conjunction with functions over DOM nodes:
– monitorEvents(object) – monitors element events;
– getEventListeners(object) – displays a list of element event handlers in the console, from which you can jump to the function code.
A simple scenario emerges :
1. Selecting elements in the inspector.
2. Call the desired command in the console and pass $0 as an argument.
3. We enjoy it like children.
Many developers remove console.log() from their code as soon as debugging is finished. But some key functionality requires constant logging. As a result, every developer writes debugging code first and then deletes it.
There is a way to prevent output to the console in production and at the same time conveniently log what’s going on in the development phase. We use UglifyJS to compress JavaScript, and it has an option to override global variable values.

// UglifyJS config.global_defs: {DEBUG: false}// Somewhere in the application codeif (DEBUG) {console.log('Something important');}

In the example above, DEBUG will not just be false after assembly. UglifyJS will realize that the condition will never be satisfied and simply remove it from the code.
You can now use the more sophisticated console output capabilities for different data types. In the state debugging example, the output will be more compact due to console.groupCollapsed. This is used in our project to track URL changes:
Chrome DevTools Superpowers
For arrays, console.table is good. You can find a complete list of output design options here

A bird’s eye view

The built-in tool for recording browser-level events is Timeline. Until recently, it could be used to analyze application performance. With the advent of experimental features, its capabilities have increased significantly.
One of the long awaited features is the display of call stacks directly in the event chart. This essentially combines the classic Timeline with the CPU Profiler report. This diagram gives you an understanding of how the application works dynamically: call sequences, total function execution time, JavaScript interaction points with the DOM. Even when there is no need to optimize, it can be used to study the inner workings of a project.
Chrome DevTools Superpowers
If you are interested in a particular piece of application logic, and there are too many events in the report, you can use console.time In addition to timing, this method adds a label to the Timeline.
Chrome DevTools Superpowers
Example of use :
1. Writing a custom script.
Examine the call stacks.
3. If necessary, jump to a specific line of code directly from the Timeline.
4. If there is too much information, wrap the code of interest in console.time and console.timeEnd.
5. Repeat until we fully understand the logic of what’s going on.

Conclusion

When working on large projects, it makes sense to invest time in development usability. Hours spent learning and adapting tools saves debugging days and gives a better understanding of how the project works.
This article describes only a small part of features of Chrome Developer Tools. As we work on 2GIS Online, we have more exotic tasks that require constant exploration of new development tools. For more on these tools, as well as on the performance of JavaScript applications, I told at the FrontTalks conference.

You may also like