How to measure script execution and * parsing * time?

As far as I know, scripts are loaded and executed synchronously in javascript. Therefore, if we write the following code:

<script type='text/javascript'>console.time('core')</script> <script type='text/javascript' src="guicore.js"></script> <script type='text/javascript'>console.timeEnd('core')</script> 

we will see in the console the total time for loading, parsing and executing js. How can we eliminate parsing time? Just add a similar file, but with all the comments. More or less, this method should work.

The problem is that it just doesn't work =)

I optimized this code, reduced the runtime from 90 ms to 25 ms, but I look the same ~ 100 ± 10 ms for Chrome and ~ 160 ± 15 ms for Firefox.

Well, I know that I can use the profiler, but the question is : "how to measure js parsing time correctly" and what I measured by the way. Research.reverse-engineering is a lot of fun, but maybe there is someone who knows this field in depth.

+6
source share
4 answers

Open Chrome and open the developer tools, go to the "Timeline" tab. If you press the record button (filled in the circle, bottom left), then reload the page, it will give you a fairly detailed timeline, divided into certain types of activities ("Send a request", "Analysis", "Rate"), calculated per microsecond.

+2
source

I know this is a kind of old question, but I stumbled upon it, looking for this solution myself. You can use the dev tools in your browser as you see fit, but if you want to do this in code, this is the method I used.

In the scriptLoadParseDuration function below, the URL of the .js file will be indicated, place it in the <script> element and write down the loading / parsing duration to the console.

Keep in mind that this will execute the <script> that you profile in the current DOM context. So in the example below: jQuery is still available in the global scope, although the script has been removed. The script can be extended to do all this in an <iframe> to isolate it.

 function scriptLoadParseDuration(url) { var start; var script = document.createElement('script'); // <script> must be attached to the document to actually load the file document.querySelector('html').appendChild(script); // Calculate load/parse duration once script has loaded script.addEventListener('load', function scriptLoad() { // Calculate load/parse duration console.log('Duration: ' + (Date.now() - start) + 'ms'); // Remove <script> from document script.parentElement.removeChild(script); }, false); // Get current time in milliseconds start = Date.now(); // Setting the `src` starts the loading. Math.random is used to make sure it is an uncached request script.src = url + '?' + Math.floor(Math.random() * 9e9); } var url = 'https://code.jquery.com/jquery-3.0.0.min.js'; scriptLoadParseDuration(url); 

Here is an example showing that jQuery is still in the global scope after removing <script> .

 function scriptLoadParseDuration(url) { var start; var script = document.createElement('script'); console.log('`jQuery` before attaching: ' + typeof jQuery); // <script> must be attached to the document to actually load the file document.querySelector('html').appendChild(script); // Calculate load/parse duration once script has loaded script.addEventListener('load', function scriptLoad() { // Calculate load/parse duration console.log('Duration: ' + (Date.now() - start) + 'ms'); console.log('`jQuery` once attached: ' + typeof jQuery); // Remove <script> from document script.parentElement.removeChild(script); console.log('`jQuery` after detach: ' + typeof jQuery); }, false); // Get current time in milliseconds start = Date.now(); // Setting the `src` starts the loading. Math.random is used to make sure it is an uncached request script.src = url + '?' + Math.floor(Math.random() * 9e9); } var url = 'https://code.jquery.com/jquery-3.0.0.min.js'; scriptLoadParseDuration(url); 
+3
source

You cannot accurately measure script syntax time regardless of runtime using only the web API. Different browsers have different strategies when they are analyzed, and some of them will be analyzed sequentially as the script runs or even "partially parsed" in cases where it is assumed that the code block is unlikely to be executed immediately (for example, the function is not IIFE , see some details in README optimize-js ).

Using separate <script> tags is the most accurate way to at least capture both parsing and runtime. The only change I would make for your snippet is this:

 <script> performance.mark('start'); </script> <script src="myscript.js"></script> <script> performance.mark('end'); performance.measure('total', 'start', 'end'); </script> 

Pay attention to the Timing API’s high-precision user interface, which, as an added bonus, displays visualization in Chrome / Edge / IE developer tools (and tools like Windows Performance Analyzer and WebPageTest, if you're so inclined).

Technically, the 3rd <script> not needed, as you can just add a label / measure at the end of the second script. But the first <script> is definitely needed to capture the entire parsing time. You can check in dev tools that labels / measures cover all initial parsing and runtime.

+2
source

A very old question with a relatively new answer.

Date.now() returns a timestamp accurate to milliseconds. For an application running on 60FPS, it must update the frame every 16 ms. Our millisecond counter may not be accurate enough.

Introducing the Performace API in modern JS browsers, this allows the use of floating point timestamps accurate to the microsecond.

Instead of Date.now() use window.performance.now() for measurements, there is a good guide on using the Performance API for HTML5Rocks .

0
source

All Articles