предисловие
Недавно я изучал проект, сгенерированный vue-cli 3.0, и нашел следующее использование в index.html, сгенерированном после построения:
<link as=style href=/css/app.f60416c7.css rel=preload>
<link as=script href=/js/app.69189fdd.js rel=preload>
Это коснулось моего слепого пятна в знаниях.В целях грамотности я изучил тег ссылки и обнаружил, что эта мелочь довольно мощная.Вышеизложенное для реализации функции предварительной загрузки.Если вы немного знаете английский язык, когда вы видите предварительную загрузку я примерно знаю.
До этого тоже были технологии предзагрузки, такие как prefetch, subresource и т.д.Разница между ними и preload - это отдельная тема.Если интересно,можете поискать сами.Если не хотите искать,то нужно только знаю, что эти два сравниваются с preload.Слабый достаточно, то есть браузерная совместимость prefetch немного лучше.Эти три также имеют свои акценты и сценарии применения.
Функции:
preload — это новый веб-стандарт, предназначенный для повышения производительности и предоставления FE более детального контроля над загрузкой. Это дает разработчикам возможность настраивать логику загрузки без снижения производительности загрузчиков на основе скриптов.
Основное использование предварительной загрузки — загрузка ресурсов заранее.Хотя большинство ресурсов, основанных на языке разметки, можно найти заранее с помощью предварительного загрузчика браузера (preloader), не все ресурсы основаны на языке разметки, например, некоторые скрытые ресурсы css и js ( шрифты, изображения и т. д.), когда браузер обнаружит, что странице нужны эти ресурсы, он снова пройдет процесс загрузки и рендеринга, что снизит удобство работы пользователя и задержит рендеринг страницы;
Введение в предварительный загрузчик
Если синтаксический анализатор HTML обнаружит синхронный сценарий при создании DOM, синтаксический анализатор прекратит создание DOM и вместо этого выполнит сценарий. Таким образом, если выборка ресурса происходит только тогда, когда синтаксический анализатор создает DOM, использование синхронных сценариев оставит сеть пустой, особенно для внешних ресурсов со сценариями, и, конечно же, внутренние сценарии также могут иногда вызывать задержки.
Появление прелоадера (Preloader) призвано оптимизировать этот процесс.Прелоадер анализирует ранние результаты парсинга HTML-документа браузером (этот этап называется «токенизация (tokenization)»), чтобы найти теги, которые могут содержать ресурсы (тег) и собрать URL-адреса этих ресурсов. Результат этапа токенизации будет отправлен парсеру реального HTML, а собранные URL-адреса ресурсов будут отправлены сборщику вместе с типом ресурса, и сборщик оценит загрузку страницы на основе этих ресурсов.Эффекты загружаются последовательно. .
Преимущества предварительной загрузки:
- Пусть браузер загружает указанный ресурс заранее (здесь он не будет выполняться после завершения предварительной загрузки), и выполняет его, когда он должен быть выполнен, чтобы загрузка и выполнение были разделены, а рендеринг и window.onload события не могут быть заблокированы.
- Предварительно загрузите указанные ресурсы, особенно файл шрифта, и шрифт больше не появится.После рендеринга страницы загрузка завершается, а затем шрифт страницы мигает и становится ожидаемым шрифтом.
- С помощью события onload вы можете настроить функцию обратного вызова после предварительной загрузки ресурса.
Введение задействованного атрибута:
Сценарии применения:
- Включить медиа
Хорошая особенность элементов заключается в том, что они принимаютmediaАтрибуты. они приемлемытип носителяили действительныйзапросы средств массовой информацииВ качестве значения свойства это позволит вам использовать реактивную предварительную загрузку!
Рассмотрим простой пример (см.Исходный код на GithubилиОнлайн-пример):
<head>
<meta charset="utf-8">
<title>Responsive preload example</title>
<link rel="preload" href="bg-image-narrow.png" as="image" media="(max-width: 600px)">
<link rel="preload" href="bg-image-wide.png" as="image" media="(min-width: 601px)">
<link rel="stylesheet" href="main.css">
</head>
<body>
<header>
<h1>My site</h1>
</header>
<script>
var mediaQueryList = window.matchMedia("(max-width: 600px)");
var header = document.querySelector('header');
if(mediaQueryList.matches) {
header.style.backgroundImage = 'url(bg-image-narrow.png)';
} else {
header.style.backgroundImage = 'url(bg-image-wide.png)';
}
</script>
</body>
Вы можете видеть, что мы включили атрибут media в элемент , поэтому, когда пользователь использует устройство с более узким экраном, будет предварительно загружено более узкое изображение, а на более широком устройстве будут предварительно загружены более широкие изображения. Затем нам еще нужно прикрепить соответствующее изображение к элементу шапки — черезWindow.matchMedia / MediaQueryListреализовать (см.Testing media queriesстатью для получения дополнительной информации).
- Шрифты загружаются раньше
Веб-шрифты являются распространенным типом критически важных ресурсов позднего обнаружения. Но на текущем этапе разработки внешнего интерфейса, когда взаимодействие с пользователем имеет решающее значение для внешнего интерфейса, веб-шрифты также имеют решающее значение для рендеринга страницы. Ссылка на шрифт скрыта глубоко в css, и даже если предварительный загрузчик заранее анализирует css, нет возможности определить, действительно ли селектор, содержащий информацию о шрифте, будет действовать на узле dom. Таким образом, чтобы уменьшить FOUT (вспышку нестилизованного текста), необходимо предварительно загрузить файлы шрифтов.При предварительной загрузке выполняется одна строка кода:
<link rel=preload href='font.woff2' as=font type='font/woff2' crossorigin />
NOTE :
Атрибут crossorigin требуется при загрузке шрифтов, даже если шрифты не являются междоменными на сервере их собственной компании, потому что пользовательские агенты должны использовать анонимный режим для получения ресурсов шрифта (Почему это так?).
Атрибут type гарантирует, что браузер извлекает только те ресурсы, которые он поддерживает.
- Динамически загружается, но не выполняется
С предварительной загрузкой возможен и другой интересный сценарий — когда вы хотите загрузить ассет, но не хотите его выполнять. Скажем, например, вы хотите выполнить скрипт в определенный момент жизненного цикла страницы, и вы не можете внести какие-либо изменения в этот скрипт, невозможно создать для него так называемую функцию runNow().
До того, как появилась предварительная загрузка, существовал предел тому, что вы могли сделать. Если ваш метод состоит в том, чтобы вставить скрипт туда, где вы хотите, чтобы скрипт выполнялся, поскольку скрипт может быть выполнен браузером только после его загрузки, вам придется подождать некоторое время. Если предварительно загрузить скрипт с помощью XHR, браузер откажется от повторного использования скрипта.В некоторых случаях для выполнения скрипта можно использовать функцию eval, но этот метод не всегда работает и не полностью свободен от побочных эффектов.
Теперь с предзагрузкой все возможно
var link = 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);
- На основе языка разметки асинхронной загрузки
Сначала посмотрите код
<link rel="preload" as="style" href="asyncstyle.css" onload="this.rel='stylesheet'">
Событие предварительной загрузки onload может изменить атрибут rel после загрузки ресурса, что обеспечивает очень крутую асинхронную загрузку ресурсов.
Скрипты также могут использовать этот метод для достижения асинхронной загрузки.
Разве у нас уже нет
Например, вы хотите загрузить фрагмент кода, который подсчитывает посещения страниц, как можно быстрее, но вы не хотите, чтобы загрузка этого кода задержала отображение страницы и повлияла на взаимодействие с пользователем. хотите отложить событие загрузки окна.
С предварительной загрузкой это можно сделать за считанные минуты.
<link rel="preload" as="script" href="async_script.js"
onload="var script = document.createElement('script'); script.src = this.href; document.body.appendChild(script);">
- Адаптивная загрузка
preload — это ссылка, которая согласно спецификации имеет медиа-атрибут (пока не поддерживается Chrome, но скоро), который разрешает выборочную загрузку.
Какая польза? Предполагая, что ваш сайт поддерживает как настольный, так и мобильный доступ, при использовании настольного браузера вы хотите представить большую интерактивную карту, а на мобильной стороне достаточно статической карты меньшего размера.
Вы определенно не хотите загружать два ресурса одновременно, сейчас распространена практика динамической загрузки ресурсов, оценивая текущий тип браузера через JS, но таким образом предварительный загрузчик браузера не может обнаружить их вовремя, что может привести к задержке. время загрузки и влияют на пользователей.Опыт и рейтинги SpeedIndex.
Как мы можем позволить браузеру обнаружить эти ресурсы как можно раньше? Еще предзагрузить!
С Preload мы можем загружать ресурсы заранее, а с атрибутом 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 для предварительной загрузки
Еще одна особенность Preload заключается в том, что ее можно отображать с помощью заголовков HTTP. Другими словами, большинство описанных выше объявлений на основе языка разметки могут быть реализованы через заголовки ответа HTTP. (Единственным исключением является случай с событием onload, когда невозможно определить обработчики событий в заголовках HTTP.)
Link: <thing_to_load.js>;rel="preload";as="script"
Link: <thing_to_load.woff2>;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.
}
Совместимость с браузером:
Статус поддержки версии браузера, отображаемый на веб-сайте caniuse.com, выглядит следующим образом: в настоящее время браузеры с относительно высокими версиями будут поддерживать эту функцию, но не беспокойтесь, в среде браузера, которая не игнорировать, вы можете сделать плавный даунгрейд.