A Blog
by Pim Veelders

Measuring front-end render times in Inertia and Vue

March 5, 2021
Inertia offers a nice way to use modern front-end techniques when building Laravel applications. However, creating a javascript heavy front-end also introduces new possible performance bottlenecks since more processing is performed in the browser.

Introduction

During development I like to keep my pages performant and running smoothly. I usually don't worry too much about the backend. This is probably because I feel confident in what I'm doing, and I know I can tweak things later when a performance issue actually occurs. Since I'm relatively new to creating javascript heavy front-end clients my confidence in this area is not as high. Also, I noticed that sometimes a seemingly small change can have a large impact on page render times. Therefore, I like to measure how fast my pages are rendered. What I want is a simple indicator showing the time it takes to render a page. Something like, "page rendered in X ms".

Watching page changes

In an Inertia app, each component has access to the $page object. This object changes every time Inertia visits a new page. So, by defining a watcher on this object we can measure how long it takes to render a page after a new json response is received from the server. A persistent layout component is the ideal place to put this logic. The code snippet below shows how to add this to your Layout component.

// Layout.vue
export default {
  data() {
    return {
      // Render time in ms (set after each inertia page visit)
      renderTime: 0,
    }
  },

  watch: {
    $page: {
      handler() {
        let startTime = performance.now();
        this.$nextTick(() => {
          this.renderTime = (performance.now() - startTime).toFixed(0);
        });
      },
    },
  },
}

Next, you only need to add {{renderTime}} somewhere in the template to start checking how long it takes to render pages. If it takes more than 100 milliseconds (or whatever your threshold is) than there is still work to be done ;-)