Процесс загрузки ресурсов страницы браузера и оптимизация

внешний интерфейс Безопасность JavaScript браузер

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

Процесс загрузки ресурсов браузером

Первые два вопроса:

  • Как браузер узнает, какие ресурсы должны быть загружены?
  • В каком порядке браузер загружает эти ресурсы? Когда браузер перехватывает запрос страницы, он выполняет следующие четыре действия по порядку.
    流程
    Процесс
  1. Во-первых, все ресурсы, которые необходимо загрузить, классифицируются.
  2. Затем в соответствии с политикой безопасности браузера определяется разрешение на загрузку ресурса.
  3. Затем вычисляется и сортируется приоритет загрузки каждого ресурса.
  4. Последним шагом является загрузка ресурсов в соответствии с порядком приоритета загрузки.
Шаг 1: Классификация ресурсов

Браузер Chrome разделяет ресурсы на 14 категорий, как показано в следующей таблице.

тип вводить
kMainResource То есть к этому типу относится основной ресурс, ресурс файла html страницы
kImage Различные ресурсы изображений
kCSSStyleSheet Как следует из названия, это CSS-ресурс каскадной таблицы стилей.
kScript Ресурсы скрипта, такие как ресурсы js
kFont Ресурсы шрифтов, такие как ресурсы набора шрифтов .woff, обычно используемые на веб-страницах.
kRaw Ресурсы смешанного типа, наиболее распространенные ajax-запросы относятся к этому типу ресурсов
kSVGDocument Ресурс файла масштабируемой векторной графики SVG
kXSLStyleSheet Расширенный язык таблиц стилей XSLT — это язык преобразования, вы можете обратиться к w3c XSL для этого типа.
kLinkPrefetch Предварительная выборка ресурсов (предварительная выборка ссылок) для страниц HTML5, например dns-prefetch. Подробности будут даны ниже
kTextTrack ресурс субтитров для видео, т.е.<track>Этикетка
kImportResource Импорт HTML, импорт файла HTML в другие документы HTML, такие как<link href="import/post.html" rel="import" />. Для получения подробной информации см. соответствующую документацию.
kMedia Мультимедийные ресурсы, видео или аудио относятся к этому типу ресурсов
kManifest Ресурсы кэша приложений HTML5
kMock Зарезервированные типы тестов
Шаг 2. Проверка политики безопасности

Политика безопасности контента (сокращенно CSP) — это система белого списка, предоставляемая браузерами. Разработчики могут сообщать браузеру ограничения загрузки и выполнения различных внешних ресурсов с помощью конфигурации для повышения безопасности веб-страниц. Одним из наиболее распространенных приложений является предотвращение XSS-атак путем ограничения загрузки скриптов с ненадежных доменов. Существует два способа настройки CSP. Первый — ограничиться полем Content-Security-Policy заголовка HTTP-запроса страницы. Как показано на рисунке ниже, это заголовок запроса на странице www.google.com:

流程
Процесс
Второй через<meta>метка для установки.<meta>Он настраивается по принципу «ключ-значение». Ниже представлены несколько конкретных примеров применения.

  1. Для предотвращения XSS:
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; style-src nos.netease.com kaola.com;">

вышеscript-srcПредставляет ресурс скрипта;style-srcПредставляет ресурсы стиля;'self'Указывает, что доверенными являются только внешние ресурсы под текущим доменным именем, а все ресурсы под другими доменами будут заблокированы;nos.netease.com kaola.comПредставляет доверие к ресурсам под двумя доменными именами nos.netease.com и kaola.com. Таким образом, значение приведенной выше метки таково: для ресурсов скриптов доверяют только те, которые находятся в этом домене Для ресурсов стилей, помимо этого домена, загружаются два доменных имени nos.netease.com и kaola.com.

  1. Для перехода на обновление протокола запроса сайта (с http на https):
<meta http-equiv="Content-Secur****ity-Policy" content="upgrade-insecure-requests">

