Ленивая загрузка компонентов для оптимизации производительности: введение в Vue Lazy Component

внешний интерфейс GitHub API Vue.js
Ленивая загрузка компонентов для оптимизации производительности: введение в Vue Lazy Component

В этой статье рассказывается об опыте знакомства с фронтенд-бизнесом.проблемы с производительностью,прибытьанализировать,решатьигребеньвнеУниверсальное решение для ленивой загрузки на уровне компонентов Vue 2.x(Vue Lazy Component).

Изначально загружено слишком много ресурсов

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

初始加载了155个请求
Изначально загружено 155 запросов

На момент начальной загрузки было запрошено 155 ресурсов, а запрошенная водопадная диаграмма почти равна длине страницы 😊

请求概况
Обзор запроса

Слишком много изначально загруженных ресурсов приводило к тому, что страница тратила много времени на загрузку подресурсов после domInteractive, из-за чего время загрузки страницы сильно увеличивалось, достигая 5,6 с.

PerformanceNavigationTiming 信息
Информация о производительности и навигации

Давайте посмотрим, что это за подресурсы.По типу запрашиваемых ресурсов мы обнаружили, что наиболее типичными являются картинки, что очевидно.Везде на странице большие картинки, за ними идут js файлы, которые генерируются сторонними бизнес-плагинами и составлены некоторые интерфейсы JSONP.

请求资源类型分布
Распределение типа ресурса запроса

анализ проблемы

页面结构拆分
Разделение структуры страницы

Вернувшись на исходную страницу, в сочетании с приведенными выше данными, мы пришли к выводу о проблеме на этой странице:

  • Страница состоит из большого количества модулей
  • Каждый модуль частично поддерживается домашней страницей, а частично — бизнес-стороной с помощью подключаемых модулей.
  • Все модули загружаются одновременно
  • В модуле много картинок
  • Каждый модуль имеет множество зависимых ресурсов (включая файлы js, файлы интерфейса, файлы css и т. д.)

Решения

Мы предлагаем следующие два основных решения:

Компонентная идея «разделяй и властвуй»

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

  • Разделите каждый модуль на детализированность компонентов
  • Инкапсулируйте все ресурсы, от которых зависит компонент, для вызова внутри компонента.

приоритет загрузки

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

  • Приоритетная загрузка видимых модулей выше сгиба
  • Остальные невидимые модули загружаются лениво и загружаются, когда они видны или вот-вот станут видимыми.

С приведенными выше идеями решения мы начинаем думать о конкретной реализации:

Как решить проблему видимости суждения?

Раньше мы отслеживали событие прокрутки и событие изменения размера, чтобы определить, виден ли модуль.Этот код не только громоздкий, но и может вызвать серьезные проблемы с производительностью без устранения дребезга функций.

Теперь у нас есть лучший вариант — IntersectionObserver API, IntersectionObserver позволяет настроить функцию обратного вызова, которая будет выполняться всякий раз, когда цель, элемент и область просмотра устройства или другой указанный элемент пересекаются. Дизайн этого API асинхронный, и он гарантирует, что количество выполнений обратного вызова очень ограничено, и обратный вызов будет выполняться, когда основной поток простаивает, что лучше по производительности и проще в использовании.

http://caniuse.com/#search=IntersectionObserver
http://caniuse.com/#search=IntersectionObserver

В настоящее время он поддерживается современными браузерами, а браузеры более ранних версий могут быть совместимы с полифиллами.

Как быть максимально ленивым с условным рендерингом?

После вынесения суждения об условии загрузки нам нужно решить проблему отсутствия рендеринга, когда условие загрузки ложно, и рендеринга только тогда, когда условие загрузки истинно. Ответ здесь очень прост: используйте инструкцию v-if, предоставленную Vue.js вы можете добиться настоящего ленивого рендеринга.

Если первоначальный рендеринг выполняется после того, как он станет видимым, как он будет отображаться до того, как станет видимым?

Если ничего не отображается, когда условие загрузки признано ложным, это вызовет ряд проблем:

  • Пользовательский опыт относительно плохой, сначала белый экран, а затем внезапно отображается контент.
  • Самое фатальное, что мы считаем, что видимости нужна цель для наблюдения, если все не отрендерить, мы не сможем наблюдать.

Здесь вводится понятие каркасного экрана.Мы делаем компонент, который очень близок к реальному компоненту по размеру и стилю для реального компонента, называемый каркасным экраном.

