задний план
Просмотр новостей и чтение информации, как контент-приложения, всегда были основным требованием пользователей Toutiao. Скорость открытия страницы напрямую связана с основным опытом пользователя при использовании Toutiao. Унификация опыта, мы несем содержание страницы сведений через WebView, но производительность самого WebView хуже, чем у Native, поэтому техническая команда Toutiao работает над оптимизацией скорости загрузки страницы сведений.
После непрерывной оптимизации страница обновления в настоящее время открыта онлайн в заголовках сегодня, что в основном менее заметно невооруженным глазом. В этой статье мы постепенно разберем и представим наши идеи и практики по оптимизации загрузки на странице подробностей.
Давайте посмотрим на эффект до и после оптимизации~
Страница сведений о сегодняшнем заголовке перед оптимизацией загрузки
После оптимизации загрузки страницы сведений Toutiao
создание данных
представление
Прежде чем мы начнем оптимизировать скорость загрузки страниц, нам нужно прояснить вопрос, с каким временем загрузки страниц на самом деле сталкиваются пользователи. Сначала мы можем взглянуть на следующую формулу:
页面加载时间 = 页面加载完成时间 - 页面开始加载时间
Хорошее время загрузки начальной страницы определяется, когда пользователь нажимает на фид карты, мы можем считать, что страница начинает загружаться.
Вопрос в том, как определить, что загрузка страницы завершена? С точки зрения клиента, будь то iOS или Android, WebView предоставляет обратный вызов loadFinsih, но в практических приложениях мы обнаружили, что обратный вызов loadFinish не отражает реальный пользовательский опыт.
Вообще говоря, рендеринг WebView должен пройти следующие этапы.
- Разобрать HTML-файлы
- Загружать файлы JavaScript и CSS
- Разобрать и выполнить JavaScript
- Создайте структуру DOM
- Загрузка ресурсов, таких как изображения
- страница загружена
На самом деле loadFinish находится на этапе загрузки страницы, и структура страницы в основном визуализируется, когда построение DOM завершено, поэтому с точки зрения реального взаимодействия с пользователем мы берем время, когда построение структуры DOM завершено (т.е. domReady ) как момент завершения загрузки страницы.
белый экран
В процессе просмотра страницы сведений, помимо скорости загрузки страницы, возникает еще одна проблема, которая особенно влияет на взаимодействие с пользователем, а именно белый экран страницы.Это также была проблема, о которой пользователи часто сообщали в первые дни, но есть много сценариев, которые могут привести к странице сведений.Когда возникает белый экран, например сетевое исключение, исключение WebView и т. д., необходимо определить белый экран пользователя с точки зрения взаимодействия с пользователем.
В настоящее время наиболее интуитивно понятным решением, которое я могу придумать, является создание снимка экрана WebView и перемещение значения цвета точек пикселя на снимке экрана.Если точка цвета небелого цвета экрана превышает определенный порог, он может следует рассматривать как не белый экран.В настоящее время нам необходимо рассмотреть эту схему.Вопросы производительности и время обнаружения.
iOS предоставляет интерфейс моментальных снимков WebView для получения содержимого, отображаемого текущим WebView. Нижний уровень использует метод реализации асинхронного обратного вызова. API занимает около 10 мс, и пользователь в основном не знает.
- (void)takeSnapshotWithConfiguration:(nullable WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(UIImage * _Nullable snapshotImage, NSError * _Nullable error))completionHandler API_AVAILABLE(ios(11.0));
Интерфейс, предоставляемый системой Android для получения содержимого представления, — это getDrawingCache, API занимает около 40 мс, и потеря производительности не особенно велика.
В дополнение к потере производительности скриншотов, обнаружение точки пикселя также является трудоемкой сценой при обнаружении белого экрана.После экспериментов мы уменьшили скриншот WebView до 1/6 исходного изображения и прошлись по пикселям обнаруженного изображения. Когда количество точек в пикселях больше 5%, мы считаем, что это не белый экран, и мы можем относительно эффективно обнаружить и точно определить, появился ли белый экран на странице сведений.
Установление индикатора
После определения калибра нам еще нужно уточнить, какие показатели могут отражать реальный опыт пользователей, когда они чистят заголовки.
В первые дни мы использовали среднее время загрузки страницы страницы сведений, которое представляет собой сумму времени загрузки страницы/страницы pv. В начале этот показатель действительно может определять нашу скорость загрузки.
Позже, когда оптимизация загрузки страницы сведений будет постепенно углубляться, будет обнаружено, что, хотя среднее время загрузки может также отражать скорость загрузки страницы сведений, поскольку pv страницы сведений относительно высока, если средняя скорость загрузки используется для улучшения многих проблем с пользовательским интерфейсом, будет усреднено. , не отражает реальную ситуацию пользователей. Позже мы скорректировали калибр и скорректировали показатель до значения 80-го процентиля всех пользователей, заходящих на страницу сведений. Например, если значение 80-го процентиля скорости загрузки страницы сведений заголовка составляет 1 секунду, то это показывает, что в 80% случаев пользователь может загрузить страницу сведений в течение 1 с. Конечно, после нашей непрерывной оптимизации значение 80-го процентиля загрузка страницы сведений может достигать 0,3 с, то есть в 80% случаев пользователь может находиться в0.3sЗавершено в пределах загрузки страницы.
Позже мы обнаружили, что даже данные 80-го процентиля не могут отражать реальную ситуацию многих пользователей с длинным хвостом при величине страницы с подробностями заголовка.Чтобы добиться более высокой производительности загрузки страницы сведений, мы, наконец, поместили страницу сведений , Калибр производительности был скорректирован до 95-го процентиля. До сих пор, благодаря нашим усилиям, 95-й процентиль скорости загрузки сегодняшней страницы сведений о заголовках также был оптимизирован почти на 80%. Что именно мы сделали, будем вводить постепенно.
Оптимизация шаблона
Разделение шаблона
Как упоминалось ранее, страница сведений о графике размещается в WebView, и самый простой способ разместить страницу в WebView — загрузить онлайн-страницу непосредственно через URL-адрес. Итак, давайте начнем с простого вопроса: что происходит, когда пользователь вводит URL-адрес из браузера на отображаемую страницу?
Процесс рендеринга страницы был представлен ранее, а теперь давайте кратко рассмотрим следующие этапы, которые должен пройти пользователь от клика до просмотра содержимого страницы:
Видно, что каждый раз, когда пользователи заходят на страницу сведений через онлайн-загрузку страниц, им приходится несколько раз загружаться по сети, что чрезвычайно восприимчиво к сетевым колебаниям.В этом случае время и вероятность загрузки страницы не могут быть гарантировано влияет на пользовательский опыт.
Таким образом, в Toutiao мы разделили заголовок и основной контент в новостях и извлекли общий стиль CSS и логический JS страницы сведений Toutiao, чтобы сформировать независимый и полный шаблон страницы сведений, чтобы мы могли напрямую встроить его в клиент.
В то же время мы завершим отображение страницы подробностей, внедрив данные содержимого тела на страницу через JS-скрипт, согласованный с интерфейсом, Таким образом, мы можем поставить интерфейс на запрос клиента.
Таким образом, когда пользователи входят на страницу сведений, им нужно только локально загрузить шаблон, а при загрузке шаблона они также могут параллельно запрашивать данные страницы сведений, а затем вставлять данные в шаблон.
Затем пользователю нужно только пройти следующие этапы после нажатия, чтобы увидеть содержимое страницы:
Как показано на изображении выше, нам нужно только передать сетевую нагрузку, чтобы завершить рендеринг страницы.
Может быть быстрее? Конечно!
Чтобы улучшить скорость загрузки страницы, клиент использует определенную стратегию для предварительной загрузки данных новостей, так что в идеальном состоянии пользователь может напрямую использовать кэшированные данные, когда он видит страницу при входе на страницу, и пользователь может быть полностью в автономном режиме при просмотре новостей, чтобы избежать влияния сети.
Разогрев шаблона
После полного отключения от сети нагрузки может быть быстрее?
Конечно вы можете! Когда весь процесс находится в автономном режиме, узким местом загрузки страницы становится время загрузки локального шаблона, поэтому следующее, что нам нужно сделать, это оптимизировать время загрузки шаблона.
Для шаблонов мы делаем две вещи
-
Слияние шаблонов.Обычно WebView должен загружать JS и CSS в HTML после загрузки основного HTML, что требует нескольких операций ввода-вывода, поэтому мы встраиваем JS, CSS и некоторые изображения в один файл, поэтому при загрузке шаблона выполняется только одна операция ввода-вывода требуется, и проблема сбоя загрузки шаблона из-за конфликтов загрузки ввода-вывода значительно снижается.
-
Упрощение шаблона, мы асинхронно подтягиваем некоторые ненужные скрипты, упрощаем ненужные стили и коды JS и уменьшаем размер шаблона более чем на 20%
Благодаря приведенной выше оптимизации мы значительно оптимизировали время загрузки шаблона, но может ли он быть более мощным? Это все еще возможно.
Для клиента, когда шаблон отделен от данных, каждый раз при клике пользователя загружается один и тот же шаблон, поэтому по сути нам не нужно создавать WebView и загружать шаблон при входе пользователя на страницу, нам нужно только для создания WebView в фоновом режиме в нужное время, а также для предварительного нагрева и загрузки шаблона Когда пользователь щелкает, чтобы войти на страницу, WebView, загрузивший шаблон, может использоваться для прямой вставки данных содержимого страницы сведений на страницу через JS. Внешний интерфейс может отображать страницу после получения данных.
На этом этапе пользователю больше не нужно перезагружать шаблон при входе на страницу сведений, и путь становится следующим:
Можно видеть, что эффект оптимизации предварительного нагрева шаблона и предварительной выборки данных через локальный тест относительно очевиден, и эффект проверки на приведенном выше снимке экрана в основном был достигнут.
Повторное использование шаблона
После того, как мы разделили шаблон и данные, оптимизация данных стала более очевидной, но мы сказали, что в дополнение к данным проверки нам также нужно смотреть на данные реального опыта онлайн-пользователей.Начиная с 95-го процентиля, фактическая оптимизация данных не очень хорошо.Очевидно, поэтому мы наблюдаем из данных, что частота попаданий пользовательского шаблона прогрева составляет всего 53%, и еще есть возможности для дальнейшего улучшения.
Чтобы максимально повысить скорость загрузки страницы, мы надеемся, что пользователи смогут использовать предварительно нагретый шаблон WebView каждый раз, когда они заходят на страницу сведений.В общем, мы будем использовать предварительно созданный пул шаблонов для оптимизации при входе пользователей страница с подробной информацией.
Но на самом деле во многих случаях создание WebView является операцией с относительно высокими затратами на производительность.Если мы используем схему предварительно созданного пула, то WebView будет часто создаваться в фоновом режиме, что будет иметь определенную степень просмотра пользователем опыт работы на сцене подачи.
Более того, если пользователь часто и быстро заходит на страницу сведений и выходит из нее, он может легко столкнуться со сценой, в которой шаблон предварительного нагрева не может быть затронут в реальной сцене.
В настоящее время, чтобы оптимизировать взаимодействие с пользователем, как упоминалось выше, мы каждый раз используем один и тот же шаблон, поэтому после того, как мы используем текущий WebView, нам нужно только очистить данные тела, когда пользователь покидает страницу, а затем ввести следующий Когда вы находитесь на странице, вы можете продолжать повторно использовать этот WebView и повторно вводить данные.
С помощью этого метода мы не только избегаем влияния частого предварительного создания веб-представлений в фоновом режиме на опыт пользователя при пролистывании канала, но также увеличиваем процент попаданий шаблона прогрева, когда пользователи заходят на страницу, с 53% до 92%, что оптимизирует взаимодействие с пользователем.
Оптимизация сети
После обсуждения нашей оптимизации в шаблоне WebView давайте представим нашу оптимизацию в запросе контента.
CDN-ускорение
Поскольку запрос страницы сведений о заголовке имеет следующие характеристики
- Трафик большой. Как я уже говорил, просмотр новостей является основным сценарием для пользователей Toutiao. Ежедневно Toutiao используют сотни миллионов пользователей, а трафик данных на странице сведений очень велик.
- Атрибуты данных в основном не изменились.В запросе страницы подробностей многие горячие статьи повторно отображаются и вычисляются.Текст, заголовок, информация об авторе, управление изображением, а также некоторые стили и бизнес-логика рендеринга в основном неизменны.Эта часть повторный расчет требует больших затрат, пропускная способность и ресурсы сервера относительно не нужны.
- Широкое распространение пользователей, сетевые условия трудно гарантировать большое количество заголовков пользователей, охватывающих различных сетевых операторов и состояние сети, качество сети не может быть хорошей гарантией. Данные могут быть кэшированы в узлах CDN по всему краю, крайний доступ к ближайшим пользовательским узлам, избегание длительной передачи по сети не может гарантировать качество общедоступной сети, тем самым улучшая коэффициент успеха и скорость ответа.
- Данные интерфейса велики Из-за существования текстовых данных данные, возвращаемые интерфейсом, часто очень велики Если они возвращаются каждый раз в режиме реального времени, нагрузка на сеть будет относительно большой, а полоса пропускания может быть заполнена и другие службы могут быть затронуты.
Поэтому мы разделяем данные содержимого страницы сведений на две части: статическую и динамическую, и размещаем практически неизмененный контент, который в основном потребляют пользователи, например основной контент, заголовок и столбец автора, в CDN.
Полное название CDN — Content Delivery Network, то есть Content Delivery Network. Его цель состоит в том, чтобы добавить новый уровень сетевой архитектуры в существующий Интернет и опубликовать содержимое веб-сайта на «крае» сети, ближайшем к пользователю, чтобы пользователь мог получить требуемый контент поблизости и улучшить скорость отклика. пользователь посещает веб-сайт. . CDN отличается от зеркалирования тем, что он умнее зеркалирования, или его можно использовать как аналогию: CDN = умнее зеркалирование + кеширование + перенаправление трафика. Следовательно, CDN может значительно повысить эффективность потока информации в сети Интернет. Технически он комплексно решает проблемы малой пропускной способности сети, большого количества посещений пользователей и неравномерного распределения торговых точек, а также повышает скорость отклика пользователей, посещающих веб-сайт.
После размещения в CDN пользователи по всей стране могут получать данные страницы сведений непосредственно с лучшего узла, что также значительно снижает затраты на пропускную способность.
аварийное восстановление
1. Мультидоменное резервное копированиеЧтобы предотвратить сбой CDN и вызвать лавину обслуживания, сервер выдаст несколько ссылок CDN.Когда пользователь ненормально обращается к текущему узлу CDN, он может быстро и автоматически переключиться на следующий узел CDN.
2. Быстрое время ожиданияОбщая политика тайм-аута, клиент будет проходить через CDN 1, 2, 3 при выполнении запроса. Если все эти запросы CDN терпят неудачу, весь сетевой запрос считается неудачным.
Но проблема с этим решением в том, что тайм-аут для запроса CDN составляет 15 секунд. В случае сбоя CDN 1 потребуется 15 с для переключения на CDN 2, что неприемлемо для времени загрузки страницы сведений.Если сеть пользователя внезапно ухудшится, потребуется 45 с, чтобы вернуться на страницу ошибки отображения сбоя.
Исходя из этого, мы разработали быструю стратегию динамического тайм-аута для запросов страниц с подробностями.
- Время ожидания для одного запроса к CDN, рассчитанное на основе значения последнего успешного запроса CDN с коэффициентом 1,5 (z-значение). И минимум 1 с (значение x), а максимум 4 с (значение y). Если оно превысит это время, оно не будет отменено, и будет запрошен следующий CDN напрямую.
- Один запрос к CDN имеет жесткое время тайм-аут 4S (W, сколько нужно быть> = y), после чего запрос отменяется. После того, как все запросы N CDN отменены, сообщается, что пользователь не удался.
Несколько случаев:
- Первый CDN внезапно зависает (при условии, что последний успешный запрос занял a) Следующий запрос: первый CDN скоро истечет (a _ 1,5); начните запрашивать второй CDN (время ожидания равно _ 1,5, но на самом деле запрос будет вернуться через b секунд). На этот раз пользователь ждет a _ 1,5 + b следующих двух запросов: первая CDN скоро истечет (b _ 1,5); начинает запрашивать вторую CDN (время ожидания b _ 1,5, но фактическое c секунд вернет запрос ). Время ожидания пользователя на этот раз составляет b _ 1,5 + c
- Пользователь внезапно попадает в среду с плохой сетью (при условии, что последний успешный запрос занял a) Следующий запрос: 1-я CDN быстро истекает (a_1.5); начинает запрашивать 2-ю CDN (a_1.5) Также истекло время ожидания; начал запрашивать третью CDN ( а_1.5). Последний запрос завершится ошибкой после _ 3 + w (это значение будет в пределах 12 с).
Можно видеть, что благодаря стратегии многодоменного резервного копирования и быстрого тайм-аута, даже если сеть или служба не работают, пользователи могут быстро восстановиться или сообщить пользователям о своих собственных сетевых проблемах.
Оптимизация рендеринга
Когда мы максимально оптимизируем уровень шаблона и сетевой уровень, нас ограничивает скорость рендеринга WebView!
Предварительный рендеринг на стороне сервера
Обычно обычными данными контента могут быть данные, такие как JSON.После того, как клиент получает данные, он вводит данные во внешний интерфейс.Внешнему интерфейсу также необходимо собрать данные JSON с шаблоном, скомпоновать теги HTML и другие шаблоны, а затем визуализировать их во внешнем интерфейсе.Визуализация WebView занимает много времени во внешнем интерфейсе.
Чтобы повысить эффективность первого экрана пользователя, мы собираем все HTML-данные тела страницы сведений на стороне сервера. Путем внедрения контента непосредственно со стороны сервера на страницу его можно напрямую отображать в WebView. , Переданный контент (например, связанные поиски) интерфейс будет выполнять вторичную асинхронную обработку для повышения эффективности работы пользователя.
рендеринг на стороне клиента
Вообще весь контент в нашем тексте рендерится через WebView, после вышеописанной оптимизации эффективность рендеринга текстовой части статьи уже очень высока, но в реальных сценариях многие статьи будут содержать больше картинок и видео сцен.
В реальных сценариях рендеринг нетекстового содержимого WebView будет иметь следующие проблемы:
- По сравнению с текстовым содержимым рендеринг нетекстового содержимого, такого как изображения и видеоресурсы, менее эффективен для WebView.
- В сцене, где в статье много изображений на странице сведений, также возникают проблемы с использованием памяти рендеринга и скольжением WebView.
- Наконец, если пользователь открывает одну и ту же статью несколько раз, у изображений в этой статье также будет проблема многократной загрузки, которую нельзя кэшировать и передать клиенту, что также является пустой тратой трафика пользователя.
Поэтому на странице сведений мы будем рендерить нетекстовый контент, такой как картинки и видео, на стороне клиента через нативные компоненты, которые могут не только повысить эффективность рендеринга, но и снизить ненужное потребление трафика.
Еще одно преимущество встроенного рендеринга заключается в том, что изображения все чаще становятся важной частью статьи.Для статей с несколькими изображениями мы также можем интеллектуально загружать изображения, требуемые страницей сведений, на странице ленты, чтобы улучшить впечатление пользователя от первого экрана. статья.
Оптимизация белого экрана
После разговора об оптимизации производительности я поделюсь некоторыми оптимизациями скорости белого экрана на странице сведений.На самом деле, большинство проблем с белым экраном, о которых сообщают многие пользователи, могут быть связаны с сетью и другими проблемами, из-за которых страница загружается в течение долгое время, что приводит к пользовательскому опыту Экран белый, и эту часть можно решить с помощью методов оптимизации производительности, описанных выше, поэтому ниже приведено лишь краткое введение в некоторые проблемы с белым экраном, которые не вызваны сетью.
После обнаружения белого экрана и анализа данных после составления отчета мы обнаружили, что проблема с белым экраном на странице сведений, вызванная причинами, не связанными с сетью, обычно связана с загрузкой WebView.
В iOS мы используем WKWebView, предоставляемый системой.WKWebView — это компонент, работающий в независимом процессе, поэтому, когда память, занимаемая WKWebView, слишком велика, процесс WebContent, в котором находится WKWebView, будет уничтожен системой, что отражается в пользовательском опыте Просто белый экран.
Согласно онлайн-практике, мы можем перезагрузить текущую страницу с помощью метода reload в функции обратного вызова webViewWebContentProcessDidTerminate, предоставляемой WKWebView, но эта ситуация применима только к запросам, загруженным через loadRequest.На странице сведений из-за использования шаблонного WebView перезагрузка может только повторно загрузить шаблон и не может нормально восстановить всю страницу сведений.Клиенту необходимо перезагрузить шаблон, а затем повторно ввести данные.
Кроме того, поскольку у нас есть логика предварительного нагрева шаблона, используемый WKWebView мог давать сбой при входе на страницу сведений. При вызове JS для ввода данных он напрямую возвращает ошибку. В случае сбоя мы попытаемся перезагрузить шаблон. Но потом обнаружилась проблема в самой работе: если метод вставки данных вызывается напрямую, то ждать, пока системный WebView вернет неудавшийся callback, придется долго, поэтому интерфейс для вставки данных тоже настраивается позже .Заранее судим о наличии данных во внедряемом скрипте.Если внедряемого интерфейса нет, значит проблема с шаблоном, и можно просто попробовать еще раз.
В Android мы используем ядро собственной разработки WebView, и тоже сталкиваемся с некоторыми странными ямами.
- Проблема многопоточного чтения файлов шаблона, шаблон файла, который WebView будет читать во время работы, если другой поток одновременно обновит файл шаблона, будет проблема с загрузкой шаблона, поэтому необходимо обеспечить атомарность загрузка шаблона
- Проблема зависания рендеринга, ядро представляет собой относительно сложную логику, и проблема зависания рендеринга возникает в редких случаях внутреннего рендеринга.Однако в пределах порядка общего пользователя страницы сведений, даже если это только один из 100 000 , это очень сложно для пользователя Это также относительно большая проблема.В это время мы будем проводить мониторинг белого экрана от бизнеса и попробуем еще раз.
Конечно, будь то iOS или Android, логика загрузки WebView более сложна, и иногда независимо от того, как повторить попытку, она не увенчается успехом.В это время мы сразу перейдем на страницу сведений о загрузке онлайн, и отдавать приоритет обеспечению опыта пользователя.
Суммировать
Из-за нехватки места мы также сделали много других вещей, включая оптимизацию запросов, предварительную загрузку push-статей, оптимизацию методов вставки данных и т. д. Мы также провели много исследований в других направлениях. Поделитесь со всеми.
Наконец, подытожим некоторые наши мысли после оптимизации скорости открытия страницы сведений.
- данные имеют значение, первое, что мы сделали перед оптимизацией скорости загрузки, это фактически установили доску данных для страницы сведений, Только с помощью данных мы можем по-настоящему понять текущий статус онлайн-пользователей и найти узкие места и точки оптимизации на основе опыта реальных пользователей.
- Сначала пользовательский опыт, существует множество схем оптимизации, помимо скорости загрузки, также необходимо выбрать оптимальную для пользователя схему из общего опыта работы с приложением
- Преследовать конечной, На самом деле первоначальная оптимизация относительно проста, но чем она сложнее, тем больше деталей требуется для достижения максимального пользовательского опыта.
поделиться больше
Анализ проблем с памятью камеры Android
Эволюция архитектуры собственной системы потокового воспроизведения ByteDance.
Большая расшифровка iOS: таинственный и загадочный КВО
Сегодняшний заголовок Оптимизация скорости компиляции Android «второго уровня»
Техническая команда Toutiao
Сегодняшняя техническая команда Toutiao не только стремится постоянно углубляться в бизнес, но и добивается максимального удобства пользователей в технологиях.
Если вы также стремитесь к росту в бизнесе со 100 миллионами DAU и ожидаете быстрого улучшения технологий, добро пожаловать к нам.
Независимо от того, являетесь ли вы iOS/Android/front-end/back-end, мы ждем вас в Шэньчжэне/Пекине/Гуанчжоу, чтобы вместе делать более сложные вещи! Электронная почта для доставки резюме:tech@bytedance.com;заголовок письма:Название-годы работы-Техническая команда Toutiao.
Добро пожаловать в техническую команду ByteDance