function PerformanceTestTrait::processChromeDriverPerformanceLogs

Same name and namespace in other branches
  1. 10 core/tests/Drupal/Tests/PerformanceTestTrait.php \Drupal\Tests\PerformanceTestTrait::processChromeDriverPerformanceLogs()

Gets the chromedriver performance log and extracts metrics from it.

The performance log is cumulative, and is emptied each time it is collected. If the log grows to the point it will overflow, it may also be emptied resulting in lost messages. There is no specific LargestContentfulPaint event, instead there are largestContentfulPaint::Candidate events which may be superseded by later events. From manual testing none of the core pages result in more than two largestContentfulPaint::Candidate events, so we keep looking until either two have been sent, or until 30 seconds has passed.

@todo https://www.drupal.org/project/drupal/issues/3379757

Parameters

string|null $service_name: An optional human readable identifier so that traces can be grouped together.

Return value

\Drupal\Tests\PerformanceData An instance of the performance data value object.

1 call to PerformanceTestTrait::processChromeDriverPerformanceLogs()
PerformanceTestTrait::collectPerformanceData in core/tests/Drupal/Tests/PerformanceTestTrait.php
Executes a callable and collects performance data.

File

core/tests/Drupal/Tests/PerformanceTestTrait.php, line 291

Class

PerformanceTestTrait
Provides various methods to aid in collecting performance data during tests.

Namespace

Drupal\Tests

Code

protected function processChromeDriverPerformanceLogs(?string $service_name) : PerformanceData {
    $attempts = 0;
    $lcp_count = 0;
    $request_count = 0;
    $response_count = 0;
    $messages = [];
    $session = $this->getSession();
    while ($attempts <= 30) {
        $attempts++;
        $performance_log = $session->getDriver()
            ->getWebDriverSession()
            ->log('performance');
        foreach ($performance_log as $entry) {
            $decoded = json_decode($entry['message'], TRUE);
            $message = $decoded['message'];
            if ($message['method'] === 'Tracing.dataCollected' && $message['params']['name'] === 'largestContentfulPaint::Candidate') {
                $lcp_count++;
            }
            if ($message['method'] === 'Network.requestWillBeSent') {
                $request_count++;
            }
            if ($message['method'] === 'Network.responseReceived') {
                $response_count++;
            }
            $messages[] = $message;
        }
        // Performance entries are logged indeterminately since page loading
        // varies by request. Chrome returns a response as soon as the HTML page
        // has returned to the browser, but CSS, JavaScript, image and AJAX
        // requests may all occur after this, and in turn trigger further requests
        // and page rendering events, and there is no performance log event for
        // the page loading 'finishing' since this is cannot be detected as such.
        // Therefore, continue collecting performance data until all of the
        // following are true, or until 30 seconds has passed:
        // - a largestContentfulPaint::candidate event has been fired
        // - all network requests have received a response
        // - no new performance log events have been recorded since the last
        //   iteration.
        if ($lcp_count && empty($performance_log) && $request_count === $response_count) {
            break;
        }
        sleep(1);
    }
    $performance_data = new PerformanceData();
    $this->collectNetworkData($messages, $performance_data);
    if (isset($service_name)) {
        $this->openTelemetryTracing($messages, $service_name);
    }
    return $performance_data;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.