原文 address: Performance metrics. What’s this all about? By Artem Denysov… Proofreader: PPP-man, Lampui

What the hell are performance metrics?

Measuring page load performance is a difficult task. So Google Developers is working with the community on Progressive Web Metrics (PWM’s).

What are PWM’s and why do we need them?

Let’s start with a little history of browser metrics.

Previously we had two main points (events) to measure performance:

DOMContentLoaded – Triggered when the page loads, but the script file has just started execution.

The load event is triggered when the page is fully loaded and the user is ready to use the page or application.

For example, if we look at reddit.com’s tracking timeline (Chrome’s developer tool helps us mark the dots with blue and red vertical lines), we can see why these metrics aren’t so useful.

To this day, we can also see that Window.onload doesn’t reflect the user’s perception as well as it used to.

Reference: Steve Souders, Moving Beyond Window.onload () (2013)

Indeed, the problem with DOMContentLoaded is the time it takes to parse and execute JavaScript, which can be very long if the script file is too large. On mobile devices, for example, measuring and tracking the timeline within the limitations of 3G networks, it takes about ten seconds to reach the load point.

On the other hand, the load event is triggered too late to analyze the performance bottleneck of the page.

So can we rely on these indicators? What exactly do they tell us?

And the main question is, how does the user perceive the process from the time the page loads until it’s finished?

Why is loading perceptions so important? See the Article at Chrome Developers that stands for Leveraging the Performance Metrics that Most Affect User Experience, which again emphasizes the loading issue.

If you take a look at the square chart, where the X axis shows the load time and the Y axis shows the relative number of users who experience the load time within a given period of time, you can see that not all users experience the load time to be less than two seconds.

So in our experiment, the load time of 17 seconds or so was of little value in terms of capturing user perceived load. What did the user actually see in those 17 seconds? Hang? Half page loaded? The page is dead (the user can’t click the input box or scroll)? If there were any answers to these questions:

  1. Can improve the user experience
  2. Bring more users to your app
  3. Increase the benefit of product owners (users, consumers, money)

So, everyone is trying to read the user’s mind and predict what the user will be thinking during those 17 seconds of loading time.

  1. “Is it running?”

Has my web browsing started (server responds, etc.)? Has my navigation started successfully (the server has responded, etc.)?

  1. “Does it work?”

Is there enough critical stuff on the page for me to understand?

  1. “Is it ready to use?”

Can I interact with the page? Or is it still loaded?

  1. “Is the user experience good?”

Was I pleasantly surprised by the lack of scrolling stuttering, animated stuttering, unstyled content flickering, and slow Web font file loading?


If DOMContentLoaded or load metrics can’t answer these questions, what can?

Progressive Web Metrics

The LIST of PWM’s metrics is intended to help detect performance bottlenecks. In addition to load and DOMContentLoaded, PWM’s provides developers with more detailed information about page loading.

Let’s use Reddit.com’s tracking timeline to explore PWM’s and try to figure out what each metric means.


First Paint (FP)

I used to say that we only have two metrics, which is not quite accurate. Developer tools also provides us with a metric called FP. This metric represents the point in time when the page was drawn, in other words when the user first saw the white screen (below is the FP screenshot from MSN.com). You can read more about this in the specification.

To see how it works, let’s take a look at the underlying mechanism of Chromium layers as an example.

The FP event is triggered when a layer is being drawn, not when text, images, or Canvas appear, but it also gives some information in the list that developers are trying to use.

But it’s not a standard metric, so measuring it becomes tricky. Hence the use of different “trick” techniques, such as:

  • additionalrequestAnimationFrameuse
  • Capture CSS resource loading
  • Even usingDOMContentLoadedloadEvents (their problems have been covered before)

However, despite these efforts, it is not of great value because text, images, and Canvas can be drawn shortly after the FP event is triggered, and these can be affected by performance bottlenecks such as page weight, CSS, or JavaScript resource size.

This metric is not part of the PWM, but it is useful for understanding the metrics covered below.

So some other metrics are needed to represent actual content rendering.

First Contentful Paint (FCP)

This is the point in time when the user sees some “content” elements drawn on the page. It’s not the same as a white screen, it can be the first appearance of text, or the first appearance of SVG, or the first appearance of Canvas, etc.

So, the user might wonder, is it running? Does the page start loading after he or she types the URL and presses Enter?

Looking at Chromium, FCP events are already triggered during the drawing of text (not counting text waiting for font files to load), images, Canvas, etc. Therefore, the time difference between FP and FCP can range from a few milliseconds to a few seconds. The difference can even be seen in the picture above. That’s why it’s valuable to have a metric to represent real first time content drawing.

You can read all the specifications here.

How does the FCP metric add value to developers?

If the first content drawing takes too long, then:

  • There may be a performance problem with your network connection
  • Resources are too large (such as index.html) and it takes too long to transfer them

Read High Performance Browser Networking by Ilya Grigorik to learn more about network Performance issues and eliminate the impact of these factors.


First Meaningful Paint (FMP)

This is the point at which the main content of the page appears on the screen, so is it useful?

What are the main contents?

when

  • The title and text of the blog
  • Search engine search text
  • Images that are important for e-commerce products

When you show it.

