6

I like the chrome devtools performance tab information, but I want to be able to record the performance profile during an automated functional test. I can execute javascript to get initial load performance data (window.performance), and what I'm looking for is something that like to get Performance profile information. Simple things like the duration of a network calls and profile summary.

Something like:

events =[
  { type: Network request,
    URL: someURL,
    Duration: 431.43 ms,
    Request Method: POST,
    Priority: High,
    Mime Type: application/json,
    Encoded Data: 544 B,
    Decoded Body: 50 B,
    Initiator: JavascriptInsert.js:49
  },
  {
    type: Network request,
    URL: someOtherURL,
    Duration: 81.50 ms,
    Request Method: POST,
    Priority: High,
    Mime Type: text/plain,
    Encoded Data: 260 B,
    Initiator: angular.js:10514  
  }
]

and

summary= {
  Loading: 2.5ms,
  Scripting: 587.6ms,
  Rendering: 77.6ms,
  Painting: 52.5ms,
  Other: 109.3ms,
  Idle: 3040.1ms
}
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Matt Westlake
  • 3,499
  • 7
  • 39
  • 80
  • 1
    These look like good starting points: https://developer.chrome.com/extensions/devtools and https://developer.chrome.com/devtools/docs/integrating – Robert Harvey Nov 15 '17 at 20:37
  • Sure, [`window.performance`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming) is your friend. – Bergi Nov 15 '17 at 20:42
  • @Bergi window.performance tells you the "inital" load of the page. For an Angular / SPA, it doesn't give you any details about any of the Angular service calls. – Matt Westlake Nov 15 '17 at 21:11
  • 2
    @MattWestlake [`performance.getEntriesByType("resource")`](https://developer.mozilla.org/en-US/docs/Web/API/Performance/getEntriesByType) should get you the details you're looking for. I'm not talking about `performance.navigation` or `performance.timing` – Bergi Nov 15 '17 at 21:13
  • @Bergi that wasn't exactly what I was looking for but it's a good start. Now If you know of anyway I can get the breakdown of painting vs downloading etc. that would be everything I need. – Matt Westlake Nov 16 '17 at 20:14
  • @Bergi if you want to post your solution as an answer, I'll accept it – Matt Westlake Jan 31 '18 at 14:19

2 Answers2

3

The durations of network calls and similar details are available in the window.performance interface as well. You can use performance.getEntriesByType("resource") to get the entries for all requests that your page made.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
2

If you are using Selenium, use browser.get_log to obtain all performance logs. My solution uses Python, but it should be similar for any supported language.

First, set up headless Chrome:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = webdriver.ChromeOptions()
chrome_options.set_headless(True)

# for possible entries refer to current implementation at
# https://chromium.googlesource.com/chromium/src/+/master/chrome/test/chromedriver/capabilities.cc#372
perfLogPrefs = {
    "traceCategories": "toplevel,disabled-by-default-devtools.timeline.frame,blink.console,disabled-by-default-devtools.timeline,benchmark"
}
chrome_options.add_experimental_option("perfLoggingPrefs", perfLogPrefs)

desired_capabilities = chrome_options.to_capabilities()
desired_capabilities['loggingPrefs'] = {
    "browser": "ALL",  # use this for console.log output, and obtain later
    "performance": "ALL",
}

browser = webdriver.Chrome(
    chrome_options=chrome_options,
    desired_capabilities=desired_capabilities)

After the tests are finished, obtain logs using get_log and extract the entries:

# based more or less on
# https://sites.google.com/a/chromium.org/chromedriver/logging/performance-log#TOC-Collecting-Log-Entries
import json
with open(base_filename + '.perf.log', 'w') as f:
    logs = browser.get_log('performance')
    f.write('[')
    add_comma = False
    for entry in logs:
        if add_comma:
            f.write(',\n')
        message = json.loads(entry['message'])['message']
        json.dump(message['params'], f)
        add_comma = True
    f.write(']')

The entries are similar to ones described in Trace Event Format documentation. However, I can't figure out the proper file format to load it later in Chrome DevTools Performance tab. I get an error:

Malformed timeline data: TypeError: Cannot read property 'split' of undefined

If someone manages to load that in Chrome, please update my answer (or post answer in How to visualize log of chrome DevTool protocol messages?).

tomasz
  • 403
  • 3
  • 16