Оптимизация производительности веб-страниц — обычная тема во внешнем интерфейсе, но из-за двухпоточной архитектуры апплета WeChat она отличается от традиционной.Web
Страница не то же самое. Итак, сегодня для изучения производительности в небольших процедурах оптимизации микро-канала.
Прежде всего, я хотел бы задать вам вопрос: каков процесс от открытия апплета WeChat до его отображения на домашней странице? (Его можно сравнить с другой распространенной проблемой с фронтендом:Web
страница из вводаurl
Перейдите на страницу, чтобы показать, какой процесс прошел)
1. Процесс запуска
я верю всемWeb
Процесс представления страницы очень ясен. Что касается апплета, вкратце, апплет проходит следующие процессы запуска:
-
инициализация апплета: Среда апплета инициализации WeChat: включая
Js
двигатель иWebView
Инициализировать и внедрить общие базовые библиотеки. Этот шаг выполняется WeChat, и он готов до того, как пользователь откроет апплет.Это предварительная загрузка операционной среды апплета. -
Загрузите пакет кода апплета Загрузите пакет бизнес-кода апплета. Вы загружаете не исходный код апплета, а скомпилированный, сжатый и упакованный код.
-
Загрузить пакет кода апплета После завершения загрузки пакет кода вводится и выполняется. В настоящее время,
app.js
, где находится страницаJs
документы и все другиеrequire
изJs
Файл будет автоматически выполнен один раз, и базовая библиотека Mini Program завершит регистрацию всех страниц. -
Инициализировать домашнюю страницу апплета Извлеките данные, передайте их с уровня логики на уровень представления и визуализируйте их.
2. Оптимизация производительности
Теперь, когда процесс запуска апплета ясен, мы можем проанализировать и оптимизировать производительность каждой ссылки.
2.1 Ссылка для инициализации мини-программы
Поскольку эта ссылка выполняется WeChat, ее выполнение в нижней части апплета занимает много времени, поэтому наши разработчики не могут это контролировать. Известно, что:iOS
Коэффициент инициализацииAndroid
Торопиться.
2.2 Загрузка и загрузка ссылок
Вообще говоря: ссылка для скачивания занимает много времени.
меньше чем1MB
Время загрузки пакета кода можно контролировать в пределах 929 мс (iOS) и 1500 мс (Android).
Тогда наиболее важным моментом для повышения производительности загрузки является контроль размера пакета.
Распространенными способами управления размером пакетов кода являются следующие:
- Оптимизируйте код, удалите бесполезный код
- Уменьшите количество файлов ресурсов, непосредственно встроенных в пакеты кода.
- Картинка размещается на cdn, используя соответствующий формат картинки
Если апплет сложный, а общий объем оптимизированного кода по-прежнему велик, для оптимизации можно использовать загрузку подпакетов.
Принцип таков: При нормальных обстоятельствах код апплета будет упакован вместе, и загрузка будет завершена одновременно с запуском апплета. При принятии субподряда пакет кода апплета можно разделить на несколько: один — «основной пакет», который содержит код страницы и связанные с ним ресурсы, которые будут открыты сразу при запуске апплета; другой — «подпакет». , который содержит остальную часть кода и ресурсов. Таким образом, когда апплет запускается, ему нужно сначала загрузить основной пакет, а затем апплет может быть запущен немедленно. Это может значительно сократить время загрузки пакета кода апплета.
Но в это время возникла другая проблема. Когда мы посещаем страницу субподряда, нам нужно загрузить код субподряда, прежде чем открывать страницу субподряда.Это может ощущаться очевидной задержкой, и опыт относительно плохой.
Мы можем настроитьpreloadRule
Предварительная загрузка подпакетов: откройте домашнюю страницу и автоматически загрузите другие подпакеты после загрузки основного пакета.
Помимо обычных схем субподряда, мини-программы также имеют независимые схемы субподряда. Независимый субподряд — это особый тип субподряда в мини-программах, который может выполняться независимо от основного пакета и других субподрядов. При входе в апплет со страницы в независимом подпакете загружать основной пакет не нужно. Основной пакет будет загружен только тогда, когда пользователь введет обычный подпакет или страницу основного пакета. Мы можем использовать его для некоторых относительно независимых страниц, таких как страницы активности.
2.3 Инициализация ссылки на главную страницу
Когда дело доходит до рендеринга первого экрана, есть несколько предложений по оптимизации:
-
Предварительный запрос: на странице
onLoad
Асинхронные запросы можно инициировать на этапе, не дожидаясь страницы.ready
. Если вы можете предварительно запросить основной асинхронный запрос текущей страницы, когда вы нажимаете, чтобы перейти на главную страницу, эффект будет лучше; -
Эффективно используйте кеш: кешируйте некоторые асинхронные данные с очень низкой частотой изменения, которые можно использовать непосредственно при следующем запуске;
-
Оптимизированное взаимодействие: во время рендеринга первого экрана используйте
loading
Эффект или схематическая диаграмма отображаются, чтобы уменьшить беспокойство пользователя по поводу ожидания.
На самом деле время инициализации страницы примерно состоит из двух частей: начальное время передачи данных страницы и начальное время рендеринга. Среди них время передачи данных относится ко времени с момента, когда данные организованы с логического уровня, до момента, когда уровень представления полностью получен, а объем данных меньше, чем64KB
Общая продолжительность может контролироваться в пределах 30 мс. Время передачи, как правило, положительно коррелирует с объемом данных, и передача чрезмерно больших данных значительно увеличивает это время. Следовательно, уменьшение объема передаваемых данных является эффективным способом сокращения времени передачи данных.
После завершения первоначального рендеринга уровень представления может выполнять обновления пользовательского интерфейса после того, как разработчик вызовет setData.
2.4 Оптимизация setData
2.4.1 Как работает setData
с традиционными браузерамиWeb
Самая большая разница между страницами заключается в том, что апплет основан надвойная нитьМодель:
В этой архитектуре уровень представления используетWebView
В качестве носителя рендеринга и логический уровень состоит из независимыхJavascriptCore
как операционная среда.
Оба являются независимыми модулями и не имеют каналов для прямого обмена данными. Передача данных между уровнем представления и логическим уровнем должна выполняться Native.JSBrigde
Сделайте перенос.
апплет черезsetData
Полный процесс обновления данных для просмотра изменений выглядит следующим образом:
- передача
setData
метод; - Слой логики будет выполняться один раз
JSON.stringify
удалятьsetData
Для непередаваемой части данных данные, которые необходимо передать, преобразуются в строку и встраиваются в определенный сценарий JS и передаютсяevaluateJavascript
Выполните скрипт для передачи данных на слой рендеринга. - После того, как слой рендеринга получит его,
WebView JS
Поток скомпилирует скрипт и войдет в очередь рендеринга, чтобы дождаться обновления данных.WebView
Отрисовка страницы, когда поток простаивает. -
WebView
Когда поток начнет рендеринг, онdata
а такжеsetData
Данные относятся кWXML
На фрагменте получите новое дерево узлов. После нового дерева виртуальных узлов и текущего дерева узловdiff
Сравните, обновите разностную часть в представлении пользовательского интерфейса. Наконец, будетsetData
данные объединены вdata
и замените старое дерево узлов новым деревом узлов для следующего повторного рендеринга.
2.4.2 setData Примечания
Как отмечалось ранее: один разsetData
Приносит два накладных расхода: накладные расходы на связь +WebView
Обновление накладных расходов.setData
Это наиболее часто используемая разработка небольших программ.API
Одна из наиболее вероятных причин проблем с производительностью.
Итак, при использовании необходимо обратить внимание на следующие моменты:
-
Данные, не связанные с отрисовкой интерфейса, лучше не задавать в
data
, рассмотрите возможность установкиpage
под другими полями объекта;this.setData({ a: '与渲染有关的字符串', b: '与渲染无关的字符串' }) // 可以优化为 this.setData({ a: '与渲染有关的字符串', }) this.b = '与渲染无关的字符串'
-
Не звони слишком часто
setData
, следует учитывать, что несколькоsetData
сливаться в одинsetData
передача;this.setData({ a: 1 }) this.setData({ b: 2 }) // 可优化为 this.setData({ a: 1, b: 2 })
Когда вам нужно вызвать setData в часто инициируемых пользовательских событиях (таких как PageScroll , события Resize), разумно используйте функцию debounce и функцию throttling.
Вы также можете разработать свой собственный
diff
алгоритм, повторно инкапсулировать setData так, чтобы вsetData
Перед выполнением пусть обновляемые данные будут такими же, как исходныеdata
данные делаютdiff
Напротив, если то же самое, пропустите выполнение обновления. Подобные пакеты есть у многих фреймворков апплетов. -
Частичное обновление списка При обновлении определенных данных в списке. Не используйте его
setData
Обновить все данные. найти корреспонденциюid
Нижний индекс этого фрагмента данных (index
не изменится), используйтеsetData
Сделайте частичное обновление.this.setData({ `list[${index}]` = newList[index] })
-
Разумное использование компонентов апплета Обновление пользовательского компонента выполняется только внутри компонента и не влияет на другие элементы страницы. Поскольку каждый компонент имеет независимое логическое пространство, данные, среду стиля и
setData
передача. на основе пользовательских компонентовShadow DOM
Дизайн модели, мы можем разместить некоторые страницы на странице, которые должны выполняться с высокой частотойsetData
Обновленные функциональные модули (такие как обратный отсчет, индикатор выполнения и т. д.) инкапсулируются в пользовательские компоненты и встраиваются в страницу. Когда эти пользовательские представления компонентов необходимо обновить, сами компоненты выполняютсяsetData
, сравнительный расчет старого и нового дерева узлов и обновление дерева рендеринга ограничиваются ограниченным числом узлов в компоненте, что эффективно сокращает время рендеринга.Конечно, чем больше пользовательских компонентов вы используете, тем лучше. Каждый раз, когда вы добавляете пользовательский компонент на страницу,
Exparser
Необходимо управлять еще одним экземпляром компонента, и потребление памяти будет больше. Поэтому пользовательские компоненты следует использовать разумно, а дизайн страницы также должен быть осторожным, чтобы не злоупотреблять тегами.
3. Инструменты анализа
На самом деле самое важное для оптимизации производительности — это говорить с данными. Однако в настоящее время в апплете нет полного и зрелого стандарта количественной оценки производительности.В настоящее время для справки доступны следующие инструменты анализа:
-
Инструмент отслеживания производительности WeChat
Andoid 6.5.10
начато, при условииTrace
Инструмент экспорта, разработчики могутTrace Panel
используйте эту функцию. Используйте учебник:Developers.WeChat.QQ.com/mini программа… -
панель производительности Из WeChat
6.5.8
Сначала предоставляется панель производительности, чтобы разработчики знали о производительности апплета. Разработчики могут открыть панель производительности в апплете версии для разработчиков. Открытый метод: войдите в апплет версии для разработки, нажмите кнопку «Дополнительно» в правом верхнем углу, нажмитепоказать окно производительности -
Мониторинг производительности нагрузки На фоне апплета мы видим мониторинг производительности загрузки. Есть три индикатора:
-
Общее время до запуска
-
Время загрузки
-
Время первого рендера
Общее время запуска = время загрузки + время начального рендеринга + другие затраты времени.
После оптимизации данные можно сравнить с помощью вышеуказанных инструментов, чтобы оценить эффект оптимизации.
Основные справочные источники: