Автор этой статьи: Бэнг, старший эксперт по разработке беспроводных сетей в Ant Financial.
Введение Алимей: Все больше и больше бизнес-приложений реализуется с использованием H5. Как ускорить запуск страниц H5 — это технический вопрос, который изучают многие люди. клиент. Давайте обсудим, какие схемы оптимизации доступны для вашей справки.
С постоянным повышением производительности мобильных устройств производительность веб-страниц постепенно становится приемлемой, и из-за многих преимуществ модели веб-разработки (кроссплатформенность, динамическое обновление, уменьшение объема, бесконечное расширение) все больше и больше приложений появляются встроенные веб-страницы (чтобы соответствовать текущей популярной поговорке, все веб-страницы ниже называются страницами H5, хотя они могут не иметь отношения к H5), многие приложения изменили некоторые функциональные модули для использования реализации H5.
Несмотря на то, что производительность страницы H5 улучшилась, если некоторые оптимизации не были сделаны целенаправленно, опыт все еще очень плохой.Есть две основные части опыта:
1. Время запуска страницы на белом экране: открытие страницы H5 требует серии операций, будет период времени на белом экране, и опыт будет плохим.
2. Быстрота ответа: из-за механизма рендеринга webkit, одного потока, исторической нагрузки и т. д. производительность обновления/взаимодействия страницы не так хороша, как нативная.
В этой статье не будет обсуждаться второй пункт, только первый пункт, как уменьшить время белого экрана. Для некоторых функциональных модулей, реализованных с использованием H5 в приложении, как ускорить их скорость запуска и сделать их запуск близким к родному.
Обработать
Почему долго появляется белый экран при открытии страницы H5? Потому что он делает много вещей, предположительно:
Инициализировать веб-просмотр -> страница запроса -> загрузить данные -> проанализировать HTML -> запросить ресурсы js/css -> рендеринг dom -> проанализировать выполнение JS -> данные запроса JS -> проанализировать и визуализировать -> загрузить визуализированные изображения
На некоторых простых страницах может не быть этого шага JS, запрашивающего данные, но большинство функциональных модулей должны присутствовать.Согласно текущей пользовательской информации, JS запрашивает соответствующие данные из фона, а затем отображает их, что является обычным методом разработки.
Как правило, страница может отображать прототип после рендеринга dom.До этого пользователь видит белый экран.После загрузки отрендеренного изображения вся страница отображается полностью.Оптимизация открытия первого экрана в секундах заключается в сокращении времени- потребление этого процесса.
Оптимизация внешнего интерфейса
Вышеупомянутый процесс открытия страницы имеет множество моментов оптимизации, в том числе front-end и client-side.Оптимизация производительности обычного front-end и back-end уже имеет лучшие практики в эпоху ПК.Основные из них:
1. Уменьшите объем запросов: слейте ресурсы, уменьшите количество HTTP-запросов, сжатие minify/gzip, webP, lazyLoad.
2. Ускорить запросы: пре-разрешить DNS, уменьшить количество доменных имен, параллельная загрузка, раздача CDN.
3. Кэш: запрос кэша протокола HTTP, манифест автономного кэша, локальное хранилище автономного кэша данных.
4. Рендеринг: оптимизация JS/CSS, порядок загрузки, рендеринг на стороне сервера, конвейер.
Среди них сетевой запрос оказывает наибольшее влияние на скорость запуска первого экрана, поэтому в центре внимания оптимизации находится кэширование Здесь мы фокусируемся на стратегии внешнего кэширования запросов. Давайте разделим его на кеш HTML, кеш ресурсов JS/CSS/изображения и кеш данных json.
Ресурсы HTML и JS/CSS/изображения являются статическими файлами. Сам HTTP предоставляет протоколы кэширования. Браузеры реализуют эти протоколы для кэширования статических файлов.
В общем, кэшей два:
1. Спросить, есть ли обновление: в соответствии с такими протоколами, как If-Modified-Since/ETag, к серверной части делается запрос, чтобы узнать, есть ли обновление, отсутствие обновления возвращает 304, а браузер использует локальный кеш.
2. Напрямую использовать локальный кеш: По полю Cache-Control/Expires в протоколе определить, как долго можно не отправлять запрос на обновление, и напрямую использовать локальный кеш.
Максимальная стратегия кэширования, которую может использовать внешний интерфейс: файлы HTML всегда запрашивают у сервера, есть ли обновление, а файлы ресурсов JS/CSS/Image не запрашивают обновления и используют локальный кеш напрямую. Как обновить файлы ресурсов JS/CSS? Общепринятой практикой является присваивание каждому файлу ресурсов номера версии или хеш-значения в процессе создания.Если файл ресурсов обновляется и номер версии и хеш-значение изменяются, URL-адрес запроса ресурса изменится, и соответствующая HTML-страница будет изменена. обновляться и изменяться. Когда запрашивается новый URL-адрес ресурса, ресурс обновляется.
Кэш данных json может использовать localStorage для кэширования запрошенных данных.Вы можете сначала использовать локальные данные, а затем запросить обновление, которое контролируется внешним JS.
Эти стратегии кэширования могут реализовать полное кэширование файлов ресурсов, таких как JS/CSS, и кэширование пользовательских данных, а также могут напрямую использовать локальные кэшированные данные каждый раз, не дожидаясь сетевых запросов. А вот кеш HTML-файлов делать нельзя.Для HTML-файлов, если время Expires/max-age установлено на долгое время, и долго используется только локальный кеш, то обновление будет несвоевременным.Сеть запрос спрашивает, есть ли обновление, а затем определяет, использовать ли локальные ресурсы.Как правило, стратегия внешнего интерфейса здесь заключается в том, чтобы запрашивать каждый раз.В случае слабой сети время белого экрана, ощущаемое пользователем, все равно будет очень длинный. Таким образом, существует противоречие между «кешированием» и «обновлением» HTML-файлов.
Оптимизация на стороне клиента
Затем наступает очередь клиента. Эпоха рабочего стола ограничена браузером, поэтому страница H5 не может быть оптимизирована. Теперь страница H5 встроена в клиентское приложение, и у клиента больше разрешений, поэтому клиент может выйти за пределы браузера и сделать больше оптимизации.
Кэширование HTML
Давайте сначала поговорим о кешировании.На стороне клиента есть более свободная стратегия кеширования.Клиентская сторона может перехватывать все запросы страниц H5 и сама управлять кешем.За противоречие между "кешем" и "обновлением" вышеуказанного HTML-файл, который мы можем использовать Эта стратегия решает:
1. Перехватить запрос на стороне клиента, кэшировать данные после первого запроса HTML-файла и использовать кэшированные данные напрямую, не отправляя запрос во второй раз.
2. Когда запрашивать обновление? Этот запрос на обновление может свободно контролироваться клиентом.Вы можете использовать локальный кеш, чтобы открыть локальную страницу, а затем инициировать запрос в фоновом режиме, чтобы попросить обновить кеш, который вступит в силу при следующем открытии; вы можете также инициировать запрос в фоновом режиме, когда приложение запускается или в определенное время.Обновления, чтобы увеличить шансы пользователей получить доступ к последнему коду.
Это выглядит идеально. HTML-файл кэшируется с использованием стратегии на стороне клиента, а остальные ресурсы и данные следуют вышеупомянутому методу внешнего кэширования. Такая страница H5 обращается к HTML-ресурсам JS/CSS/Image для второй раз, а затем к данным.Все может быть прочитано непосредственно из локального, не нужно ждать сетевых запросов, и в то же время может максимально поддерживать обновления в реальном времени, решить проблему с кешем и значительно улучшить скорость запуска первого экрана страниц H5.
вопрос
Приведенное выше решение, кажется, полностью решило проблему с кешем, но на самом деле проблем гораздо больше:
1. Нет предварительной загрузки: опыт открытия в первый раз оставляет желать лучшего, и все данные запрашиваются из сети.
2. Кэш неуправляем:Доступ к кешу контролирует системный веб-просмотр, и его логика кеширования не может контролироваться Проблемы включают в себя:
-
Логика очистки не поддается контролю, а объем кеша ограничен.После кэширования нескольких больших изображений важные кэши HTML/JS/CSS могут быть очищены.
-
Дисковый ввод-вывод не может контролироваться и не может быть предварительно загружен с диска в память.
-
Плохой опыт обновления: при обновлении фонового HTML/JS/CSS загружается полный объем данных, объем данных велик, а загрузка в слабой сети занимает много времени.
-
Невозможно предотвратить захват: если HTML-страница взломана оператором или другими третьими лицами, захваченная страница будет храниться в кэше в течение длительного времени.
Эти проблемы можно решить на стороне клиента, но они немного хлопотны.Кратко опишу:
1. Вы можете настроить список предварительно загруженных заранее, чтобы запросить некоторое время для запуска или в приложении, необходимость включения списка предварительно загруженных страниц и ресурсов требуемого модуля H5, также необходимо рассмотреть модуль H5 Страницы, этот список может быть очень большим, также нужны инструменты для генерации и управления предварительно загруженным списком.
2. Клиент может взять на себя кеш всех запросов без стандартной логики кеша веб-просмотра и самостоятельно реализовать механизм кеша, который может разделить приоритет кеша и предварительную загрузку кеша.
3. Инкрементальные обновления могут быть сделаны для каждого файла HTML и ресурсов, но это более проблематично для реализации и управления.
4. Используйте httpdns + https на клиенте, чтобы предотвратить захват.
Вышеупомянутое решение очень громоздкое для реализации. Причина в том, что каждый HTML-файл и ресурсный файл разбросаны и ими трудно управлять. Существует лучшее решение для решения этих проблем, которое представляет собой автономный пакет.
автономный пакет
Поскольку многие проблемы вызваны сложностью децентрализованного управления файлами, и наш сценарий использования здесь заключается в использовании H5 для разработки функциональных модулей, легко подумать об упаковке и выпуске всех соответствующих страниц и ресурсов каждого функционального модуля.Этот сжатый пакет может можно назвать функцию Offline пакета модулей. Используя офлайн-пакетное решение, вышеуказанные проблемы могут быть решены относительно просто:
1. Весь офлайн-пакет можно скачать заранее.Его нужно настроить только в соответствии с бизнес-модулем и не нужно настраивать в соответствии с файлом.Оффлайн-пакет содержит все страницы, относящиеся к бизнес-модулю, и может быть предварительно загружены за один раз.
2. Основной файл автономного пакета и кеш файла ресурса динамического изображения страницы разделены, что может более удобно управлять кешем, а автономный пакет также может быть загружен в память целиком заранее, что сокращает время, затрачиваемое на диск. ИО.
3. Автономный пакет можно легко обновлять поэтапно в зависимости от версии.
4. Автономный пакет доставляется в виде сжатого пакета, который будет зашифрован и проверен одновременно, поэтому операторы и третьи лица не смогут его украсть или подделать.
На данный момент автономный пакет является довольно хорошим решением для использования H5 для разработки функциональных модулей.Давайте кратко рассмотрим решение автономного пакета:
1. Серверная часть использует инструмент построения для упаковки страниц и ресурсов, связанных с одним и тем же бизнес-модулем, в файл и одновременно шифрует/подписывает файл.
2. В соответствии с таблицей конфигурации клиент извлекает автономный пакет в заданное время и выполняет распаковку/расшифровку/проверку.
3. Согласно таблице конфигурации, при открытии услуги она будет перенесена на страницу входа открытия офлайн-пакета.
4. Перехватывать сетевые запросы и напрямую читать файлы, уже существующие в автономных пакетах.
5. Возвращаются данные автономного пакета, в противном случае используется логика кэширования протокола HTTP.
Когда автономный пакет обновляется, данные о различиях между двумя версиями отправляются в фоновом режиме в соответствии с номером версии, а клиент объединяется и постепенно обновляется.
больше оптимизаций
Решение для автономного пакета уже сделало почти то же самое в кэшировании, и оно также может быть оснащено некоторыми подробными оптимизациями:
общедоступный пакет ресурсов
Каждый пакет будет использовать одну и ту же структуру JS и глобальные стили CSS. Дублировать эти ресурсы в каждом автономном пакете слишком расточительно. Вы можете создать общий пакет ресурсов для предоставления этих глобальных файлов.
предварительно загрузить веб-просмотр
Будь то iOS или Android, инициализация локального веб-просмотра занимает много времени, а веб-просмотр можно инициализировать заранее. Существует два типа предварительной загрузки:
1. Предварительная загрузка в первый раз: Инициализация веб-просмотра в первый раз в процессе отличается от второй инициализации.Первый раз будет намного медленнее, чем второй раз. Ожидается, что причина заключается в том, что после первой инициализации веб-представления, даже если веб-представление было выпущено, некоторые глобальные объекты службы или ресурса, совместно используемые несколькими веб-представлениями, не были выпущены, и эти объекты не нужно регенерировать во время вторая инициализация, чтобы сделать это быстрее. Мы можем предварительно инициализировать веб-представление при запуске приложения, а затем выпустить его, чтобы оно было быстрее, когда пользователь фактически переходит к модулю H5 для загрузки веб-представления.
2. Пул веб-просмотров: его можно повторно использовать с двумя или более веб-просмотрами вместо создания нового веб-просмотра каждый раз, когда открывается H5. Однако этот метод должен решить проблему очистки предыдущей страницы при переходе страницы.Кроме того, если есть утечка памяти в JS на странице H5, это повлияет на другие страницы и не может быть освобождено во время работы ПРИЛОЖЕНИЕ.
предварительная загрузка данных
В идеале, когда офлайн пакетное решение открывается в первый раз, все HTML/JS/CSS используют локальный кеш, не дожидаясь сетевых запросов, но пользовательские данные на странице все равно нужно вытягивать в реальном времени. Это можно сделать во время инициализации веб-просмотра. Для параллельного запроса данных требуется некоторое время для инициализации веб-просмотра. В это время нет сетевых запросов. Параллельные запросы в это время могут сэкономить много времени.
С точки зрения конкретной реализации, во-первых, в таблице конфигурации может быть указан URL-адрес, который необходимо предварительно загрузить для офлайн-пакета.Клиент инициирует запрос во время инициализации веб-просмотра.Запрос обрабатывается менеджером, а результат кэшируется, когда запрос завершен, а затем веб-просмотр начинается после инициализации. При запросе предварительно загруженного URL-адреса только что клиент перехватывает запрос и перенаправляет его только что упомянутому диспетчеру запросов. Если предварительная загрузка была завершена, содержимое будет возвращено напрямую, а если нет, то подождет.
Fallback
Если пользователь обращается к модулю автономного пакета, автономный пакет не был загружен или таблица конфигурации обнаруживает, что существует новая версия, но локальная версия является старой версией? Несколько вариантов:
1. Простое решение — синхронно заблокировать и дождаться загрузки последнего автономного пакета, если локальный автономный пакет недоступен или не обновлен. Такой опыт открытия пользователем еще хуже, потому что автономный пакет относительно большой.
2. Также может быть так, что если есть старый пакет локально, то пользователь в этот раз будет напрямую использовать старый пакет.Если нет блокировки и ожидания повторной синхронизации, это приведет к несвоевременным обновлениям и не может гарантировать, что пользователи используют старый пакет Последняя версия.
3. Вы также можете сделать онлайн-версию автономного пакета.Файлы в автономном пакете имеют соответствующий адрес доступа один к одному на сервере.Если локально нет автономного пакета, вы можете напрямую получить доступ к соответствующему онлайн-адресу и откройте онлайн-страницу с традиционной.Таким же образом, этот опыт лучше, чем ожидание загрузки всего автономного пакета, и он также может гарантировать, что пользователи будут иметь доступ к последней версии.
Третий метод резервного копирования также приносит пользу в конечном результате.В некоторых непредвиденных ситуациях, когда офлайн-пакет неверен, вы можете напрямую получить доступ к онлайн-версии, и функция не пострадает.Кроме того, если общедоступный пакет ресурсов не обновляется вовремя, его также можно использовать, когда версия не соответствует.Прямой доступ к онлайн-версии является хорошим итоговым решением.
Вышеупомянутые стратегии также могут быть смешаны, в зависимости от бизнес-требований.
Использование клиентского интерфейса
Если вы используете ajax и localStorage webkit для интерфейсов сети и хранилища, будет много ограничений, которые трудно оптимизировать.Вы можете предоставить эти интерфейсы JS на стороне клиента, и клиент может делать такие вещи, как предварительное разрешение DNS/IP прямое соединение/длинное соединение по сетевым запросам/параллельным запросам и другие более подробные оптимизации, а хранилище также может использовать клиентский интерфейс для выполнения целевых оптимизаций, таких как параллелизм чтения-записи/изоляция пользователя.
рендеринг на стороне сервера
На ранних веб-страницах JS отвечал только за взаимодействие, и весь контент был непосредственно в HTML.На современных страницах H5 многое из контента уже зависит от логики JS, чтобы решить, что отображать, например, ожидание, пока JS запросит данные JSON, а затем объединение его в HTML для создания рендеринга DOM на странице, поэтому рендеринг страницы должен ждать всего этого процесса, это занимает много времени, и сокращение времени, затрачиваемого здесь, также находится в рамках оптимизации белого экрана. .
Метод оптимизации может заключаться в искусственном сокращении логики рендеринга JS, а может быть более тщательным, возвращаясь к исходному, весь контент определяется HTML, возвращаемым сервером, и нет необходимости ждать логику JS, которая называется рендерингом на стороне сервера. Делать ли такую оптимизацию, зависит от ситуации в бизнесе, ведь это приведет к негативным последствиям изменения режима разработки/увеличения трафика/увеличения нагрузки на сервер. Некоторые страницы мобильного QQ используют рендеринг на стороне сервера, который называется динамическим прямолинейным.
наконец
От внешней оптимизации до кэширования на стороне клиента, автономных пакетов и более детальной оптимизации для достижения вышеуказанных целей страницы H5 почти сравнимы с собственным интерфейсом при запуске.
Подводя итог, можно сказать, что общая идея оптимизации такова: кэшировать/предварительно/параллельно, кэшировать все сетевые запросы, пытаться загрузить весь контент до того, как пользователь его откроет, и не делать последовательно то, что можно делать параллельно. Некоторые методы оптимизации здесь требуют полного набора инструментов и поддержки процессов, которые необходимо сопоставить с эффективностью разработки и оптимизировать в соответствии с реальными потребностями.
Кроме того, приведенное выше обсуждение представляет собой схему оптимизации для страниц функциональных модулей H5, которые будут открываться за считанные секунды.В дополнение к функциональным модулям в клиентском приложении другие страницы H5, такие как маркетинговая деятельность/внешний доступ, могут иметь некоторые точки оптимизации, которые не применимо Зависит от ситуации и потребностей. Кроме того, мини-программы WeChat относятся к разряду функциональных модулей, что является почти такой же рутиной.
Здесь обсуждается оптимизация времени запуска первого экрана страницы H5.После вышеуказанной оптимизации трудоемким в основном является только механизм запуска/рендеринга самого веб-просмотра.Эта проблема и последующая проблема беглости ответа относятся к еще одна область оптимизации, то есть такие программы, как RN / Weex, имеют возможность снова исследовать.
Об авторе: Бэнг, в настоящее время работает в Ant Financial, специализируясь на iOS и интерфейсных областях, в основном отвечает за инфраструктуру iOS, включая исследование небольших программ. Я сделал JSPatch, личный блог blog.cnbang.net