Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPA impact #79

Closed
chaffeqa opened this issue Oct 16, 2020 · 3 comments
Closed

SPA impact #79

chaffeqa opened this issue Oct 16, 2020 · 3 comments

Comments

@chaffeqa
Copy link

I'm concerned that the CLS will not trigger by default until a user has navigated a few times in a SPA... wouldn't that throw off the value significantly?

The main reason for incorporating this into our application is to track user experience on first load. So in that sense I feel like I'd prefer CLS to have a way of returning the current shift value when called (after DOM load in our case) which obviously hopefully would be a value of 0

@philipwalton
Copy link
Member

I'm concerned that the CLS will not trigger by default until a user has navigated a few times in a SPA... wouldn't that throw off the value significantly?

As currently defined, CLS doesn't treat SPAs differently from any other web page. CLS measures layout shifts that occur throughout the entire lifecycle of a page, regardless of whether that page updates the URL.

So to answer your question, no, navigating in an SPA does not throw off the value of CLS; though (depending on how the SPA is loading new content) it could mean that a page that a user keeps open for a long time may end up with higher CLS than it would have if it had used traditional page loads. On the other hand (again, depending on how the site is built), an SPA may also end up with less CLS in cases where most of the layout shifts happen during page load.

The main reason for incorporating this into our application is to track user experience on first load. So in that sense I feel like I'd prefer CLS to have a way of returning the current shift value when called (after DOM load in our case) which obviously hopefully would be a value of 0

I understand why you'd want this, but I want to stress that what you're describing is not CLS. If you do want to track this data, I'd recommend calling it something else to avoid confusion (e.g. "pre-load layout shift" or "CLS before load", etc.).

Also, while it's possible to track CLS before load using this library, it gets a bit tricky because PerformanceObserver callbacks are not always called right away (to avoid them affecting performance), so you can't necessarily guarantee that all callback have run by the time the load event fires.

For example, this (using the reportAllChanges param) will be close but might not be 100% accurate:

import {getCLS} from 'web-vitals';

let clsBeforeLoad = 0;

getCLS((metric) => {
  clsBeforeLoad = metric.value;
}, true);

addEventListener('load', () => {
  // `clsBeforeLoad` here might not have the latest entries.
  console.log(clsBeforeLoad);
});  

If you need precision, you're better off not using this library and just using the underlying Layout Instability API directly:

let clsBeforeLoad = 0;

function onLayoutShiftEntry(entry) {
  // Only count layout shifts without recent user input.
  if (!entry.hadRecentInput) {
    clsBeforeLoad += entry.value;
  }
}

const po = new PerformanceObserver((list) => {
  list.getEntries().map(onLayoutShiftEntry);
});
po.observe({'layout-shift', buffered: true});

addEventListener('load', () => {
  // Calling `takeRecords()` gives you access to any undispatched entries in the load event.
  po.takeRecords().map(onLayoutShiftEntry);
  console.log(clsBeforeLoad);
});  

@philipwalton
Copy link
Member

I'm going to close this issue as I don't think there are any changes that need to be made to the library to address this.

@robindirksen1
Copy link

Maybe interesting thread about Web Vitals in combination with ranking factors (coming in May 2021): https://twitter.com/simonhearne/status/1316775506222682112

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants