Tuning web performance with just browser APIs

As web applications become more complex, with a corresponding increase in required bandwidth and bundle sizes, to meet users’ expectations the need to consider web performance has never been more important.

Yes, there are third-party tools that can help with performance but what about what is available “out-of-the-box”? In this talk we will look at some of the browser APIs which can greatly assist in implementing techniques to improve web performance.

From Network Information API, to Device Memory and Performance APIs, these are all right there in the browser and a great set of tools with which to design our apps from the ground up with performance in mind and the means to identify where we can focus to help our users.

Tuning web performance with just browser APIs

Yaser Adel Mehraban, Lead Consultant TelstraPurple

New web performance APIs allow us to tune our sites with native tools, rather than having to rely on third party tools.

First of all we should set a definition:

Performance optimisation is the act of monitoring and analysing the speed and interactivity of the application and identifying ways to improve it.

This can be on both the server side and the client side; but this talk focuses on the client side.

The process for web performance is easy: measure some metrics, make changes to the site, then take measurements again to see if it made things better.

Some actions are done in the lab (localhost, dev environment, sometimes third parties) or in production. Ideas should be tested in the lab, tested in production, then taken back to the lab environment to continue improving things.

This is not all about hitting 100% in Lighthouse, it’s about user happiness. Performance optimisations can take a lot of time and money, so if users are already happy you may not want to push beyond that into low ROI work.

Metrics:

  • Perceived load speed
  • Load responsiveness
  • Runtime responsiveness
  • Visual stability
  • Smoothness

Three reasons to care about performance:

  • Conversion
  • Traffic
  • UX

The classic example of impact is that Amazon found that every 100ms delay cost them 1% in sales… which at their scale meant $330m/pa.

Common ways to measure performance:

  • Browser devtools
  • Lighthouse
  • Third party tools

Monitoring APIs:

  • User Timing
  • Performance Timeline
  • Navigation timing
  • Resource timing
  • Long tasks

User Timing

  • Performance marks
  • Performance measures
  • Accessed on the performance object in the client side

This API lets you set marks during execution of your code, then create measures between those marks. You can also clear these marks, because these might not get garbage collected effectively so clean up after yourself.

Browser support is good for this feature.

Performance Timeline helps you manage and observe your marks and measures.

  • performance.getEntries
  • PerformanceObserver

A PerformanceEntry looks like this:

{
  “name”: “measure-1”,
  “entryType”: “measure”,
  “startTime”: 22.68000000003667,
  “duration”: 0.025000001187436283
}

Again, good browser support for these features.

PerformanceNavigationTiming

  • total page load time
  • request response time
  • page render time
const perfData = window.performance.timing;
const connectTime = perfData.responseEnd – perfData.responseStart;
const renderTime = perfData.domComplete – perfData.domLoading;

Lots of examples of how to use these on MDN

Excellent browser support, although the API might change in future.

You can also send the information to a server in JSON.

const [entry] = performance.getEntriesByType(“navigation”);
console.table(entry.toJSON())

The data is quite rich and you can draw lots of insights from it.

Resource timing – Network request timing

  • high-res timestamps (ms)
  • resource loading timestamps
  • resource size

yas.fyi/3dG3aCN

The last API for today is Long Task:

  • Tasks running for 50ms or more
  • Culprit browsing context container
  • Attributions

This lets you flag tasks that are taking too long, using the longtask entry type.

NOTE this API is in draft, so its browser support isn’t as good as the other APIs.

So let’s say we’ve used all those APIs to find some areas to improve.. there are some more APIs we can use to make those improvements.

  • Network Information
  • Page Visibility
  • Resize Observer
  • Intersection Observer

Network Information

  • detect network condition changes on the client side
  • preload large requests
  • exposed via navigator.connection, navigator.mozConnection, navigator.webkitConnection

Early days so mostly works in Chrome at the moment.

(demo of using this in action, sending lighter images to slower connections)

Page Visibility

  • watch for when a page is not visible to the user
  • document.hidden
  • document.visibilityState
  • document.onVisibilityChange

This lets you know if the user is currently using the page or not; and you can do things like pause media, stop pre-fetching data, etc.

Resize Observer

  • monitoring object sizes in a performant way
  • ResizeObserver
  • ResizeObserverEntry

This lets you react if the page or container is resized – this gets away from having to manage and debounce the page resize event which gets fired a lot.

Intersection Observer

  • Observe changes in intersection of an element asyncronously
  • IntersectionObserver
  • IntersectionObserverEntry

One example of this is that an element that is initially off screen lower down a page will fire an event once it intersects with the viewport.

Use cases: lazy loading images, infinite scrolling, ad revenue reporting, prevent running tasks or animations.

To set up your intersection observer you will need to pass in some options: root (target element; null for the whole document), rootMargin (space around the target element) and threshold.

(demo of lazy image loading)

@yashints | yashints.dev