骨架屏
Скелетонный экран

Функции каркасного экрана:

  • Улучшить восприятие пользователя
  • Гарантированная стабильность переключения
  • Целевой объект, который обеспечивает наблюдения за видимостью

Как улучшить опыт переключения?

Когда реальный компонент начинает рендеринг, ему требуется определенное количество времени и пространства.Время относится ко времени от создания до рендеринга реального компонента, включая время запроса интерфейса, запроса ресурсов и рендеринга. относится ко времени, необходимому для реального компонента в макете страницы. Оставьте только правильное положение, чтобы избежать тряски.

Здесь мы можем использовать встроенный компонент перехода Vue.js для настройки эффектов входа и выхода компонентов скелета и реальных компонентов.Благодаря разумному макету и расположению можно уменьшить дрожание при переключении.
Разрешить определенное время загрузки для реальных компонентов, установив эффекты перехода.

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

Введение в решение для ленивой загрузки компонентов Vue

Адрес проекта на гитхабе:GitHub.com/Thunderwind 2 О/В…

Это общее решение, основанное на вышеизложенном. Далее кратко представлены сведения о функциях, использовании и API, а затем объединены 5 конкретных DEMO для объяснения более сложного использования.

характеристика

  • Поддержка ленивой загрузки, когда компонент виден или вот-вот станет видимым
  • Отложенная загрузка компонентов поддержки
  • Поддержка отображения скелета компонента перед загрузкой компонентов для улучшения взаимодействия с пользователем.
  • Поддержка асинхронной загрузки подпакета компонента отложенной загрузки

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

npm i @xunlei/vue-lazy-component
  • Метод 1 Глобальная регистрация с использованием метода плагина
  • Способ 2 Частичная регистрация
  • Режим 3 Внедрение независимой версии, автоматическая глобальная регистрация

использование

使用方式
Как пользоваться

Props

параметр инструкция тип необязательное значение По умолчанию
viewport Область просмотра, в которой находится компонент. Если компонент прокручивается внутри контейнера страницы, область просмотра является контейнером. HTMLElement true null, представляющий окно
direction направление прокрутки области просмотра,verticalпредставляет вертикальное направление,horizontalпредставляет горизонтальное направление String true vertical
threshold порог предварительной загрузки, единицы css String true 0px
tagName Имя метки внешнего контейнера, обертывающего компонент String true div
timeout время ожидания, если указано время, видимое или нет, автоматически загружаться по истечении указанного времени Number true -

Events

название события инструкция Параметры события
before-init Модуль виден или отсроченный крайний срок приводит к тому, что модуль с отложенной загрузкой готов к загрузке. -
init Начните загружать модуль ленивой загрузки, и скелетный компонент начнет исчезать. -
before-enter Лениво загруженные модули начинают входить el
before-leave Компоненты скелета начинают уходить el
after-leave Компонент скелета ушел el
after-enter Включен режим ленивой загрузки el
after-init загрузка завершена -

DEMO 1 Ленивая загрузка очень длинных страниц

Thunder Wind 2 Oh.GitHub.IO/v UE-lazy-co…

<vue-lazy-component>
    <st-series-sohu/>
    <st-series-sohu-skeleton slot="skeleton"/>
</vue-lazy-component>

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

ДЕМО 2 Отложенная загрузка

Thunder Wind 2 Oh.GitHub.IO/v UE-lazy-co…

延时加载
ленивая загрузка

<vue-lazy-component :timeout="1000">
    <st-series-sohu/>
    <st-series-sohu-skeleton slot="skeleton"/>