вышеupgrade-insecure-requests, что буквально означает: эскалировать все незащищенные запросы. Когда этот метатег добавлен, браузер автоматически обновит все страницы http на https до https. Например, когда нам нужно преобразовать весь сайт с http на https, мы напрямую принудительно отправим запрос в виде SSL-шифрования, такого как https или wss, для большого количества исходных http-ресурсов, не сообщая об ошибке. Конечно, если сервер ресурсов не поддерживает SSL-шифрование, такое как https, ресурс не будет загружен.

  1. Для блокировки смешанного контента:
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">

Смешанный контент (Mixed Content) — это то, о чем говорил второй пример, на https-сайте http-запрос. Этот тип содержимого, смешанный с незащищенным содержимым запроса в защищенной ссылке, называется смешанным содержимым. Когда возникает такой запрос, мы можем найти соответствующее предупреждающее сообщение в консоли браузера, как показано на следующем рисунке.

流程
Процесс
Смешанный контент может ухудшить безопасность и удобство использования веб-сайтов HTTPS. Однако немного обнадеживает тот факт, что браузеры будут напрямую перехватывать и сообщать об ошибках для запросов смешанного режима для типов ресурсов, которые могут представлять большую угрозу безопасности, таких как ресурсы сценария, как показано на следующем рисунке. А вот для изображений, аудио, видео и прочих ресурсов только предупредит, но не предотвратит загрузку.
流程
Процесс
Для веб-сайтов с чрезвычайно высокими требованиями к безопасности вы можете заблокировать все типы запросов незащищенных ссылок с помощью вышеуказанных тегов, чтобы ресурсы, включая изображения, аудио и видео, также были перехвачены, и было сообщено об ошибке. Конечно, есть много других функций для настройки Content-Security-Policy, вы можете пройтиMDNУзнать больше.

Шаг 3: Расчет приоритета ресурсов

Приоритет ресурса делится наУровень 5. По разным данным этоУровень 5может отличаться в описании названия. В основном потому, что сами данные могут бытьсетевой уровень,ядро браузераилидисплей клиентской консолиодно из этих трех направлений. Хотя эти три направленияУровень 5Имена разные, но все они соответствуют один к одному.сетевой уровень, 5 уровней: самый высокий, средний, низкий, самый низкий, бездействующий;ядро браузера, 5 уровней: очень высокий, высокий, средний, низкий, очень низкий;дисплей клиентской консоли, 5 уровней: самый высокий, высокий, средний, низкий, самый низкий;

