Что такое разделение времени?

JavaScript оптимизация производительности

согласно сГруппа производительности W3CВнедрение более 50мс - долгая задача.

图片描述

Изображение изОцените производительность с помощью моделей RAIL

Согласно приведенному выше рисунку мы можем знать, что когда задержка превышает 100 мс, пользователь почувствует небольшую задержку.

Итак, чтобы избежать этой ситуации, мы можем использовать две схемы, одна из которыхWeb Worker, другойРазделение времени.

Web Worker

Все мы знаем, что JS однопоточный, поэтому при выполнении длинных задач легко вызвать состояние приостановленных страниц.Хотя мы можем ставить задачи в очередь задач и выполнять их асинхронно, сути это не меняет Дж.С.

Поэтому для того, чтобы изменить эту ситуацию,whatwgвыпускатьWeb Workers.

Конкретная грамматика не будет объяснена, заинтересованная детская обувь может проверитьMDN Web Worker.

мы можем посмотреть на использованиеWeb WorkerПосле эффекта оптимизации:

const testWorker = new Worker('./worker.js')
setTimeout(_ => {
  testWorker.postMessage({})
  testWorker.onmessage = function (ev) {
    console.log(ev.data)
  }
}, 5000)

// worker.js
self.onmessage = function () {
  const start = performance.now()
  while (performance.now() - start < 1000) {}
  postMessage('done!')
}

图片描述

Код и скриншоты взяты изСделайте ваши веб-страницы более плавными

Разделение времени

Time slicing — широко используемое техническое решение, суть которого состоит в том, чтобы разбивать длинные задачи на задачи с коротким временем выполнения, а затем выполнять их одну за другой.

Эта концепция очень полезна для нашей ежедневной оптимизации производительности.

Например, когда нам нужно сразу вставить на страницу длинный список (конечно, обычно в этом случае мы будем использовать для этого пагинацию).

Если мы используем концепцию квантования времени для достижения этой функции, мы можем использоватьrequestAnimationFrame+DocumentFragment

По поводу этих двух API я тоже не буду давать подробного описания, если вам интересно, вы можете ознакомиться с ними.MDN requestAnimationFrameа такжеMDN DocumentFragment.

Вот две демонстрации, вы можете сравнить беглость:

Не использовать разделение времени:

<style>
    * {
        margin: 0;
        padding: 0;
    }
    .list {
        width: 60vw;
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
    }
</style>
<ul class="list"></ul>
<script>
    'use strict'
    let list = document.querySelector('.list')
    let total = 100000
    for (let i = 0; i < total; ++i) {
        let item = document.createElement('li')
        item.innerText = `我是${i}`
        list.appendChild(item)
    }
</script>

Используйте разделение времени:

<style>
    * {
        margin: 0;
        padding: 0;
    }
    .list {
        width: 60vw;
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
    }
</style>
<ul class="list"></ul>
<script>
    'use strict'
    let list = document.querySelector('.list')
    let total = 100000
    let size = 20
    let index = 0
    const render = (total, index) => {
        if (total <= 0) {
            return
        }
        let curPage = Math.min(total, size)
        window.requestAnimationFrame(() => {
            let fragment = document.createDocumentFragment()
            for (let i = 0; i < curPage; ++i) {
                let item = document.createElement('li')
                item.innerText = `我是${index + i}`
                fragment.appendChild(item)
            }
            list.appendChild(fragment)
            render(total - curPage, index + curPage)
        })
    }
    render(total, index)
</script>

Я не делал слишком много оценок, но, судя по визуальному опыту пользователя, первое решение, которое я просто хочу обновить несколько раз, и при скольжении вниз также возникает явление белого экрана.

В дополнение к приведенной выше схеме генерации DOM мы также можем использовать Web Api.requestIdleCallbackи API ES6Generator]реализовать.

Не буду много вводить, вы можете ознакомиться с подробными правиламиMDN requestIdleCallbackтак же какMDN Generator.

Конкретная реализация выглядит следующим образом:

<style>
    * {
        margin: 0;
        padding: 0;
    }
    .list {
        width: 60vw;
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
    }
</style>
<ul class="list"></ul>
<script>
    'use strict'
    function gen(task) {
      requestIdleCallback(deadline => {
        let next = task.next()
        while (!next.done) {
          if (deadline.timeRemaining() <= 0) {
            gen(task)
            return
          }
          next = task.next()
        }
      })
    }
    let list = document.querySelector('.list')
    let total = 100000
    function* loop() {
      for (let i = 0; i < total; ++i) {
        let item = document.createElement('li')
        item.innerText = `我是${i}`
        list.appendChild(item)
        yield
      }
    }
    gen(loop())
</script>

использованная литература

  1. web-performance
  2. Measure Performance with the RAIL Model
  3. Сделайте ваши веб-страницы более плавными
  4. Высокопроизводительный внешний рендеринг 100 000 фрагментов данных (временной разрез)

постскриптум

Если вам нравится обсуждать технологии или у вас есть какие-либо комментарии или предложения по этой статье, вы можете добавить друзей Yutou в WeChat для совместного обсуждения.Конечно, Yutou также надеется поговорить с вами о жизни, хобби и поболтать. WeChat ID Fish Head: krisChans95 Вы также можете отсканировать код, чтобы подписаться на официальный аккаунт и подписаться на более интересный контент.

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/3/4/170a55cc795174aa~tplv-t2oaga2asx-image.image