But if I show you

  • Drop down menus or something like that
  • Style-free content flicker (FOUC)
  • Navigation bar or page title

Is not counted in the main content.

FMP = Maximum layout change when drawing

Based on the Chromium implementation, this drawing is calculated using LayoutAnalyzer, which collects all layout changes and gives the time when the layout changes the most. And that time is FMP.

You can read all the specifications here.

How does the FMP metric help developers?

If the main content has not been shown for a long time, then:

  • Too many resources (images, styles, fonts, JavaScript) have high loading priorities and, as a result, they block FMP

I don’t want to repeat too many of the practices that have been used to improve these bottlenecks, but I’ll give you some links:

All the information you need can be found in these articles.


Visually ready

The state when the page looks “close” to loading, but the browser has not executed all script files.


Expected input delay

This metric is intended to gauge how smoothly an application responds to user input.

But before I go any further, I want to explain a few terms so that you can get in sync.

Long task

The browser layer packages all user input in a single task (UI task) and places it in a queue in the main thread. In addition, the browser must parse, compile, and execute JavaScript code (application tasks) on the page. If each application task takes a long time, user input tasks can be blocked before other tasks finish. So it delays the interaction with the page, and the page behavior becomes sluggish and delayed.

Simply put, a long task is a block of JavaScript code that takes more than 50 milliseconds to parse, compile, and execute.

You can read all the specifications here.

The long task API has been implemented in Chrome and is used to measure how busy the main thread is.

Going back to expected input latency, the user will assume that the page is responding quickly, but if the main thread is busy with long tasks, the user will not be satisfied. User experience is critical to applications, and you can read about how this type of Performance bottleneck can be improved in Measure Performance with the RAIL Model.


For the first time the interaction

Interaction – Is it ready to use? Yes, that’s the question users ask when they see a visually ready page and want to interact with it.

The following conditions must be met for the first interaction:

  • FMP
  • &&
  • The DOMContentLoaded event was raised
  • &&
  • Page visual completion is 85%

First preferably Interactive – This indicator can be broken down into two indicators, Time to First Interactive (TTFI) and Time to First sustained Interactive (TTCI).

The reasons for the split are:

  • Define minimal interaction when the UI is responsive, but it’s acceptable if it’s not
  • When the site has complete and enjoyable interaction, and strictly follows RAIL’s guidelines

TTCI

Using reverse analysis, starting from the end of the trace line, it was found that the page-loading activity remained quiet for 5 seconds and there were no more long tasks performed, resulting in a period called the quiet window. The time after the quiet window and before the first long task (counting from the end of the quiet period) is the TTCI.

TTFI

The definition of this metric is a little different from TTCI. Let’s analyze and track the timeline from beginning to end. There should be a 3 second quiet window after FMP occurs. This is enough time to say that the page is interactive to the user. However, there may be long tasks that start executing during or after this quiet window, and they can be ignored.

Long tasks – Tasks performed far from the FMP, separated by a 250ms execution time period (channel size) and a 1 second quiet period before and after the channel size. The sample task could be a third-party AD or analysis script.

Sometimes “long tasks” longer than 250 milliseconds can have a serious impact on the page.

Such as detecting AdBlock

You can read all the specifications here.

How can TTFI and TTCI metrics help developers?

When a thread is busy for an extended period of time between visually ready and first interaction

This is one of the most complex bottlenecks, and there is no standard way to fix this type of problem. It is independent and depends on the specific circumstances of the application. Chrome Developer Tools has a series of articles to help us detect runtime performance issues.


Visual finish/speed index

Visual finish was calculated using screenshots of the page, and pixel analysis of those screenshots was performed using a speed index algorithm. Sometimes measuring visual completion can be tricky.

If a page has images that change, such as a rotating image, getting the correct visual finish can be a bit of a challenge.

The speed index itself represents the median of the visually completed results. The smaller the speed index, the better the performance.

Visually 100% complete is the final point that determines whether the user is satisfied with the page. This is also a time to answer questions – is the user experience good?


conclusion

The above is not all PWM, but the most important part. The above metrics have added links to resources to help us improve them, and I’d also like to include links to tools for measuring these types of metrics:

P.S. To get results for all of these metrics, I recommend Lighthouse or Pwmetrics. Calibre and WPT both run Lighthouse and can provide all of these metrics through extensions.

If you want to measure performance manually, there is a native API called PerformanceObserver that can help you achieve your measurement goals.

Examples taken from the specification:

const observer = new PerformanceObserver(list => {
  list
    .getEntries()
    // Get the values we are interested in
    .map(({ name, entryType, startTime, duration }) => {
      const obj = {
        "Duration": duration,
        "Entry Type": entryType,
        "Name": name,
        "Start Time": startTime,
      };
      return JSON.stringify(obj, null, 2);
    })
    // Display them to the console
    .forEach(console.log);
  // maybe disconnect after processing the events.
  observer.disconnect();
});
// retrieve buffered events and subscribe to new events
// for Resource-Timing and User-Timing
observer.observe({
  entryTypes: ["resource", "mark", "measure"],
  buffered: true
});Copy the code

Thanks to all the staff who did a great job on the specification, articles and tools!


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, React, front-end, back-end, product, design and other fields. If you want to see more high-quality translation, please continue to pay attention to the Project, official Weibo, Zhihu column.