当前位置:网站首页>The first screen time, you said you optimized it, then you calculated it and showed it to me!

The first screen time, you said you optimized it, then you calculated it and showed it to me!

2022-06-26 07:19:00 Sunshine_ Lin

Preface

Hello everyone , I'm Lin Sanxin , Speak the most difficult knowledge points in the most easy to understand words It's my motto , Foundation is the premise of advanced It's my first heart

background

When we are doing project performance optimization , Optimize the first screen time It is an unavoidable optimization direction , But how many people have thought about the difference between these two things :

  • White screen time
  • First screen time

And what's the difference between the calculation of these two times ? Next, I will tell you about it !

White screen time

What is it? ?

White screen time refers to : The time when the page begins to display content . That is to say : The time when the browser displays the first character or element

How to calculate ?

We just need to know when the browser starts displaying content , That is, the white screen time of the page can be obtained at the end time of the page white screen .

therefore , We usually think that browsers start rendering <body> Tag or parse <head> The time of the tag is the time when the white screen of the page ends .

  • Browser support performance.timing

    <head>
    <title>Document</title>
    </head>
    <script type="text/javascript">
    //  White screen time end point 
    var firstPaint = Date.now()
    var start = performance.timing.navigationStart
    console.log(firstPaint - start)
    </script>
  • Browser does not support performance.timing

    <head>
    <title>Document</title>
    <script type="text/javascript">
      window.start = Date.now();
    </script>
    </head>
    <script type="text/javascript">
    //  White screen time end point 
    var firstPaint = Date.now()
    console.log(firstPaint - window.start)
    </script>

    First screen time

    What is it? ?

    The first screen time is when the user opens the website , The time until the first screen of the browser is rendered . For the user experience , The first screen time is an important factor for users to experience a website .

Why not just use the lifecycle ?

Some of them will say : Why not directly in App.vue Of mounted Calculate time in the life cycle ? You can see that , Official website said mounted Execution does not mean that all elements on the first screen have been loaded , therefore mounted The calculated time will be shorter .

Why not use it directly nextTick?

nextTick When it comes back , First screen DOM It's all rendered , But calculation First screen time You don't have to render everything DOM, So the calculated time will be longer

How to calculate ?

We need to use MutationObserver monitor DOM The change of , Monitor every time DOM Changing fraction , The calculation rule is :
(1 + The layer number * 0.5), Let me give you an example :

<body>
    <div>
      <div>1</div>
      <div>2</div>
    </div>
</body>

above DOM The score of the structure is :

1.5 + 2 + 2.5 + 2.5 = 8.5( branch )

In fact, during the loading of the first screen , It will involve DOM An increase in 、 modify 、 Delete , So it will trigger many times MutationObserver , So we will count the number of different stages score, We put these score Stored in an array observerData in , The back is very useful

First screen time practice

Now let's start calculating the first screen time !

Lead to

  • index.html:html page

    <!DOCTYPE html>
    <html lang="en">
    <head> </head>
    <body>
      <div>
        <div>
          <div>1</div>
          <div>2</div>
        </div>
        <div>3</div>
        <div>4</div>
      </div>
      <ul id="ulbox"></ul>
    </body>
    <script src="./computed.js"></script>
    <script src="./request.js"></script>
    </html>
  • computed.js : File for calculating the first screen time

    const observerData = []
    
    let observer = new MutationObserver(() => {
    //  Calculate every time DOM When modifying , The time before the page starts loading 
    const start = window.performance.timing.navigationStart
    const time = new Date().getTime() - start
    
    const body = document.querySelector('body')
    const score = computedScore(body, 1)
    //  Add to array  observerData  in 
    observerData.push({
      score,
      time
    })
    })
    observer.observe(
    document, {
      childList: true,
      subtree: true
    }
    )
    
    function computedScore(element, layer) {
    let score = 0
    const tagName = element.tagName
    //  Exclude these labels 
    if (
      tagName !== 'SCRIPT' &&
      tagName !== 'STYLE' &&
      tagName !== 'META' &&
      tagName !== 'HEAD'
    ) {
      const children = element.children
      if (children && children.length) {
        //  Recursively calculate the score 
        for (let i = 0; i < children.length; i++) {
          score += computedScore(children[i], layer + 1)
        }
      }
    
      score += 1 + 0.5 * layer
    }
    return score
    }
  • request.js : Simulation request modification DOM

    //  Simulation request list 
    const requestList = () => {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(
          [1, 2, 3,
            4, 5, 6,
            7, 8, 9
          ]
        )
      }, 1000)
    })
    }
    
    const ulbox = document.getElementById('ulbox')
    
    //  Simulation request data rendering list 
    const renderList = async () => {
    const list = await requestList()
    const fragment = document.createDocumentFragment()
    for (let i = 0; i < list.length; i++) {
      const li = document.createElement('li')
      li.innerText = list[i]
      fragment.appendChild(li)
    }
    ulbox.appendChild(fragment)
    }
    
    //  Simulate minor changes to the list 
    const addList = async () => {
    const li = document.createElement('li')
    li.innerText = ' Add '
    ulbox.appendChild(li)
    }
    
    (async () => {
    //  Simulation request data rendering list 
    await renderList()
    //  Simulate minor changes to the list 
    addList()
    })()

