Преднагрузка: Для чего это полезно?

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

Дальнейшее чтение на Smashing:

Несколько недель назад, я поставил поддержку предзагрузки в Chrome Canary, и за исключением неожиданных ошибок он ударит Chrome стабильной в середине апреля. Но что это за предгрузка? Что он делает? И как это может помочь вам?

Ну, <link rel=“preload”> это декларативная директива.

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

Разве у нас этого уже не было?

Вроде, но не совсем. <link rel=“prefetch”>была поддержана в Интернете в течение длительного времени, и имеет достойную поддержку браузера. Кроме того, мы также <link rel=“subresource”> поддерживаем в Chrome в течение некоторого времени. Так что нового в предзагрузке? Чем она отличается от этих других директив? Они все говорят браузеру, чтобы принести вещи, не так ли?

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

<link rel=“prefetch”>является директивой, которая говорит браузеру, чтобы получить ресурс, который, вероятно, будет необходимо для следующей навигации. Это в основном означает, что ресурс будет извлечен с крайне низким приоритетом (так как все, что браузер знает, необходимо в текущей странице является более важным, чем ресурс, который мы думаем, может быть необходимо в следующем). Это означает, что основным примером использования prefetch является ускорение следующей навигации, а не текущей.

<link rel=“subresource”>первоначально планировалось заняться текущей навигацией, но она не сделала этого в некоторых впечатляющих способов. Поскольку веб-разработчик не имел возможности определить, что приоритет ресурса должно быть, браузер (только Chrome и Chromium основе браузеров, на самом деле) загрузили его с довольно низким приоритетом, что означало, что в большинстве случаев, запрос ресурса вышел примерно на то же самое время, что было бы, если подресурсы не было вообще.

Как предзагрузить сделать лучше?

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

  • Браузер может установить правильный приоритет ресурса,так что он будет загружен соответствующим образом, и не будет задерживать более важные ресурсы, ни тег и пометки позади менее важных ресурсов.
  • Браузер может убедиться, что запрос подчиняется правильным директивам Content-Security-Policy, и не выходит на сервер, если он не должен.
  • Браузер может отправлять соответствующие Accept заголовки в зависимости от типа ресурса. (например, реклама поддержки «изображение / webp» при получении изображений)
  • Браузер знает тип ресурса, поэтому он может позже определить, может ли ресурс быть повторно использован для будущих запросов, которые нуждаются в том же ресурсе.

Преднагрузка также отличается, так как она имеет функциональное onload событие (которое, по крайней мере в Chrome, не работает для двух других rel значений).

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

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

Давайте пройдем через них, не так ли?

Загрузка позднеобнаруженных ресурсов

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

Теперь у вас есть средства, чтобы сказать браузеру: «Эй, браузер! Вот ресурс, который вам понадобится позже, так что начните загружать его сейчас».

Это будет выглядеть примерно так:

<link rel="preload" href="late_discovered_thing.js" as="script">

asАтрибут сообщает браузеру, что он будет загружать. Возможные as значения включают в себя:

  • "script",
  • "style",
  • "image",
  • "media",
  • и "document" .

(См. спецификацию для получения полного списка.)

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

Ранняя загрузка шрифтов

Одним из популярных воплощений шаблона «поздних обнаруженных критических ресурсов» является веб-шрифты. С одной стороны, в большинстве случаев они имеют решающее значение для визуализации текста на странице (если вы используете блестящие значения CSS-дисплея шрифта). С другой стороны, они похоронены глубоко в CSS, и даже если предзагрузчик браузера разогнал CSS, он не может быть уверен, что они будут необходимы, пока он также не знает, что селекторы, которые требуют их на самом деле применяются к некоторым из узлов DOM. Хотя в теории, браузеры могли бы понять, что, ни один из них, и если они будут это может привести к ложным загрузок, если правила шрифта получить переопределена дальше вниз по линии, еще раз правила CSS прийти дюйма

Короче говоря, это сложно.

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

<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

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

Кроме того, type атрибут есть, чтобы убедиться, что этот ресурс будет получать только предварительной загрузки на браузеры, которые поддерживают этот тип файла. Сейчас только Chrome поддерживает предварительную загрузку, и он поддерживает WOFF2, но больше браузеров могут поддерживать предварительную загрузку в будущем, и мы не можем предположить, что они также поддерживают WOFF2. То же самое верно для любого типа ресурсов, который вы предзагрузили и какой браузер поддержки не вездесущ.

Динамическая загрузка без выполнения

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

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

Так что вы можете сделать?

Перед предварительной загрузкой, не так много. (В некоторых случаях вы можете eval() содержание сценария, но это не всегда возможно, ни без побочных эффектов.) Но с предварительной нагрузкой вы можете!


var preload = document.createElement("link");
link.href = "myscript.js";
link.rel = "preload";
link.as = "script";
document.head.appendChild(link);

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


var script = document.createElement("script");
script.src = "myscript.js";
document.body.appendChild(script);

Разметка на основе Async Loader

