Front-end performance optimization series - optimizing white screen time

I. Introduction

Front-end optimization is an eternal topic. Every front-end developer hopes that their pages can load quickly and give users a good experience. However, in actual development, we often encounter a thorny problem, which is the white screen problem on the homepage. .

The white screen problem on the homepage means that after users open the page, they need to wait for a long time to see the page content. This will make users feel impatient and even lose them. There are many reasons for the white screen, such as network delay, excessive JS loading, Poor rendering performance, etc. For different reasons, we need to adopt different optimization strategies.

Today I will discuss with you a common scenario and one of its optimization methods. This optimization method may not be known to many people, but it is very effective and can greatly improve the user's perceived efficiency.

2. Scene review

<template>
  <div class="container">
    <div v-for="n in 100">
      <heavy-comp></heavy-comp>
    </div>
  </div>
</template>

<script setup>
  import HeavyComp from './components/HeavyComp.vue';
</script>

Here we imported a component called HeavyComp. There are many elements in this component, especially in large-screen projects, the elements may be particularly dense. Then we looped this component 100 times, rendering it once each time. Let's take a look. Check out how it works.

8ff9844858b055dfa3325f3926a41d2c.jpeg

We will find that there is a long wait, and finally render these components together. Then we use the browser's debugging tool Performance to do a performance analysis:

217dffd1289b73547e79040f315e3543.jpeg

It can be seen that it takes 2686 milliseconds to load JS and 2795 milliseconds to render. Such a page is completely unacceptable to users, so how to optimize it?

3. How to optimize

In fact, the main idea is to render these components part by part. The pressure of rendering them all together is too great. We need to divide them up. Render part of them first so that the user can see it, and then continue to render the remaining parts. Although the total time has not changed, and may even increase, as far as the user's perception is concerned, the time from the user opening the page to seeing something has been greatly reduced. Here we first use the written optimization method directly:

<template>
  <div class="container">
    <div v-for="n in 100">
      <!-- 在渲染组件的时候,我们可以利用 defer 函数来进行 if 判断 -->
      <heavy-comp v-if="defer(n)"></heavy-comp>
    </div>
  </div>
</template>

<script setup>
import HeavyComp from './components/HeavyComp.vue';
// 导入一个我已经写好的函数
import { useDefer } from './useDefer';
// 这个函数返回一个方法
const defer = useDefer();
</script>

So what does this defer function do? Everyone should know about rendering frames, that is, within a rendering timeline, it is divided into many small segments, each segment is a rendering frame, and the interval between each rendering frame is 16.6 milliseconds.

149e97a3be559ed51c5961eff65e6254.jpeg

If the first rendering frame is called the first rendering, the second rendering frame is called the second rendering, and so on, then this defer(n) means that the current rendering Does the frame exceed this n

For example: For example, defer(10), passing in 10 means that when the number of rendered frames is the first frame, false is returned, and it is still false when the second frame is rendered. Return false, and only return true when the rendering frame is greater than or equal to the tenth frame, it's that simple.

When it returns false, because we use v-if, then this component will not render. In other words, passing an n to it here means that it loops 100 times. When n is 1 for the first component, it means that the first component is rendered in the first frame. When n is 2 for the second component, it means that the second component is rendered in the second frame. So on and so forth.

Let’s take a look at the rendering of the optimized page:

4d9d4a688344c35aefff3942f5fce74b.jpeg

We found that we got a response quickly. Although the total time did not change because it was still rendering continuously, the user perceived that its efficiency had been greatly improved. We used the performance analysis tool to analyze it again.

4f70073db856c75a2ed4359702781292.jpeg

As you can see, the rendering process is divided into renderings one frame at a time, which avoids long-term page freezes. Users can see the rendering results of each rendering. This is a bit like React's fiber architecture. There is a similar concept in Vue3. In fact, they all use the browser's idle time for task scheduling and splitting.

Next let's take a look at how this function is implemented.

4. useDefer

import { ref } from "vue";
// 函数接收一个参数,表示监测的最大帧数,这里默认值是 1000
// 如果说你渲染的东西特别多可以传入一个值
export function useDefer(maxFrameCount = 1000) {
  // 然后开始计数
  const frameCount = ref(0);
  const refreshFrameCount = () => {
    requestAnimationFrame(() => {
      // 每一次 requestAnimationFrame 就计数加一
      // 表示当前渲染的帧数变多了一帧
      frameCount.value++;
      // 只要当前帧数小于最大帧数就递归执行
      if (frameCount.value < maxFrameCount) {
        refreshFrameCount();
      }
    });
  };
  refreshFrameCount();
  // 返回一个函数,接收传递进来的 n
  return function (showInFrameCount) {
    // 判断当前渲染的帧数有没有大于 n
    return frameCount.value >= showInFrameCount;
  };
}

5. Summary

The white screen problem of front-end optimization is a very important and common problem. We need to adopt different strategies according to different scenarios. This article introduces one of the scenarios and optimization methods, which is to use the defer function to control when components are rendered, so that the page content can be gradually displayed, thereby improving user perception efficiency and experience. Of course, there are other optimization methods and techniques, such as using skeleton screens, preloading, lazy loading, and code splitting.

Guess you like

Origin blog.csdn.net/weixin_42981560/article/details/134725320