Web Performance with SiteSpeed.io
Published: 2020-07-24 07:06:06

In this post we will cover basic concepts for Web Performance and with what frameworks we can measure it in modern web applications. 

## Why should we care for Web Performance??

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zxuzx8it0yxjk7l7zbs0.png)

Two words you often hear together are mobile and site speed. And that’s not without reason because these two go hand in hand. Mobile-friendliness and site speed are some of the most pressing matters we have to deal with. 


Measuring page speed has always been something of a dark art. The site speed tools we use today are fairly adequate, but with the new Web Vitals metrics Google is trying to come at it from a different, more realistic angle, taking page experience into account.

The first thing to understand is that there is no single metric or measurement for ‘speed’. There’s no simple number which you can use to measure how quickly your pages load.

Think about what happens when you load a website. There are lots of different stages and many different parts which can be measured. If the network connection is slow, but the images load quickly, how ‘fast’ is the site? What about the other way around?

Even if you try to simplify all of this to something like “the time it takes until it’s completely loaded“, it’s still tricky to give that a useful number.

For example, a page which takes longer to ‘finish loading’ may provide a functional ‘lightweight’ version while the full page is still downloading in the background. Is that ‘faster’ or ‘slower’ than a website which loads faster, but which I can’t use until it’s finished loading?

### Browser Stuff

This stage is where the page needs to be constructed, laid out, colored in, and displayed. The way in which images load, in which JavaScript and CSS are processed, and every individual HTML tag on your page affects how quickly things load.

We can monitor some of this from the ‘outside-in’ with tools which scan the website and measure how it loads. We recommend using multiple tools, as they measure things differently, and are useful for different assessments. For example:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5chb0y4zcg6uzhbnjsfb.jpg)

How to diagnose speed issues through the waterfall charts:

1.**Look for red text** 

If you have 400 or 500 error response codes for resources in your waterfall chart, you may see the name of the resource marked in red text. This indicates an error retrieving that resource. The below example shows a 500 Internal Server Error on a waterfall chart, but you could see any individual request fail within the makeup of a page.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vj1ngwmas3598nf8w24w.jpg)


2.**Look for long bars**

In the following example, the long bar represents an exceptionally long time for a DNS lookup to find a custom font on a site.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rpycmcr6wp2842v05hac.jpg)

3.**Look for big gaps between requests**

As demonstrated in the following example, these gaps represent times when no requests happened, such as when JavaScript was executing or the browser was processing.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ewfkmure9fzoi9j1500g.png)

### Universal Metrics

Despite all of these moving parts, there are a few universal metrics which make sense for all sites to measure, and optimize for. These are:

* Time until first byte, which is how long it takes until the server responds with some information. Even if your front-end is blazing fast, this will hold you up. Measure with Query Monitor or [NewRelic](https://newrelic.com/).

* Time until first contentful (and meaningful) paint, which is how long it takes for key visual content (e.g., a hero image or a page heading) to appear on the screen. Measure with [Lighthouse for Chrome](https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk?hl=en).

* Time until interactive, which is how long it takes for the experience to be visible, and react to my input. Measure with [Lighthouse for Chrome](https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk?hl=en).

These are much more sophisticated metrics than “how long did it take to load”, and, perhaps more importantly, have a user-centric focus. Improving these metrics should correlate directly with user satisfaction, which is super-important for [SEO](https://yoast.com/how-site-speed-influences-seo/)


## Measuring Web Performance with SiteSpeed.io

When it comes to more modern tools SiteSpeed.io covers multiple metrics and has the advantage to integrate into a more modern DevOps Pipeline.  

Sitespeed.io is a set of [Open Source tools](https://www.sitespeed.io/documentation/) that makes it easy to monitor and measure the performance of your web site.

**_Built-in Simulation Features_**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0f1wbd32uis1smiohnfe.png)

* Browser Support
* Mobile 
* Simulation
  Real Device (Android for now)
* Bandwidth Simulation
* Continuous Integration
* Selenium Integration
* Crawling

**_Third Party Tools Integration_**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vbyhbov8sz5yv1349vxm.png)

* Slack Integration
* Google Page Speed Insight Integration
* WebpageTest Integration
* Various Plugins
* Custom Metrics

**_Reports_**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wks8pm7klexrfglbfrew.png)

* Grafana Dashboards
* Coach
* Unitary Report
* Historical Dashboard

### SiteSpeed.io in CI/CD