observerData

When we are all ready to run the code , We got observerData , Let's see what it looks like ?

Calculate the first screen time

How do we base it observerData To calculate the first screen time ? We can do that : The first screen time is the time when the next score increases the most than the last score

A lot of people will ask , Why not take the time of the last item as the first screen time ? We should pay attention to : The first screen is not all DOM Render all , Let me take the code just now as an example , We finished rendering the list , Then add another one li, Which time period do you think is the first screen ? It should be the first screen after rendering the list , Because only one has been added li, Small increase in scores , Negligible

So let's start calculating :

const observerData = []

let observer = new MutationObserver(() => {
  //  Calculate every time DOM When modifying , The time before the page starts loading 
  const start = window.performance.timing.navigationStart
  const time = new Date().getTime() - start
  const body = document.querySelector('body')
  const score = computedScore(body, 1)
  observerData.push({
    score,
    time
  })

  // complete Time to call  unmountObserver
  if (document.readyState === 'complete') {
    //  Only calculate 10 Seconds rendering time 
    unmountObserver(10000)
  }
})
observer.observe(
  document, {
    childList: true,
    subtree: true
  }
)

function computedScore(element, layer) {
  let score = 0
  const tagName = element.tagName
  //  Exclude these labels 
  if (
    tagName !== 'SCRIPT' &&
    tagName !== 'STYLE' &&
    tagName !== 'META' &&
    tagName !== 'HEAD'
  ) {
    const children = element.children
    if (children && children.length) {
      //  Recursively calculate the score 
      for (let i = 0; i < children.length; i++) {
        score += computedScore(children[i], layer + 1)
      }
    }

    score += 1 + 0.5 * layer
  }
  return score
}

//  Calculate the first screen time 
function getFirstScreenTime() {
  let data = null
  for (let i = 1; i < observerData.length; i++) {
    //  Calculate the amplitude 
    const differ = observerData[i].score - observerData[i - 1].score
    //  Take the maximum amplitude , Record the corresponding time 
    if (!data || data.rate <= differ) {
      data = {
        time: observerData[i].time,
        rate: differ
      }
    }
  }
  return data
}

let timer = null

function unmountObserver(delay) {
  if (timer) return
  timer = setTimeout(() => {
    //  Output the first screen time 
    console.log(getFirstScreenTime())
    //  End MutationObserver Monitoring of 
    observer.disconnect()
    observer = null
    clearTimeout(timer)
  }, delay)
}

Calculate the first screen time 1020ms

summary

My calculation method actually has many flaws , The deletion of elements is not taken into account , But I want you to know how to calculate the first screen time , That's the most important thing , I hope you can understand this calculation idea

Conclusion

I'm Lin Sanxin , An enthusiastic front-end rookie programmer . If you make progress , Like the front , Want to learn the front end , Then we can make friends , Fish together, ha ha , Fish schools , Add me, please note 【 Think no 】

image.png

原网站

版权声明
本文为[Sunshine_ Lin]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202171141363722.html