Not long ago, huawei cloud official website user performance data collection and front-end monitoring (juejin.cn/post/699276… Made a very simple summary, deeply feel the site performance data collection for monitoring the site and optimize the performance has a good role in guiding. In fact, we are based on the Chrome development team to test the site performance of a series of performance indicators:

  1. First-paint (FP), the time from the start of page loading until the first pixel is drawn on the screen
  2. FCP(first-Contentful-paint), the time from the time the page loads until any part of the page content completes rendering on the screen
  3. LCP(largest- Contentful-paint), the time from the start of page loading until the largest text block or image element is rendered on the screen
  4. CLS(layout-Shift), the cumulative score for all unexpected layout offsets that occur from the time the page is loaded and its life cycle state becomes hidden

The four performance indicators can be obtain by PerformanceObserver (performance. GetEntriesByName () can also be used to retrieve, but it is not in the event trigger notifications). PerformanceObserver is a performance monitoring object that listens for logging performance data, which triggers a callback so we can report the data in a callback.

FP

First-paint (FP) is the time between the page loading and the first pixel being drawn on the screen. That’s what we call white screen time. The measurement code is as follows:

const handlerFn = (list) = > {        
    for (const entry of list.getEntries()) {
        if (entry.name === 'first-paint') {
            observer.disconnect()
        }
       console.log(entry)
    }
}
const observer = new PerformanceObserver(handlerFn)
The buffered property indicates whether to observe cached data, which means it doesn't matter if the code is added later than the event is triggered.
observer.observe({ type: 'paint'.buffered: true })
Copy the code

The contents of FP can be obtained from the above code:

{
    duration: 0.entryType: "paint".name: "first-paint".startTime: 359./ / fp time
}
Copy the code

StartTime is the drawing time we want.

FCP

FCP(first-Contentful-paint) is the time from the start of the page loading until any part of the page content is rendered on the screen. Any part here refers to a complete page module (text, image, background, SVG or Canvas element). In the second image below, there is a complete module that completes the FCP. In order to provide a good user experience, FCP scores should generally be kept under 1.8 seconds.

Measurement code:

const handlerFn = (list) = > {        
    for (const entry of list.getEntries()) {
        if (entry.name === 'first-contentful-paint') {
            observer.disconnect()
        }
        console.log(entry)
    }
}
const observer = new PerformanceObserver(handlerFn)
observer.observe({ type: 'paint'.buffered: true })
Copy the code

You can get the contents of the FCP from the code above:

{
    duration: 0.entryType: "paint".name: "first-contentful-paint".startTime: 459./ / FCP time
}
Copy the code

StartTime is the drawing time we want.

LCP

LCP (largest – contentful – paint) refers toThe time a page load begins until the maximum block of text or image element is rendered on the screen. A good LCP score should be under 2.5 seconds. The second image completes the drawing of the largest text block or image as shown below.

Measurement code:

const entryHandler = (list) = > {
    if (observer) {
        observer.disconnect()
    }
    for (const entry of list.getEntries()) {
        console.log(entry)
    }
}
const observer = new PerformanceObserver(entryHandler)
observer.observe({ type: 'largest-contentful-paint'.buffered: true })
Copy the code

The contents of the LCP can be obtained with the following code:

{
    duration: 0.element: p,
    entryType: "largest-contentful-paint".id: "".loadTime: 0.name: "".renderTime: 1021.299.size: 37932.startTime: 1021.299.url: "",}Copy the code

StartTime is the drawing time we want. The difference between FCP and LCP is that FCP fires as soon as any content is drawn, while LCP fires as soon as the maximum content is rendered.

CLS

The Cumulative Layout Shift (CLS) is the Cumulative score of all unexpected Layout offsets that occur from the time the page is loaded and its lifecycle state becomes hidden. Unexpected movement of page content often occurs because of asynchronous loading of resources or dynamic addition of DOM elements. The culprit could be an image or video of unknown size, or a font file (larger or smaller than the default font), or a third-party AD or widget (that automatically changes size). The more complex the site, the more likely it is to get a high CLS score. For simple layouts such as the iconic Google home page, there is no CLS because they contain few elements. That’s not to say that all complex sites have high CLS scores, like Amazon. No one would argue that the e-commerce giant uses simple web design. However, you can hardly see layout changes when you browse through its catalog.

  • 1. What is the impact of CLS on site performance?

In theory, you can have a very fast website and still have a relatively poor CLS score. As with other core web metrics, CLS scores may not be directly related to the overall performance of a site. Your website can be surprisingly fast, but when it loads, it unfolds like a folding box, and big layout changes can definitely have a negative impact on the user experience of the site. Google sees this as very important. That’s why Google puts so much weight on this data point.

  • 2. Is CLS less important than FCP or LCP scores?

Many users are more concerned with FCP and LCP scores. This is because these two metrics are easier to relate to site performance. Although FCP is also a specifically user-centric metric, CLS is more difficult to measure consistently across a large number of users. These three indicators make up Google’s core network indicators. If you ignore one of these metrics, you run the risk of falling behind in relevant search results. Make sure your site is optimized for low CLS and generally has no positive impact on site performance such as LCP and FCP. How good is fast load time if users are pushed under the screen as soon as they see ‘Largest Contentful Paint’?

The layout offset score is calculated as follows:

Layout offset score = Impact score * Distance scoreCopy the code

[Influence score] Measures the effect of an unstable element on the visible area between frames.

[Distance score] is the maximum distance (horizontal or vertical) that any unstable element can move in a frame divided by the maximum dimensional dimension (width or height, whichever is greater) of the visible area.

So how do we compute the value of CLS? In CLS, a term is defined calledThe session windowOne or more single layout offsets occurring in rapid succession, each offset less than 1 second apart, and the maximum duration of the entire window is 5 seconds. For example, the second session window in the figure below has four layout offsets. Each offset must be less than 1 second apart, and the time between the first offset and the last offset must not exceed 5 seconds in order to be considered a session window. If not, consider it a new session window.

CLS is generally calculated by taking the maximum value of all session Windows. This method is the optimal calculation method at present. Only the maximum value of all session Windows is taken each time to reflect the worst case of page layout deviation.

let sessionValue = 0
let sessionEntries = []
const cls = {
    subType: 'layout-shift'.name: 'layout-shift'.type: 'performance'.pageURL: getPageURL(),
    value: 0,}const entryHandler = (list) = > {
    for (const entry of list.getEntries()) {
        if(! entry.hadRecentInput) {const firstSessionEntry = sessionEntries[0]
            const lastSessionEntry = sessionEntries[sessionEntries.length - 1]

            // This condition ensures that it is a session window
            if (
                sessionValue
                && entry.startTime - lastSessionEntry.startTime < 1000
                && entry.startTime - firstSessionEntry.startTime < 5000
            ) {
                sessionValue += entry.value
                sessionEntries.push(formatCLSEntry(entry))
            } else {
                sessionValue = entry.value
                sessionEntries = [formatCLSEntry(entry)]
            }

            // If the current sessionValue is larger, use this value
            if (sessionValue > cls.value) {
                cls.value = sessionValue
                cls.entries = sessionEntries
                cls.startTime = performance.now()
                lazyReportCache(deepCopy(cls))
            }
        }
    }
}

const observer = new PerformanceObserver(entryHandler)
observer.observe({ type: 'layout-shift'.buffered: true })
Copy the code

After reading the above text description, look at the code to make sense. The measurement of a layout offset is as follows:

{
  duration: 0.entryType: "layout-shift".hadRecentInput: false.lastInputTime: 0.name: "".sources: (2) [LayoutShiftAttribution, LayoutShiftAttribution],
  startTime: 1176.199999999255.value: 0.000005752046026677329,}Copy the code

The value field in the code is the layout offset score.