</vue-lazy-component>
`

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

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

DEMO 3 пользовательский эффект перехода

Thunder Wind 2 Oh.GitHub.IO/v UE-lazy-co…

自定义过渡效果
Пользовательские эффекты перехода

Если вы чувствуете, что эффект перехода постепенного появления и исчезновения, который поставляется с Vue Lazy Component, слишком уродлив, или вам нужно настроить продолжительность эффекта появления и исчезновения, вы можете изменить эффект перехода, настроив стиль. Этот пример демонстрирует другой эффект перехода, жизненный цикл перехода можно посмотреть в документации компонента перехода Vue.js.

Подпакет веб-пакета DEMO 4

Thunder Wind 2 Oh.GitHub.IO/v UE-lazy-co…

懒加载组件异步加载
Компоненты ленивой загрузки загружаются асинхронно

DEMO1 демонстрирует, как лениво загружать модули, но на самом деле это только задерживает рендеринг модулей и загрузку ресурсов в модулях.Если нам нужно пойти дальше, то даже код самого модуля лениво загружается, так же, как AMD загружает асинхронно на спрос, это также Это может быть сделано.

Здесь вы можете использовать асинхронные компоненты Vue.js для регистрации каждого реального компонента в качестве асинхронного компонента и использовать AMD-версию Webpack's require в фабричной функции асинхронного компонента, чтобы реальные компоненты можно было разделить на независимые пакеты. для загрузки, выхода со страницы.js бандл.

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

Этот пример демонстрирует подход. Vue Lazy Component может передать свойство загрузки реальному компоненту через Scoped Slots перед переключением реального компонента. Реальный компонент может избежать загрузки не по запросу, если он условно отображается в соответствии с этой загрузкой. Это похоже на Vue..js связан с механизмом парсинга компонентов, соответствующий код есть в примере, желающие могут изучить его подробно.

DEMO 5 Ленивая загрузка в определенном окне просмотра

Thunder Wind 2 Oh.GitHub.IO/v UE-lazy-co…

IM场景
мгновенная сцена

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

Здесь я жалуюсь на дизайн $parent и $refs Vue.js.Они не реагируют.Если вам нужно динамически получить $el для этих ссылок на компоненты, вы должны дождаться, пока не произойдет смонтированное событие, поэтому код примера немного громоздко..

Применение эффектов

Прежде всего, хотя дизайн Vue Lazy Component находится на уровне компонентов, его гранулярность может быть большой или маленькой, например разные области страницы, а маленькая — это просто аватар пользователя в DEMO5, поэтому применимость очень сильный, пока есть сценарии с ленивой загрузкой, в основном можно использовать.

Кроме того, с точки зрения терминалов, он не только совместим с проектами на стороне ПК, но также может использоваться на мобильных терминалах.Конечно, проблема совместимости IntersectionObserver API должна быть решена.Адрес полифилла w3c указан в ридми проекта.

Бизнес приложений

В настоящее время мы используем два проекта в Xunlei: один — проект домашней страницы PC Xunlei, а другой — проект командного ускорения PC Xunlei, который, как ожидается, будет распространен на большее количество предприятий на более позднем этапе.

迅雷前端项目
Интерфейсный проект Thunder

Запросить каскадную диаграмму после оптимизации

Рассмотрим ситуацию в начале страницы: после использования технологии ленивой загрузки компонентов количество запросов стало всего 31, а водопадная диаграмма стала короче.

请求数变为31个
Количество запросов становится 31

Сравнение данных

Сравним данные до и после:

  • Количество запросов стало в 1/5 меньше, а эффект от оптимизации более заметен.
  • Размер запроса существенно не уменьшился по сравнению с предыдущим
  • Время загрузки также менее очевидно

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

Последующее направление оптимизации производительности

В дальнейшем мы продолжим оптимизацию этой страницы по двум основным направлениям:

Изменение размера и сжатие изображения

Благодаря кадрированию и сжатию изображений решается проблема, заключающаяся в том, что время загрузки подресурсов с большим размером запрашиваемого ресурса велико и время загрузки увеличивается.

предварительный рендеринг

Используйте подключаемый модуль предварительного рендеринга, чтобы встроить основные css и js страницы, и сгенерируйте каркас экрана с помощью предварительного рендеринга, чтобы избежать проблемы с длинными путями клавиш, видимыми на первом экране SPA, и после того, как страница проанализирует дерево dom, будет виден первый экран.

Ленивая схема загрузки ДОРОЖНАЯ КАРТА

Решение для ленивой загрузки Vue Lazy Component по-прежнему имеет некоторые аспекты, которые недостаточно хороши.Планируется поддержка следующих функций в более поздних младших версиях:

  • Поддержка SSR v1.1.0
  • Модульный тест пользовательского интерфейса v1.2.0
  • Снижение производительности v1.3.0
    • перерисовать
    • FPS

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

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

Наконец, каждый может внести свой вклад, отправив сообщение или PR.Адрес проекта на Github:GitHub.com/Thunderwind 2 О/В….


Пролистайте и обратите внимание на внешний публичный аккаунт Xunlei.