To run SiteSpeed.io its pretty simple especially if you use the [Docker Image](https://hub.docker.com/r/sitespeedio/sitespeed.io/)



``` 
docker run --shm-size=1g --userns=host --rm -v ${WORKSPACE}:/sitespeed.io sitespeedio/sitespeed.io:13.3.2-plus1 --outputFolder output/report --axe.enable true  --video false --influxdb.host ... --influxdb.port .... --influxdb.database ... --influxdb.username ... --influxdb.password ... http://www.google.com --slack.hookUrl ...
```

In the above example we have various arguments passing summarized:
* **--outputFolder**: The folder relative to workspace to store the results
* **--axe.enable**: Enable support for accessibility scores
* **--video**: Enable or disable video support
* **--influxdb.host**: InfluxDB host to store metrics as time series data
* **--influxdb.port**: InfluxDB port 
* **--influxdb.database**: InfluxDB database name to store the metrics
* **--slack.hookUrl**: Enable WebHooks to Slack channels and update the channel with performance output

Of course this is just an example if you want to add more capabilities in your docker image command visit [SiteSpeed Configurations](https://www.sitespeed.io/documentation/sitespeed.io/configuration/)

The output after scanning will produce multiple html reports combined in one dashboard providing scores and individual metrics per pages

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/v5c0j9v0xjjeag5nyu9q.jpg)

When you have to deal with scanning the application when registration forms or login forms are providing more data for the user then using only the docker image to scan will not be sufficient. No problem ... Selenium is our tool.

You can write a Selenium async script(EventCloud2.js) and pass it to docker image:
```
module.exports = async function(context, command) {
       // Use case #1: Open EventCloud Page
   await command.measure.start('http://eventcloud.aspnetboilerplate.com/', 'Load EventCloud');  
    try
   {
       // Use case #2: Open Register Page
       await command.navigate('http://eventcloud.aspnetboilerplate.com/account/login');
       await command.measure.start('Open_Register');
       await command.click.byClassName('btn btn-block bg-deep-purple waves-effect');
       context.log.info('Register page opened..');
       await command.measure.stop();

       // Use case #3: Login Page.
       await command.navigate('http://eventcloud.aspnetboilerplate.com/account/login');
       await command.wait.byTime(5000);
       await command.addText.byXpath('john', '//input[@name="userNameOrEmailAddress"]');
       await command.addText.byXpath('123qwe', '//input[@name="password"]');

       await command.measure.start('Login');
       await command.click.byIdAndWait('LoginButton');
       context.log.info('User logged In..');

       return command.measure.stop();
   }
   catch(e) {}
};
```

Then just execute the following command:

```
docker run --shm-size=1g --userns=host --rm -v ${WORKSPACE}:/sitespeed.io sitespeedio/sitespeed.io:13.3.2-plus1 --outputFolder output/report --axe.enable true  --video false --influxdb.host ... --influxdb.port .... --influxdb.database ... --influxdb.username ... --influxdb.password ... EventCloud2.js --slack.hookUrl ...
```

#### Grafana Integration

In order to display the metrics, we need to create the SiteSpeed dashboard. For this specific task, we are going to import a JSON script by following these steps:

• Click the “+” icon on the left menu > “Import.”

• In the text box, paste the JSON script copied from this [link](https://github.com/sitespeedio/grafana-bootstrap-docker/blob/main/dashboards/influxdb/pageSummary.json).  

• Click the “Load” button.

• In the import options, set a name for your dashboard, the folder where you want to have it, and the InfluxDB data source created in step 5.

• Click the “Import” button.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/rrqs4otgpag3tk15ajus.png)

Now you can review above widgets in Grafana containing most of the information in html reports:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ngo1w9spqe35dhd86yg2.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/13rgdlp8c5iez89f9eim.png)

#### Slack Integration

You can enable WebHook into a public/private Slack Channel to send information for running scans to the team as well.

* Create a new Slack app in the workspace where you want to post messages.
* From the Features page, toggle Activate Incoming Webhooks on.
* Click Add New Webhook to Workspace.
* Pick a channel that the app will post to, then click Authorize.
* Use your Incoming Webhook URL to post a message to Slack
* Copy the WebHook URL to use it in argument --slack.hookUrl

Then you will see results summarized and posted to Slack:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/laddjrsp05d2f5qng6ek.png)

### Wrapping this into a process
* Use an ‘outside-in’ tool, like SiteSpeed or Lighthouse to generate a waterfall diagram of how the website loads.
* Identify bottlenecks with servers and the back end. Look for slow connection times, slow SSL handshakes, and slow DNS lookups. Use a plugin like Query Monitor, or a service like NewRelic to diagnose what’s holding things up. Make server, hardware, software and script changes.
* Identify bottlenecks with the front end. Look for slow loading and processing times on images, scripts and stylesheets. Use a tool like SiteSpeed.io we described previously to measure also more metrics, like time until first meaningful paint and time until interactive.