Следующееядро браузераВ качестве направления исследования давайте представим процесс расчета приоритета ресурсов браузера:

  • Первый шаг — установить приоритет по умолчанию в соответствии с типом ресурса. Для каждого типа браузера ресурсов существует правило приоритета загрузки по умолчанию:
  1. Три типа ресурсов, html, css и шрифт, имеют наивысший приоритет;
  2. Затем ресурс предварительной загрузки (через<link rel=“preload">предварительная загрузка тега), скрипт, запрос xhr;
  3. Потом идут картинки, голос, видео;
  4. Самый низкийprefetchПредварительно загруженные ресурсы.
  • Второй шаг — настроить приоритет в соответствии с некоторыми фактическими правилами. После установки начального приоритета браузер настраивает приоритет в соответствии с фактическими свойствами ресурса и местоположением в документе, чтобы определить окончательный порядок приоритета загрузки. Правила корректировки для нескольких распространенных типов ресурсов следующие:
  1. заXHR-запросРесурсы: будетСинхронный запрос XHRнастроен на наивысший приоритет. Запросы XHR можно разделить на синхронные запросы и асинхронные запросы.Браузер повысит приоритет синхронных запросов до наивысшего уровня, чтобы получить данные как можно быстрее и ускорить отображение страницы.
  2. зарисунокРесурсы: изменит приоритет в зависимости от того, находится ли изображение в видимом представлении или нет. Приоритет ресурсов изображений по умолчанию — Низкий. Чтобы улучшить взаимодействие с пользователем на первом экране, современные браузеры будут вычислять, находится ли ресурс изображения в пределах видимого вида первого экрана во время рендеринга.Если это так, приоритет этой части изображения в ресурсе области просмотра будет повышен до Высокий .
  3. засценарийРесурсы: Браузер разделит сценарий на три категории в соответствии с расположением тегов сценария и атрибутов и соответственно установит приоритет. Во-первых, приоритет всех скриптов с тегом атрибута defer/async будет снижен до Low. Затем сценарии, не добавляющие этот атрибут, можно разделить на две категории в зависимости от того, находится ли сценарий в документе до или после первого изображения, отображаемого браузером. в предыдущем(标记early**)Он будет установлен как высокий приоритет после того, как(标记late**)Будет установлен средний приоритет. На следующем рисунке показаны приоритеты различных ресурсов после расчета приоритета ресурсов, в котором объединены три общих ресурса, упомянутых выше. Красное поле — это тип сценария, фиолетовое поле — тип изображения, а синее поле — запрос XHR. Источник изображениякликните сюда.
    流程
    Процесс
Шаг 4: Загрузите или заблокируйте ресурсы в соответствии с политикой безопасности и приоритетом, рассчитанным выше.

Цепочка критических запросов и оптимизация

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

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

как найти страницуцепочка запросов ключей
  1. Получите ключевые ресурсы изображения с помощью первого снимка экрана. Как показано на рисунке ниже, мы используем первый снимок экрана для получения ресурсов изображения, которые должны быть загружены на первый экран. (в красной рамке)
    流程
    Процесс
  2. пройти черезLightHouseПлагин получает ключевые ресурсы js и css в цепочке запросов ключей.LightHouseДля получения подробной информации о том, как его использовать, нажмитездесьвыяснить. Запустив плагин, можно, наконец, сгенерировать отчет, содержащий подробные отчеты и рекомендации о производительности страницы. Отчет по цепочке запросов ключей показан на следующем рисунке:
    流程
    Процесс
  3. Просмотр приоритета отдельных запросов через консоль браузера Откройте консоль Chrome, перейдите на вкладку Network, вы сможете просмотреть приоритет ресурсов (Priority). Если столбца «Приоритет» нет, вы можете щелкнуть правой кнопкой мыши и выбрать «Приоритет» в раскрывающемся меню. Как показано ниже:
    流程
    Процесс
оптимизацияцепочка запросов ключей

оптимизацияцепочка запросов ключейСпособов много, вот в основном два.

  • Первый: использоватьPreloadиPrefetch.

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

    <link rel="preload" href="test.jpg">
    

    Prefetch: Предварительная выборка включает в себя предварительную загрузку ресурсов, предварительное разрешение DNS, предварительное подключение по http и предварительный рендеринг страницы.

    资源预加载:<link rel="prefetch" href="test.css">
    DNS预解析:<link rel="dns-prefetch" href="//haitao.nos.netease.com">
    http预连接:<link rel="prefetch" href="//www.kaola.com"> 将建立对该域名的TCP链接
    页面预渲染:<link rel="prerender" href="//m.kaola.com"> 将会预先加载链接文档的所有资源
    

    ТакPrefetchиPreloadкакие отличия есть? Конкретно,Preloadсообщить браузеру о предварительном запросе ресурсов, необходимых для текущей страницы, тем самым повысив приоритет запроса этих ресурсов. Например, для тех критических запросов с более низким приоритетом мы можем установитьPrefetchдля повышения приоритета этих запросов.PrefetchЧтобы сообщить браузеру ресурсы, которые пользователь может использовать на других страницах (не на этой странице) в будущем, тогда браузер предварительно загрузит эти ресурсы и поместит их в http-кеш, когда они простаивают, самый распространенный dns-prefetch . Например, когда мы просматриваем страницу A, если мы переходим на страницу B по ссылке на странице A, и некоторые ресурсы на странице B хотят быть загружены заранее как можно скорее, тогда мы можем добавить эти ресурсы на страницу A.Prefetch, то при бездействии браузера эти ресурсы будут загружены. Поэтому для тех ресурсов, которые могут быть использованы на текущей странице, можно использоватьPrefetch, а также для некоторых ресурсов, которые могут быть использованы на некоторых будущих страницахPreload. Если вы посмотрите на приоритет загрузки,Prefetchповысит приоритет запроса; иPreloadРесурсу будет присвоен самый низкий приоритет, и он будет предварительно загружаться, когда браузер бездействует.

    • Плесните в таз с холодной водой: теперь, когдаPrefetchиPreloadС таким мощным эффектом, можем ли мы использовать его с уверенностью? Но на самом деле кроме dns-prefetch очень беспокоит и другая совместимость. В частности, в Safari поддержка этих методов предварительной загрузки практически не реализована из-за строгих требований безопасности Apple.PreloadКак показано на рисунке ниже, обнаружено, что новая версия Chrome поддерживает лучше, но Safari полностью уничтожен.
      流程
      Процесс
      dns-prefetchПоддержка не плохая.
      流程
      Процесс
      PrefetchТот же Сафари был затерт.
      流程
      Процесс
  • Второе: использоватьLocalStorage. Поскольку первый метод предварительной загрузки плохо поддерживает кэширование ресурсов, обычно можно использоватьLocalStorageЧтобы кэшировать некоторые запрошенные данные и результаты, сэкономьте время, затрачиваемое на отправку http-запросов, тем самым улучшив скорость отклика веб-страниц. Этот вид практики широко используется на мобильных терминалах. Ниже описано, как страницы goose, cat и dog используют LS для кэширования запросов.

  • WeChat: Используйте LS для кэширования файлов js. Как показано на рисунке ниже, использовать браузер, чтобы открыть статью публичного аккаунта WeChat, открыть консоль и обнаружить, что даже файл js в Сети не нужно загружать? Смущенный!

    流程
    Процесс
    Когда я переключился на LS, я понял, что весь JS был спрятан здесь!
    流程
    Процесс
    WeChat использует эту технику для кэширования ресурсов js в критическом пути, что значительно ускоряет доступ к странице. Конечно, фактическая реализация не так проста, как кажется на первый взгляд, js помещается в LS при первом доступе к нему, и так просто выполнять его каждый раз, когда он входит и забирает его. , Самое главное — спроектировать механизм обновления кеша. Во-первых, нам нужно через суффикс задать уникальный идентификатор версии кэшируемого js-файла, во-вторых, каждый раз, когда бэкэнду нужно передать файл конфигурации ресурса, фронтенд будет соответствовать идентификатору версии кэшированного в LS файла согласно этот файл конфигурации, чтобы решить, использовать ли кэш LS или повторно отправить запрос на обновление ресурса. Например, этот файл конфигурации в WeChat синхронно выводится на внешний интерфейс через moon_map, как показано на следующем рисунке:
    流程
    Процесс

  • Торговый центр: используйте LS для кэширования критических асинхронных запросов XHR. отДомашняя страница супермаркета TmallНапример: Как показано на рисунке ниже, посмотрите на LS и обнаружите, что он кэширует данные карусели и 10 записей классификации на первом экране.

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

  • JD.com: Используйте LS для кэширования некритических запросов. в версии для ПКГлавная страница JD.comНапример. Jingdong думает наоборот и странным образом применяет другой способ использования LS. То есть вырезать некритические запросы и хранить их в LS. В частности, для данных первого экрана они по-прежнему загружаются и отображаются нормально. Однако для загрузки и рендеринга внешних данных он будет блокировать и вытеснять ресурсы, что влияет на рендеринг верхней страницы. Поэтому HTML/CSS и другие ресурсы не первого экрана извлекаются и помещаются в LS, а при прокрутке страницы до видимой области данные берутся из LS и вставляются в DOM. Это очень похоже на ленивую загрузку текущего модуля. Как показано на рисунке ниже, каждый LS содержит ресурсы HTML/CSS, необходимые модулю.

    流程
    Процесс

P.S.: После волны рекламы набирается фронтенд Netease Koala~ ЗаинтересованоНажмите, чтобы отправить мое резюме

END

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

  1. Посмотрите, как браузер загружает ресурсы из исходного кода Chrome: https://zhuanlan.zhihu.com/p/30558018.
  2. Preload, Prefetch и их приоритет в Chrome: https://yq.aliyun.com/articles/226240
  3. Поговорим об оптимизации загрузки ресурсов браузера: http://qingbob.com/let-us-talk-about-resource-load/
  4. Критический запрос: http://www.zcfy.cc/article/the-critical-request-css-tricks-3843.html.
  5. Прочее: документация MDN и документация Google Web Develop для связанного контента.