Browser Performance Testing using k6
Tags: performance, testing, go, tutorial
Published: 2023-10-20 13:26:12

<!-- wp:paragraph -->
<p>In this blog post you will learn how to get started with browser performance testing using k6. Client-side performance is paramount to validate the performance of your application along with the network load i.e. protocol load e.g. APIs. Not many tools are sophisticated when it comes to measuring end-to-end performance. Opentext LoadRunner TruClient protocol is one of the tool at its best when it comes to measuring front-end performance. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>JMeter w/ Selenium can be used to measure the browser performance. But the maintenance is nightmare and too flaky. If you do not want to use any tool, you can leverage the <strong>Chromium Developer Protocol</strong>.</p>
<!-- /wp:paragraph -->

<!-- wp:generateblocks/headline {"uniqueId":"064bb512","blockVersion":3} -->
<h2 class="gb-headline gb-headline-064bb512 gb-headline-text">What is Chromium Developer Protocol?</h2>
<!-- /wp:generateblocks/headline -->

<!-- wp:paragraph -->
<p>It is often referred to as the Chrome DevTools Protocol (CDP), is a set of APIs and tools that allow developers to interact with and inspect web pages in the Chromium-based web browsers like Google Chrome, Microsoft Edge, and others. It provides a way to access and control various aspects of web pages, such as inspecting the Document Object Model (DOM), manipulating CSS, monitoring network activity, debugging JavaScript, and much more.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Getting Started with k6 browser</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>k6 is getting traction among developers and performance engineers. After getting acquired to Grafana, there are numerous improvements in the k6 ecosystem. I have already published a complete series on k6, please check it out if you are new to k6.</p>
<!-- /wp:paragraph -->

<!-- wp:embed {"url":"https://www.youtube.com/playlist?list=PLJ9A48W0kpRJKmVeurt7ltKfrOdr8ZBdt","type":"video","providerNameSlug":"youtube","responsive":true,"className":"wp-embed-aspect-16-9 wp-has-aspect-ratio"} -->
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
https://www.youtube.com/playlist?list=PLJ9A48W0kpRJKmVeurt7ltKfrOdr8ZBdt
</div><figcaption class="wp-element-caption">k6 Series</figcaption></figure>
<!-- /wp:embed -->

<!-- wp:paragraph -->
<p>No more building xk6 browser from the binaries. The latest version of k6 is now bundled with the browser capability to test the front-end performance.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The following are the prerequisites to get started with k6 browser:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li>the latest version of k6 </li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Chrome browser in your local</li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>You can install k6 in Windows, Linux, and macOS. Here is the command to install k6 in Mac.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>brew install k6</code></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To verify the installation, use <code>k6 version</code>.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":17649,"width":"466px","height":"auto","aspectRatio":"7.639344262295082","sizeSlug":"full","linkDestination":"media","className":"is-style-default"} -->
<figure class="wp-block-image aligncenter size-full is-resized is-style-default"><a href="https://qainsights.com/wp-content/uploads/2023/10/image.png"><img src="https://qainsights.com/wp-content/uploads/2023/10/image.png" alt="k6 version - Browser Performance Testing using k6" class="wp-image-17649" style="aspect-ratio:7.639344262295082;width:466px;height:auto"/></a></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>k6 browser is built on top of Playwright API. Playwright is an open-source automation library for browsers that allows developers and testers to automate tasks and interactions with web pages in Chromium, Firefox, and WebKit-based browsers. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>It provides a JavaScript API that makes it easy to write browser automation scripts and run them across different browser engines. Playwright is developed by Microsoft and is designed to be a more powerful and user-friendly alternative to other browser automation libraries like Puppeteer.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Hello, Browser in k6 browser</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Copy and paste the below code and save it as <code>hello-browser.js</code>.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>import { browser } from 'k6/experimental/browser';

export const options = {
  scenarios: {
    ui: {
      executor: 'shared-iterations',
      options: {
        browser: {
          type: 'chromium',
        },
      },
    },
  },
  thresholds: {
    checks: &#91;"rate==1.0"]
  }
}

