Resource Timing (part 2) - Loading Dependencies

in Browsertools 4 minutes read

This is post #2 in the category “Browser Tools”, focusing on understanding Loading Dependencies. In part 1 about ResourceTiming we looked at the attributes responseEnd and startTime. Now we want to go a bit deeper and look at how the tools allow us to understand the dependencies of the loaded resources.

For doing so we are using the Resource Timing API, which allows to gather information about resources our site loads. This is done by using the Performance API accessible via JavaScript using window.performance. Here we will explore how much details we can gather about each resource that is loaded (JS files, CSS files, fetches, etc.). Especially about their timing and dependencies.

Setting the Context

Let’s shortly sum up how we gather those data. There is a built-in functionality that you see in action, right here:

> window.performance.getEntriesByType('resource')
[{
    // ... shortened
    name: "http://techblog.holidaycheck.com/css/main.css",
    initiatorType: "link",
    startTime: 18.41499999864027,
    // ... shortened
}, {...}]

As you can see above window.performance provides these data right in the browser. If you want to understand more details read part 1.

From here on we will take apart some of the data and make sure we understand what they mean.

The startTime Attribute

The spec says that the attribute startTime is “the time immediately before the [browser] starts to queue the resource for fetching”. This means, e.g. if the browser is about to load the HTML page the startTime is recorded. This time is relative from “the time when the browsing context is first created”. In other words when the browser starts loading a new page. So this is a very browser-internal thing, that we would not be able to get access to without extending the browser itself. That proves that this API can give us insights which we could not be able to obtain otherwise, especially not on any website itself. These numbers are also way more explicit in regards to what the user expriences.

A startTime of 0 is the moment when the browsing context was created, when the browser started loading this page. This is for example a website reload, or navigating to a new site, opening a tab with a certain URL and alike. That means a startTime=20 means 20 milliseconds after the browser context was created. Having a timestamp relative to the browser context creation allows us to get insights on our resource timings without any timestamp offset calculations, as we used to do using Date.now() (more in the previous post).

Let’s look at some real life numbers:

The "startTime" for all resources requested by this page

Hint: The chart above shows the real numbers of the page you are looking at, if you reload, the numbers above may change (changes can be seen best on the x-axis scale).

In the chart one should see that some requests start at the same time. These requests have most probably been triggered by the same resource. For example the “main.css”, the logo and the “main.js” files start to get loaded around the same time, as the first resources. This is because the HTML file that directly references them, triggers the loading of these files. The browser reads the HTML file, interprets it and finds <link> and <script> tags that reference those resources, so they start to get loaded, hence they have the lowest startTime.

In the chart one can also see that the fonts start loading way later. This is because they are referenced inside the “main.css” file, which needs to be downloaded and read by the browser first to know that the according fonts need to get loaded. This way one can understand better how the browser handles the resources, in which order and also using which constraints to load them.

The initiatorType Attribute

This attribute is the type that triggered this resource to be loaded. In the chart above one can see strings like initiatorType: navigation, initiatorType: link, initiatorType: script and others. There are basically two types of attributes, the initiatorType is either:

  1. The name of the HTML tag, the DOM node (or as the spec text says the “value as the localName of that element [DOM], if the request is a result of processing the element”),
    • this refers to attributes like src in a <script src="resource.js"> tag, the href attribute in a <link href="resource.css"> tag or the src atttribute of an <img> tag among others.
  2. Or it is one of “css”, “navigation”, “xmlhttprequest”, “fetch”, “beacon” or “other” when the loading was not directly triggered by a DOM node,
    • these are things like loading a new page (“navigation”), loading a resource from within a CSS file (“css”) or the request done via the native JavaScript window.fetch() method (“fetch”).

This attribute gives a bit more context to the loading times and makes the loading dependencies talked about in the paragraph before easier to understand. A CSS file needs to be loaded by the browser, before it can know what other files are referenced inside of it and need to be loaded. This might also surface the question how much should be inlined, or if preload should be used to speed up website loading.

Focus on the Dependencies

I hope this post allows to gather better insights and hopefully also decouple the dependencies among resources where accurate and therefore speed up the website. I tried to focus on just looking at the two attributes startTime and initiatorType so the loading dependencies become very obvious and in case it is what one wants to focus on, they might be a good start.

This site is quite simple and therefore makes the dependencies easy to understand. If you try this out on a more complex page loading dependencies will also be a bit harder to identify. Have fun untangling your loading dependencies. Feel free to share findings and insights with us on twitter.

You want to know more? Read part 3 of this series about “Waterfall Chart”.

*Main photo by Ben Harritt on Unsplash