Недавно опубликован новый стандарт на технологию Preload (ссылка). Основной задачей этой спецификации было обеспечить возможность тонкого управления логикой загрузки ресурсов страницы разработчиком.
Предыдущие стандарты
Идея об управлении загрузкой не нова. Ранее были разработаны несколько вариантов тегов link с атрибутами subresource, prerender и prefetch. Однако, они работали несколько иначе: с их помощью можно загружать элементы страниц или целые страницы, которые могут потребоваться при дальнейшей навигации по сайту. То есть, браузер отправлял такие запросы с низким приоритетом и в последнюю очередь. Если же нужно повысить приоритет, то решений не было.
Загрузка ресурсов с preload
Что же даёт новая спецификация? Во-первых, теперь загрузка происходит с уточнением, что загружается. Исходя из указанного типа ресурса браузером выставляется приоритет загрузки. Например:
link rel = «preload» href = «/js/script.js» as = «script» >
Зачем нужен Preloader (предзагрузка) для сайта? Плюсы и минусы
link rel = «preload» href = «/fonts/1.woff2» as = «font» type = «font/woff2» crossorigin>
Во-вторых, тип ресурса (as) позволяет браузеру послать правильные заголовки, чтобы сервер мог отправить контент с лучшим вариантом сжатия (например, послать WebP картинки, если браузер их поддерживает).
Во втором примере мы загружаем файл шрифта, при этом указан конкретный формат (WOFF2), который поддерживается не всеми браузерами. Однако, пока поддержка механизма preload совпадает с поддержкой такого формата, проблем не возникает. Текущую поддержку механизма можно посмотреть здесь.
Ускоренная загрузка шрифтов
В качестве примера ускорения сайта с использованием preload можно назвать загрузку глубоко закопанных ресурсов, например, шрифтов. В обычном процессе загрузки браузер должен сначала загрузить CSS-файл с указанием на шрифт, провести парсинг этого файла и только потом поставить в очередь запрос на скачивание файла шрифта.
Если мы укажем preload этого шрифта в коде HTML-страницы, браузер отправит запрос сразу же после разбора HTML-документа, что может быть на несколько секунд раньше, чем в обычном случае. А мы знаем, что подключаемые шрифты являются блокирующими элементами и задерживают отрисовку шрифта на странице, поэтому загрузить их нужно как можно быстрее. Особенно остро эта проблема стоит при использовании HTTP/2, когда браузер отправляет сразу множество запросов к серверу, в результате чего какие-нибудь картинки могут заполнить полосу клиента и загрузка важных ресурсов будет отложена.
Асинхронная загрузка CSS
CSS-файлы всегда блокируют рендеринг страницы, поэтому все CSS-ресурсы, загрузку которых можно отложить, можно загружать как обычные файлы и динамически подключать к странице.
Делается это следующим образом:
link rel = «preload» as = «style» href = «async_style.css» onload = «this.rel=’stylesheet'» >
Preload, prefetch, preconnect для ускорения сайтов
Загрузка JS-кода без исполнения
Также полезным может оказаться предзагрузка кода скрипта на JS, чтобы выполнить его позже.
Это можно сделать с помощью следующего кода:
link rel = «preload» as = «script» href = «async_script.js» onload = «var script = document.createElement(‘script’); script.src = this.href; document.body.appendChild(script);» >
Разбираем различия между HTTP Preload и HTTP/2 Push
HTTP Preload и HTTP/2 Server Push используются для ускорения загрузки веб-приложения. В этой статье мы рассмотрим сходства и различия HTTP Preload и HTTP/2 Push. А также узнаем, когда нужно использовать каждую из них.
Что такое HTTP/2 Push?
HTTP/2 Push позволяет веб-разработчикам определять конкретные ресурсы, которые должны быть переданы клиенту вместе с HTML-документом . Традиционно клиентская сторона, запрашивающая ресурсы у сервера, сначала получает HTML-файл. Затем анализирует его, чтобы определить, какие ресурсы нужно запрашивать далее. После чего на сервер поступают дополнительные запросы.
Но благодаря HTTP/2 Push, сервер может заранее передавать ресурсы еще до того, как клиент проанализирует HTML. Например, есть сайт с файлом index.html и файлом style.css . В этом случае браузер сначала запрашивает index.html , а после его получения и анализа – файл style.css . Но поскольку мы знаем, что клиент все равно будет запрашивать style.css , можно указать серверу отправить style.css одновременно с index.html .
Что такое HTTP Preload?
HTTP Preload – это еще одна технология, которую можно использовать для предварительной отправки определенных ресурсов клиенту. Но директива Preload работает не так, как HTTP/2 Push.
С помощью директивы Preload можно указать браузеру запрашивать определенные высокоприоритетные ресурсы, необходимость которых он определяет только после анализа HTML-файла.
Предположим, что браузер запросил файл index.html . При его анализе браузер обнаруживает, что необходим style.css . А также что в этом CSS-файле есть ссылка на файл font.ttf . Предварительная загрузка позволяет отправлять на сервер запрос одновременно и на style.css , и на font.ttf . Поскольку font.ttf – это ресурс, который понадобится в ближайшем будущем.
Сходства и различия
HTTP Preload и HTTP/2 Push предоставляют браузеру необходимые ресурсы заранее. Тем не менее, существует несколько важных различий между этими технологиями. Например:
- Синтаксис Preload и Push различается. Вы можете использовать директиву Preload, чтобы инициировать Push. Если вы хотите явно предварительно загрузить ресурс, а не вызывать Push, примените команду nopush следующим образом:
Link: rel=preload; ; as=script; nopush
- С помощью Push можно принудительно отправить ресурсы, как только сервер получит первоначальный запрос от браузера. Preload позволяет выполнить предварительную загрузку только после того, как браузер получит и проанализирует HTML-файл.
- Preload позволяет загружать ресурсы со сторонних доменов. С помощью Push можно принудительно отправлять ресурсы только со своих доменов.
- Preload еще не полностью поддерживается браузерами. А Push имеет больше поддержки, поскольку это функция HTTP/2.
Ниже приведена простая диаграмма от Nginx , которая лучше демонстрирует разницу между двумя технологиями.
Когда использовать Preload, а когда Push?
Нельзя применять Preload и Push для ускорения доставки всех используемых ресурсов одновременно. Вместо этого вы должны заранее отправлять только первоочередные ресурсы.
Несколько примеров использования Push :
- Вместо встраивания кода CSS или JavaScript в HTML разместите его в отдельных файлах и принудительно отправьте браузеру.
- Push отлично подходит для оптимизации использования серверных мощностей.
Примеры использования Preload :
- Загрузка критически важного CSS, который поздно обнаруживается в HTML-документе.
- Загрузка изображений из верхней части веб-страницы, на которые ссылается CSS-файл.
- Загрузка шрифтов, на которые ссылается CSS-файл.
Использование Preload и HTTP/2 Push с KeyCDN
KeyCDN поддерживает HTTP/2 Push, если установить заголовок Link с директивой Preload. После этого KeyCDN будет отправлять ресурсы с помощью push:
add_header Link «; as=style; rel=preload»;
Но если вы не хотите использовать push, установите атрибут nopush. Кроме этого, если реализация HTTP/2 не принимает принудительно отправленные ресурсы, клиент будет рассматривать их как обычный предварительно загружаемый (preload) ресурс.
Итоги
HTTP Preload и HTTP/2 Push являются полезными механизмами. Но для эффективного их использования нужно провести проверку изменения скорости загрузки страниц. Не торопитесь и поэкспериментируйте с Preload и Push в своем собственном приложении.
Сергей Бензенко автор-переводчик статьи « Exploring Differences Between HTTP Preload vs HTTP/2 Push »
Пожалуйста, оставьте ваши мнения по текущей теме статьи. Мы очень благодарим вас за ваши комментарии, отклики, дизлайки, подписки, лайки!
Источник: www.internet-technologies.ru
Русские Блоги
PreloadКак новый веб-стандарт, он направлен на повышение производительности и предоставление веб-разработчикам более детального контроля загрузки. Предварительная загрузка позволяет разработчикам настраивать логику загрузки ресурсов без потери производительности, вызванной загрузчиком ресурсов на основе сценариев.
В HTML-коде это выглядит как следующая декларативная директива выборки (declaratiev fetch directive).
По нашим словам, таким образом мы говорим браузеру начать поиск определенного ресурса, ведь мы являемся автором и знаем, что браузер скоро будет использовать этот ресурс.
Отличие от существующих аналогичных технологий
Фактически, что касается предварительной нагрузки, у нас уже есть И поддержка браузеров довольно хорошая.
Кроме того, Chrome также поддерживает 。
Но Preload отличается от двух, Функция состоит в том, чтобы указать браузеру загрузить ресурсы, которые могут быть использованы на следующей странице. Обратите внимание, что это следующая страница, а не текущая. Следовательно, приоритет загрузки этого метода очень низкий (естественно, по сравнению с ресурсами, необходимыми для текущей страницы, ресурсы, которые могут быть использованы в будущем, не так важны), что означает, что роль этого метода заключается в ускорении скорости загрузки следующей страницы. .
Первоначальная цель дизайна заключалась в том, чтобы иметь дело с текущей страницей, но, в конце концов, это была героическая жертва. Поскольку разработчики не могут контролировать приоритет загрузки ресурсов, браузеры (фактически, только Chrome и браузеры на базе Chrome) имеют очень низкий приоритет при обработке таких тегов. Насколько он низок? Скажем так, в большинстве случаев это бесполезно.
Почему Preload лучше
Предварительная загрузка создается для обработки текущей страницы, которая совпадает с субресурсом, но между ними есть тонкие и существенные различия. Предварительная загрузка имеет атрибут as, который позволяет браузеру выполнять действия, недоступные для подресурсов и предварительной выборки:
- Браузер может установить правильный приоритет загрузки ресурсов. Этот метод может гарантировать, что ресурсы загружаются последовательно в соответствии с их важностью. Таким образом, предварительная загрузка не влияет на загрузку важных ресурсов и не позволяет вторичным ресурсам влиять на загрузку самих себя.
- Браузер может гарантировать, что запрос соответствует политике безопасности контента, например, если наша политика безопасности Content-Security-Policy: script-src ‘self’ Браузеру разрешено выполнять сценарий только на своем собственном сервере, а ресурсы внешнего сервера со значением as для сценария загружаться не будут.
- Браузер может отправлять соответствующую информацию заголовка Accept в соответствии со значением as
- Браузер может узнать тип ресурса через значение as, поэтому, когда полученные ресурсы одинаковы, браузер может определить, можно ли повторно использовать ранее полученные ресурсы.
Разница в предварительной загрузке также отражается в событии onload (по крайней мере, в Chrome предварительная выборка и субресурс не поддерживаются). Другими словами, вы можете определить функцию обратного вызова после загрузки ресурса.
Кроме того, предварительная загрузка не будет блокировать событие onload окон, если только запрос ресурсов предварительной загрузки не исходит от ресурсов, которые блокируют загрузку окна.
Сочетая все эти функции, предварительная загрузка дает нам некоторые функции, которые раньше были невозможны.
Ранняя загрузка ресурсов
Основное использование предварительной загрузки — предварительная загрузка ресурсов, хотя большинство ресурсов, основанных на языке разметки, могут быть предварительно загружены браузером (PreloaderУзнайте как можно скорее, но не все ресурсы основаны на языках разметки, например некоторые ресурсы, скрытые в CSS и Javascript. Когда браузер обнаруживает, что ему нужны эти ресурсы, уже слишком поздно, поэтому в большинстве случаев загрузка этих ресурсов вызывает задержку отрисовки страницы.
Введение в предварительный загрузчик Если анализатор HTML встречает синхронный сценарий при создании DOM, он прекращает создание DOM и вместо этого выполняет сценарий. Следовательно, если получение ресурсов происходит только тогда, когда синтаксический анализатор создает модель DOM, вмешательство сценария синхронизации сделает сеть пустой, особенно для внешних ресурсов сценария.Конечно, сценарий на странице может иногда вызывать задержки.
Появление прелоадера призвано оптимизировать этот процесс. Предварительный загрузчик анализирует ранние результаты анализа HTML-документов браузером (этот этап называется «токенизацией») и находит теги, которые могут содержать ресурсы ( tag) и соберите URL-адреса этих ресурсов. Выходные данные этапа токенизации будут отправлены в настоящий HTML-синтаксический анализатор, а собранные URL-адреса ресурсов будут отправлены считывателю (сборщику) вместе с типом ресурса, и считыватель загрузит страницу в соответствии с этими ресурсами. Эффекты нагрузки загружаются последовательно.
Теперь, с предварительной загрузкой, вы можете сказать браузеру с помощью фрагмента кода, подобного следующему: «Эй, браузер! Вы будете использовать этот ресурс позже, загрузите его сейчас».
Функция атрибута as состоит в том, чтобы сообщить браузеру, какой ресурс загружен. Возможные значения as включают:
- “script”
- “style”
- “image”
- “media”
- “document”
Для получения дополнительной информации см.fetch spec
Игнорирование атрибута as или неправильного атрибута as приведет к тому, что предварительная загрузка будет равна запросу XHR. Браузер не знает, что загружено, поэтому он предоставит таким ресурсам очень низкий приоритет загрузки.
Предварительная загрузка шрифтов
Веб-шрифты — это распространенный тип поздно обнаруженных важных ресурсов. Веб-шрифты очень важны для рендеринга текста страницы, но они глубоко встроены в CSS. Даже если предварительный загрузчик анализирует CSS, невозможно определить, действительно ли селектор, содержащий информацию о шрифте, будет применен к узлу DOM. Теоретически эту проблему можно решить, но на самом деле ни один браузер не решил эту проблему. Более того, даже если проблема решена, браузер может предварительно загрузить файл шрифта в разумных пределах.Когда новое правило CSS перезаписывает существующее правило шрифта, предыдущая предварительная загрузка становится избыточной.
Одним словом, это очень сложно.
Но со стандартом предварительной загрузки простой фрагмент кода может обрабатывать предварительную загрузку шрифтов.
Следует отметить, что атрибут crossorigin необходим, даже если ресурс шрифта находится на собственном сервере, поскольку пользовательский агент должен использовать анонимный режим для получения ресурса шрифта.
Атрибут 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);
Приведенный выше код позволяет предварительно загрузить сценарий, следующий код позволяет сценарию выполнять
var script = document.createElement(«script»); script.src = «myscript.js»; document.body.appendChild(script);
Асинхронная загрузка на основе языка разметки
Сначала посмотрите на код
Событие onload предварительной загрузки может изменить атрибут rel после загрузки ресурса, чтобы реализовать очень крутую асинхронную загрузку ресурса.
Скрипты также могут использовать этот метод для достижения асинхронной загрузки.
Разве у нас уже нет ? Хотя это и хорошо, он блокирует событие загрузки окна. В некоторых случаях вам может это понадобиться, но всегда есть случаи, когда вы не хотите блокировать загрузку окна.
Например, вы хотите загрузить фрагмент кода, который подсчитывает просмотры страниц как можно быстрее, но вы не хотите, чтобы загрузка этого кода задерживала рендеринг страницы и влияла на взаимодействие с пользователем. Ключевым моментом является то, что вы не хотите задерживать событие onload окна.
С предварительной нагрузкой это можно сделать за считанные минуты.
Отзывчивая загрузка
preload — это ссылка, по спецификации есть атрибут media (Chrome не поддерживает, но скоро), этот атрибут делает возможной выборочную загрузку.
Что толку? Предполагая, что ваш сайт поддерживает как настольный, так и мобильный доступ, когда вы используете настольный браузер для доступа, вы хотите представить большую интерактивную карту, в то время как на мобильной стороне достаточно статической карты меньшего размера.
Вы определенно не хотите загружать два ресурса одновременно. Сейчас распространенной практикой является динамическая загрузка ресурсов, оценивая текущий тип браузера с помощью JS, но таким образом предварительный загрузчик браузера не может их вовремя обнаружить, что может задерживать время загрузки и влиять на пользователей. Оценка опыта и SpeedIndex.
Как браузер может обнаружить эти ресурсы как можно раньше? Еще предзагрузить!
С помощью Preload мы можем загружать ресурсы заранее, используя атрибут media, браузер будет загружать только необходимые ресурсы.
Еще одна особенность Preload — то, что она может быть представлена через заголовки HTTP. Другими словами, большинство деклараций на основе языка разметки, упомянутых выше, можно реализовать через заголовки ответов HTTP. (Единственным исключением является событие onload. Мы не можем определить функции обработки событий в заголовке HTTP.)
Link: ;rel=»preload»;as=»script» Link: ;rel=»preload»;as=»font»;crossorigin
Этот метод особенно полезен в некоторых сценариях, например, когда лицо, ответственное за оптимизацию, и разработчик страницы — не одно и то же лицо (то есть оптимизатор не может или не хочет изменять код страницы), и еще одним выдающимся примером является внешний механизм оптимизации ( Механизм внешней оптимизации), который сканирует и оптимизирует контент.
Обнаружение функции
Все предыдущие примеры основаны на предположении — браузер в определенной степени поддерживает предварительную загрузку и, по крайней мере, реализует базовые функции, такие как загрузка скриптов и стилей. Но если это предположение не выполняется. Все сойдется.
Чтобы определить, поддерживает ли браузер предварительную загрузку, мы изменили спецификацию DOM, чтобы знать, какие значения поддерживает rel (поддерживается ли rel = ‘preload’).
Что касается того, как проверить, то этого нет в исходном тексте, но есть фрагмент кода на Github для справки.
var DOMTokenListSupports = function(tokenList, token) < if (!tokenList || !tokenList.supports) < return; >try < return tokenList.supports(token); >catch (e) < if (e instanceof TypeError) < console.log(«The DOMTokenList doesn’t have a supported tokens list»); >else < console.error(«That shouldn’t have happened»); >> >; var linkSupportsPreload = DOMTokenListSupports(document.createElement(«link»).relList, «preload»); if (!linkSupportsPreload) < // Dynamically load the things that relied on preload. >
Можно ли использовать HTTP / 2 Push для завершения работы с предварительной загрузкой?
Конечно, нет. Хотя у них есть некоторые схожие характеристики, в целом их отношения дополняют, а не заменяют друг друга.
Преимущество HTTP / 2 Push заключается в том, что он может активно проталкивать ресурсы в браузер, то есть серверу даже не нужно ждать запроса ресурса, чтобы передать ресурсы браузеру.
Преимущество Preload заключается в том, что его процесс загрузки прозрачен: после загрузки ресурса или возникновения исключения приложение может получать уведомления о событиях. Это то, чего нет в HTTP / 2 Push. Кроме того, Preload также может загружать сторонние ресурсы, но HTTP / 2 Push — нет.
Кроме того, HTTP / 2 Push не может учитывать кэш браузера и неглобальные файлы cookie. Другими словами, контент, отправленный сервером, может уже существовать в кэше клиента, что приводит к бессмысленной передаче по сети. (Однако новая спецификация направлена на решение этой проблемы -cache digest specification, Легкий веб-сервис на GithubH2OВ устройстве реализована эта функция, в H2O введены файлы cookie.cache-aware server push, Принцип состоит в том, что после завершения первого нажатия сервера отпечаток пальца сохраняется на клиенте. Когда сервер впоследствии проверяет, существует ли отпечаток пальца, он сначала запрашивает ресурс, который нужно вставить в отпечаток пальца, а затем отправляет его, если он не найден), но неглобальный файл cookie не Так повезло. Для этого типа ресурсов Preload — ваш друг.
Предварительная загрузка также имеет возможность, которой HTTP / 2 Push не имеет, а именно согласование содержимого, что означает, что если вы хотите передатьClient-HintsИли информация о принятии в заголовке HTTP может получить наиболее подходящий формат ресурса, HTTP / 2 Push вам не поможет.
Источник: russianblogs.com