export default async function () {
  const page = browser.newPage();

  try {
    await page.goto('https://example.com');    
  } finally {
    page.close();
  }
}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>To run the script, <code>k6 run hello-browser.js</code></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Here is the output.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":17652,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://qainsights.com/wp-content/uploads/2023/10/image-1.png"><img src="https://qainsights.com/wp-content/uploads/2023/10/image-1-1024x591.png" alt="k6 output" class="wp-image-17652"/></a></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Let us break down the code one by one. </p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li>Import the <code>browser</code> object from the <code>k6/experimental/browser</code> module. This object is used to interact with web pages in your performance test.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Define the <code>options</code> object, which specifies the configuration for the k6 test.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>scenarios</code>: This section defines different test scenarios. In this case, there is only one scenario named "ui."<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>executor</code>: It specifies the execution mode for the scenario, which is set to "shared-iterations." In this mode, virtual users share a fixed number of iterations.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>options</code>: Further options for the scenario, including the type of browser to be used. Here, it's set to "chromium," indicating the Chromium browser.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>thresholds</code>: This section defines the criteria for passing or failing the test.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>checks</code>: It specifies a threshold for a check named "rate," which is set to 1.0. This means that all checks in the test should have a success rate of 100% for the test to pass.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Export a default asynchronous function. This function will be executed by k6 during the performance test.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Inside the function, a new page is created using <code>browser.newPage()</code>. This represents a virtual user's interaction with a web page.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Within a <code>try</code> block, the virtual user navigates to the URL '<a href="https://example.com/">https://example.com</a>' using <code>page.goto()</code>. This simulates a user visiting the specified web page.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>In the <code>finally</code> block, the <code>page</code> is closed using <code>page.close()</code>. This ensures that resources are properly cleaned up after the virtual user has finished interacting with the web page.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Here is the output breakdown.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":17654,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://qainsights.com/wp-content/uploads/2023/10/image-2.png"><img src="https://qainsights.com/wp-content/uploads/2023/10/image-2-1024x281.png" alt="" class="wp-image-17654"/></a></figure>
<!-- /wp:image -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li><strong>browser_data_received</strong>: This section shows statistics related to data received by the browser during the test.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>1.6 kB</code>: The total amount of data received by the browser during the test.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>1.6 kB/s</code>: The data receiving rate, indicating the rate of data transfer per second.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>browser_data_sent</strong>: This section shows statistics related to data sent by the browser during the test.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>343 B</code>: The total amount of data sent by the browser during the test.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>331 B/s</code>: The data sending rate, indicating the rate of data transfer per second.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>browser_http_req_duration</strong>: These statistics provide information about the duration of HTTP requests made by the browser.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>avg=422.89ms</code>: The average duration of HTTP requests in milliseconds.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>min=422.89ms</code>: The shortest (minimum) request duration.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>med=422.89ms</code>: The median (middle) request duration.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>max=422.89ms</code>: The longest (maximum) request duration.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>p(90)=422.89ms</code>: The 90th percentile of request durations.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>p(95)=422.89ms</code>: The 95th percentile of request durations.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>browser_http_req_failed</strong>: This section provides information about failed HTTP requests made by the browser.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>0.00%</code>: The percentage of HTTP requests that failed.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>? 0</code>: The number of successful requests (0).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>? 1</code>: The number of failed requests (1).</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>browser_web_vital_cls, browser_web_vital_fcp, browser_web_vital_lcp, browser_web_vital_ttfb</strong>: These sections report various web vital metrics that are important for measuring web page performance.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>These sections include metrics such as average, minimum, median, maximum, and percentiles for Core Web Vitals like Cumulative Layout Shift (CLS), First Contentful Paint (FCP), Largest Contentful Paint (LCP), and Time to First Byte (TTFB).</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>checks</strong>: This section reports on the success or failure of checks performed during the test.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>0.00%</code>: The percentage of checks that failed.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>? 0</code>: The number of successful checks (0).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>? 0</code>: The number of failed checks (0).</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>data_received, data_sent</strong>: These sections show statistics related to data received and sent during the test. In this case, no data was sent or received.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>iteration_duration</strong>: These statistics provide information about the duration of iterations (test cycles).<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>avg=678.25ms</code>: The average duration of iterations in milliseconds.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>min=678.25ms</code>: The shortest (minimum) iteration duration.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>med=678.25ms</code>: The median (middle) iteration duration.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>max=678.25ms</code>: The longest (maximum) iteration duration.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>p(90)=678.25ms</code>: The 90th percentile of iteration durations.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>p(95)=678.25ms</code>: The 95th percentile of iteration durations.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>iterations</strong>: This section provides information about the number of iterations (test cycles) completed during the test.<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>1</code>: The total number of iterations.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>0.96512/s</code>: The rate at which iterations were executed per second.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list --></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>vus</strong>: This section shows statistics related to the virtual users (VUs) used in the test.</li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>1</code>: The current number of virtual users.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>min=1</code>: The minimum number of virtual users.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>max=1</code>: The maximum number of virtual users.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:list {"ordered":true,"start":11} -->
<ol start="11"><!-- wp:list-item -->
<li><strong>vus_max</strong>: This section provides information about the maximum number of virtual users.</li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><code>1</code>: The maximum number of virtual users during the test.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>min=1</code>: The minimum number of virtual users during the test.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><code>max=1</code>: The maximum number of virtual users during the test.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Headless Mode</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>By default, k6 runs the test in headless mode. To turn off it, issue <code>K6_BROWSER_HEADLESS=false k6 run &lt;your-script&gt;.js</code> </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This will launch the Chromium browser and perform the scripted actions.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You can also interact with the application using <code>Locator</code> object. k6 also supports Asynchronous operations.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Recommended Way to Test</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>It is always ideal to test both the APIs and the front-end simultaneously to get the real simulation of production. You can create both the tests in one script, or you can write two different scripts and run it simultaneously. </p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In conclusion, browser performance testing with k6 is a valuable addition to your toolkit for assessing and optimizing the performance of web applications. With its user-friendly approach, bundled browser capability, and the power of the Chromium Developer Protocol, k6 simplifies the process of evaluating client-side performance and empowers you to build faster, more efficient, and more reliable web applications. It's a powerful tool that every performance engineer and developer should consider in their testing repertoire.</p>
<!-- /wp:paragraph -->