Другой прохладный рубить заключается в использовании onload обработчик для того, чтобы создать своего рода разметки на основе async погрузчик. Скотт Джел был первым, кто экспериментировал с этим, как часть его библиотеки loadCSS. Короче говоря, вы можете сделать что-то вроде:

<link rel="preload" as="style" href="async_style.css" onload="this.rel='stylesheet'">

и получить async загруженных стилей в разметке! Скотт также имеет хорошую демо-страницу для этой функции.

То же самое может работать и для асинсскриптов.

У нас уже <script async> есть, что ты скажешь? Ну, <script async> это здорово, но это блокирует событие onload окна. В некоторых случаях, это именно то, что вы хотите, чтобы это сделать, но в других случаях в меньшей.

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

С предварительной нагрузкой, достижение, что легко:


<link rel="preload" as="script" href="async_script.js"
onload="var script = document.createElement('script');
        script.src = this.href;
        document.body.appendChild(script);">

(Это, вероятно, не очень хорошая идея, чтобы включить длинные функции JS в качестве onload атрибутов, так что вы можете определить, что часть как включив функции.)

Ответная загрузка

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

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

Если вы умны об этом, вы хотите загрузить только один из этих ресурсов, а не оба. И единственный способ сделать это будет загружать их динамически, используя JS. Но, делая эти ресурсы невидимыми для предзагрузчика, и они могут быть загружены позже, чем это необходимо, что может повлиять на визуальный опыт ваших пользователей, и негативно повлиять на ваш балл SpeedIndex.

Что мы можем сделать, чтобы браузер знал об этих ресурсах как можно раньше?

Вы догадались! Преднатяг.

Мы можем использовать предварительную загрузку, чтобы загрузить их заранее,и мы можем использовать его media атрибут так, что только необходимый скрипт будет предустановлен:

<link rel="preload" as="image" href="map.png" media="(max-width: 600px)">

<link rel="preload" as="script" href="map.js" media="(min-width: 601px)">

Заголовки

Еще одна особенность, которая поставляется вместе бесплатно со ссылкой теги является то, что они могут быть представлены как HTTP заголовки. Это означает, что для большинства примеров разметки я показал выше, вы можете иметь заголовок ответа HTTP, который делает то же самое. (Единственным исключением является onload пример, связанный с этим. Обработчик нагрузки не может определиться как часть заголовка HTTP.)

Примеры таких заголовков ответов HTTP могут выглядеть следующим образом:

Link: <thing_to_load.js>;rel="preload";as="script"

Link: <thing_to_load.woff2>;rel="preload";as="font";crossorigin

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

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

Обнаружение функций

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

Все ломается!

Мы не хотим этого. Таким образом, в рамках преднагрузочных усилий мы также изменили спецификацию DOM, чтобы можно было обнаружить ключевые слова, поддерживаемые rel функциями.

Пример функции обнаружения функций может выглядеть примерно так:

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

Не HTTP/2 Push Обложка те же случаи использования?

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

ПРЕИМУЩЕСТВО HTTP/2 Push является возможностью нажатия ресурсов, которые браузер еще не отправил запрос. Это означает, что Push может отправлять вниз ресурсы, прежде чем HTML даже начали отправляться в браузер. Он также может быть использован для отправки ресурсов вниз на открытом подключении HTTP/2, не требуя ответа, на котором могут быть прикреплены заголовки HTTP Link.

С другой стороны, предварительная загрузка может быть использована для разрешения случаев использования, которые HTTP/2 не может. Как мы видели, при предварительной загрузке приложение знает о загрузке ресурсов и может быть уведомлено после полной загрузки ресурса. Это не то, что HTTP/2 Push был разработан, чтобы сделать. Кроме того, HTTP/2 Push не может быть использован для сторонних ресурсов, в то время как предварительная загрузка может быть использована для них так же эффективно, как она будет использоваться на ресурсах первой стороны.

Кроме того, HTTP/2 Push не может принимать во внимание состояние кэша браузера и неглобальное состояние файлов cookie. В то время как состояние кэша может быть решено с новой спецификацией дайджеста кэша,для неглобальных файлов cookie нет ничего, что можно сделать, поэтому Push не может быть использован для ресурсов, которые полагаются на такие файлы cookie. Для таких ресурсов, предварительная загрузка ваш друг.

Еще один момент в пользу преднагрузки заключается в том, что он может выполнять переговоры по содержимому, в то время как HTTP/2 Push не может. Это означает, что если вы хотите использовать Client-Hints, чтобы выяснить правильное изображение для отправки в браузер, или Accept: заголовки для того, чтобы выяснить лучший формат, HTTP/2 Push не может помочь вам.

Сооо…

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

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

Источник: smashingmagazine.com

Великолепный Журнал

Великолепный, сокрушительный, разящий (см. перевод smashing) независимый журнал о веб-разработке. Основан в 2006 году в Германии. Имеет няшный дизайн и кучу крутых авторов, которых читают 2 млн человек в месяц.

Добавить комментарий

%d такие блоггеры, как: