Асинхронная загрузка JavaScript - ускоряем загрузку страниц. Скрипт небольшой и зависим? Все так просто

Вайбер на компьютер 14.05.2019
Вайбер на компьютер

Эта проблема была предварительно затронута в статье: «Как JavaScript тормозит Веб (и что с этим делать)?»

Для начала определимся с самой проблемой. Событие window.onload используется программистами для старта их веб-приложения. Это может быть что-то довольно простое, например, выпадающее меню, а может быть и совсем сложное, как пример, запуск почтового приложения. Суть проблемы заключается в том, что событие onload срабатывает только после того, как загрузится вся страница (включая все картинки и другое бинарное содержимое). Если на странице много картинок, то можно заметить некоторую задержку между загрузкой страницы и тем моментом, когда она начнет фактически работать. На самом деле, нам нужно только узнать способ определить, когда DOM полностью загрузится, а не ждать еще и загрузку картинок.

Mozilla впереди планеты всей

У Mozilla (прим.: на данный момент Firefox является более актуальным, поэтому далее упоминается именно он ) есть (недокументированное) событие специально для этих целей: DOMContentLoaded . Следующий образец кода выполняет как раз то, что нам нужно в Mozilla-подобных браузерах (а также в Opera 9):

// для Firefox if (document.addEventListener) { document.addEventListener("DOMContentLoaded", init, false); } А Internet Explorer?

IE поддерживает замечательный атрибут для тега <script> : defer . Присутствие этого атрибута указывает IE, что загрузку скрипта нужно отложить до тех пор, пока не загрузится DOM. Однако, это работает только для внешних скриптов. Следует также заметить, что этот атрибут нельзя выставлять, используя другой скрипт. Это означает, что нельзя создать с этим атрибутом, используя DOM-методы, — атрибут будет просто проигнорирован.

Используя этот удобный атрибут, можно создать мини-скрипт, который и будет вызывать наш обработчик onload:

Условные комментарии

Есть некоторая проблема с этим подходом. Другие браузеры проигнорируют атрибут defer и загрузят этот скрипт сразу же. Существует несколько способов, как можно с этим побороться. Моим любимым методом является использование условных комментариев (conditional comments ), чтобы скрыть «отложенный» скрипт:

IE также поддерживает условную компиляцию (conditional compilation ). Следующий код будет JavaScript-эквивалентом для заявленного выше HTML-кода:

// для Internet Explorer /*@cc_on @*/ /*@if (@_win32) document.write(""); /*@end @*/ Все так просто?

И конечно же, нам нужно обеспечить поддержку для остальных браузеров. У нас есть только один выход — стандартное событие window.onload:

// для остальных браузеров window.onload = init; Двойное выполнение

Остается одна маленькая неприятность (кто сказал, что будет легко?). Поскольку мы устанавливаем событие onload для всех (оставшихся) браузеров, то init сработает дважды в IE и Firefox. Чтобы это обойти, нам нужно сообщить функции, что она должна выполняться только один раз. Итак, наш метод init будет выглядеть примерно так:

function init() { // выходим, если функция уже выполнялась if (arguments.callee.done) return; // устанавливаем флаг, чтобы функция не исполнялась дважды arguments.callee.done = true; // что-нибудь делаем };

Прим.: лично мне кажется, что выставление глобальной переменной READY в данном случае более логично, ведь знать, что страница начала функционировать может потребовать не только одной функции init .

Избавляемся от внешнего файла

У описанного решения существует пара минусов:

  • Для IE нам требуется внешний JavaScript-файл
  • Не поддерживается Safari (Opera 9 поддерживает DOMContentLoaded)

Большое спасибо Matthias Miller , теперь у нас есть решение и для Internet Explorer, которое не зависит от внешних файлов:

// для Internet Explorer (используем условную компиляцию) /*@cc_on @*/ /*@if (@_win32) document.write(" "); var script = document.getElementById("__ie_onload"); script.onreadystatechange = function() { if (this.readyState == "complete") { init(); // вызываем обработчик для onload } }; /*@end @*/ И Safari тоже!

Я позже почерпнул из листа рассылки jQuery , что, благодаря создателю jQuery, John Resig , существует решение и для Safari!

if (/WebKit/i.test(navigator.userAgent)) { // условие для Safari var _timer = setInterval(function() { if (/loaded|complete/.test(document.readyState)) { clearInterval(_timer); init(); // вызываем обработчик для onload } }, 10); }

По всей видимости, jQuery — это первая библиотека, которая имеет универсальное решение для заявленной проблемы.

Полное решение // Dean Edwards/Matthias Miller/John Resig function init() { // выходим, если функция уже выполнялась if (arguments.callee.done) return; // устанавливаем флаг, чтобы функция не исполнялась дважды arguments.callee.done = true; // что-нибудь делаем }; /* для Mozilla/Firefox/Opera 9 */ if (document.addEventListener) { document.addEventListener("DOMContentLoaded", init, false); } /* для Internet Explorer */ /*@cc_on @*/ /*@if (@_win32) document.write(""); var script = document.getElementById("__ie_onload"); script.onreadystatechange = function() { if (this.readyState == "complete") { init(); // вызываем обработчик для onload } }; /*@end @*/ /* для Safari */ if (/WebKit/i.test(navigator.userAgent)) { // условие для Safari var _timer = setInterval(function() { if (/loaded|complete/.test(document.readyState)) { clearInterval(_timer); init(); // вызываем обработчик для onload } }, 10); } /* для остальных браузеров */ window.onload = init;

Сейчас я расскажу Вам об интересном способе, который поможет вам ускорить свой сайт на WordPress за счет параллельной загрузки скриптов.

Для чего это нужно?

Все очень просто. Современный сайт представляет из себя сборник самых разнообразных скриптов, тегов, сниппетов, стилей, шрифтов и всего прочего. Как вы понимаете, чем больше «плюшек», тем дольше грузится ваш сайт. Что касается JavaScript, тут отдельная песня. Замечали ли вы такой косяк, когда страница вроде бы загрузилась, но вкладка показывает, что страница все еще грузится? Так бывает, когда какой-то отдельный скрипт не прогрузился до конца. Ладно бы так, иногда страница вообще простаивает до тех пор, пока не загрузится тот самый, вроде бы и не совсем важный скрипт. А у ваших пользователей просто может не хватить терпения.

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

Асинхронный вызов скрипта выглядит так:

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

Как автоматизировать процесс?

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

Находим уже знакомый нам файл functions.php вашей темы и вставляем туда (например в конец) следующий код:

// асинхронный javascript function wcs_defer_javascripts ($url) { if (FALSE === strpos($url, ".js")) return $url; if (strpos($url, "jquery.js")) return $url; return "$url" async="async"; } add_filter("clean_url", "wcs_defer_javascripts", 11, 1);

Заключение

Что можно добавить в заключение. Данный скрипт, возможно, подойдет не всем, так-как, кто его знает, какие скрипты подключены именно у вас, поэтому, ставьте и экспериментируйте. Минуса у такого скрипта быть не может, разве что несовместимость с конкретным сайтом ввиду его специфики. Это был еще один маленький шаг по большой оптимизации вашего сайта.

/ 26.01.2018

С ростом скорости интернет соединения и увеличении мощности не только десктопных, но и мобильных устройств веб страницы стают более «тяжелыми». Количество и размер подключаемых файлов растет: JavaScript файлы, css файлы, изображения, виджеты сторонних сайтов, iframe. На данный момент специфика работы браузеров такая, что при загрузке js файла блокируется отривсовка до того момента, пока скрипт не выполниться. Современные браузеры в фоновом режиме будут парсить документ и скачивать скрипты и стили, но отрисовка будет заблокирована. Сравнение сетевых параметров для различных браузеров можно посмотреть на browserscope.org. Мы не можем устранить блокировку полностью, но можем оптимизировать серверную и клиентскую часть приложения, что бы блокировка отрисовки занимала наименьший промежуток времени.

Решения для серверной части:
— Уменьшить размер передаваемых файлов
— Использовать CDN
— Вынести статические файлы на отдельный домен или под домен, таким образом увеличить количество одновременных соединений браузера.
— Включить сжатие передаваемых файлов(gzip)

Решения для клиентской части:
— Уменьшить количество запросов.
— Кэшировать файлы на стороне клиента с помощью заголовков Expires и Etags.
— Использовать общедоступные CDN(Google CDN, Yandex CDN). Таким образом, существует вероятность, что файл с общедоступного CDN уже будет храниться в кеше браузера.

Одним из способов оптимизации скорости загрузки сайта является асинхронная загрузка файлов, которая не блокирует отрисовку.

Скрипт асинхронной загрузки JavaScript:

(function() { var s = document.createElement(‘script’); s.type = ‘text/javascript’; s.async = true; s.src = ‘URL файла’; document.getElementsByTagName(‘head’).appendChild(script); })();

Если JavaScript нужно выполнить после загрузки всей страницы, включая содержание, изображения, стилевые файлы и внешние скрипты, то к загрузчику нужно добавить отслеживания события onload.

if (window.addEventListener) { window.addEventListener(‘load’, async_load, false); } else if (window.attachEvent) { window.attachEvent(‘onload’, async_load); }

Скрипт асинхронной загрузки JavaScript с учетом события onload

(function() { function async_load(){ var s = document.createElement(‘script’); s.type = ‘text/javascript’; s.async = true; s.src = ‘URL файла’; document.getElementsByTagName(‘head’).appendChild(script); } if (window.addEventListener) { window.addEventListener(‘load’, async_load, false); } else if (window.attachEvent) { window.attachEvent(‘onload’, async_load); } })();

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

Скрипт асинхронной загрузки множества подключаемых JavaScript файлов

(function() { function async_load(){ [ ‘URL_файла_1.js’, ‘URL_файла_2.js’, ‘URL_файла_3.js’ ].forEach(function(src) { var s = document.createElement(‘script’); s.type = ‘text/javascript’; s.async = true; s.src = src; document.getElementsByTagName(‘head’).appendChild(script); }); } if (window.addEventListener) { window.addEventListener(‘load’, async_load, false); } else if (window.attachEvent) { window.attachEvent(‘onload’, async_load); } })();

Но в такой реализации есть минус — скрипты будут загружаться в произвольном порядке и соответсвенно выполнятся они будут произвольно во времени. Данный скрипт асинхронной загрузки идеально подходит, если выполнение JavaScript файлов не зависят один от другого и не зависит от DOM. В обратном случае его использование может привести к ошибкам на странице или непредвиденному результату выполнения. Для последовательного выполнения, но асинхронной загрузки, нужно указать async=false, тогда файлы будут скачиваться в произвольном порядке, но выполняться по очереди.

Стандарт HTML 5 поддерживает асинхронную загрузку JavaScript. Это можно сделать путем добавления ключевого слова async или defer. Например:

.jpg» type=»text/javascript» defer>

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

Скрипт, который подключен с атрибутом async выполнится при первой возможности после полной загрузки, но при этом не ожидает окончания парсинга документа и до загрузки объекта window. Браузеры не гарантируют выполнение скриптов в том же порядке в котором они подключены.

Библиотеки для асинхронной загрузки JavaScript

RequireJS — модуль загрузки JavaScript. Оптимизирован под браузеры, но он может использоваться в других средах, таких как Node, Rhino.

require([«script»], function(script) { console.log(«start after load script.js»); });

extsrc.js - библиотека, которая запускает скрипты на выполнение после того, как страница загрузится и отобразится пользователю. Работает корректно с document.write.

.jpg»>.jpg»>

yepnope.js — позволяет совершать асинхронную загрузку JavaScript и CSS файлов.

yepnope([ ‘script.js’, ‘style.css’ ]);

Простой способ загрузки JavaScript скриптов

Оказывается, что на практике добиться оптимальной кросс браузерной загрузки JavaScript скриптов, которые не блокируют отображение сложно, а порой невозможно..jpg»> в конец документа перед закрывающимся тегом body. Из за ограничения разных браузеров и самого HTML такой вариант загрузки, который не блокирует отображение, можно считать наиболее простой.

Google PageSpeed: CSS стили и JavaScript скрипты, блокирующие загрузку страницы на WP

В этом посту будет подразумеваться, что вы знакомы с инструментом Google по оптимизации скорости загрузки страниц сайта — PageSpeed Insights. Слушайте, да прямо сейчас вбейте туда свой сайт нажмите кнопку «Analize».

Окей, а теперь — о чём этот пост?

Вполне возможно, что в результатах проверки вашего сайта есть пункт «Eliminate render-blocking JavaScript and CSS in above-the-fold content».

Я заметил, что этот пункт один из самых трудноразрешимых (трудоёмких) и практически на всех сайтах, даже на очень быстрых, он присутствует.

Как его исправить в теории:

  • Объединяем все JavaScript файлы и размещаем то, что получилось перед закрывающим тегом сайта.
  • Объединяем все CSS, суём прямо перед JavaScript, которые мы уже переместили, затем выбираем из них те стили, которые необходимы для корректного отображения страницы, а в особенности её верхней части (первого экрана) и помещаем их в тег в сайта.
  • Как же обстоит дело на практике, и в данном конкретном случае — для сайтов на WordPress?

    1. Воспользуемся зависимостью других скриптов от jQuery

    В корректно состряпанной теме WordPress все CSS и JS файлы подключаются через wp_head() и wp_footer() — то есть в и в конце соответственно.

    Также у файлов есть зависимости, то есть например плагин должен подключаться после, а это значит, что если библиотека jQuery находится в wp_footer(), то FancyBox ну никак не может попасть в wp_head().

    Перемещаем jQuery в футер сайта

    Делается это очень просто — при помощи функций wp_deregister_script(), wp_register_script(), wp_enqueue_script() и хука (иногда используют хук в связке с is_admin()). Всё, что требуется от вас, это вставить код следующего содержания в файл вашего сайта.

    Хочу обратить ваше внимание на то, что это автоматизированное решение, и хотя оно работает практически в 100% случаев, бывает такое, что некоторые скрипты не хотят переноситься в футер сайта. Тогда уже потребуется более внимательный к каждому вашему файлу JavaScript.

    На этом наша работа с JS заканчивается, конечно прирост в скорости даст ещё и объединение скриптов (то есть снимаете их все с регистрации и потом просто подключаете свою объединенную версию) — но Google сейчас это уже не требует.

    2. Объединение CSS в WordPress

    Если объединение всех JavaScript в один файл — не всегда хорошая идея, то CSS-ки я бы рекомендовал объединять по возможности всегда.

    Помните скриншот в самом начале статьи (10 blocking CSS resources )? Откуда берется такое количество файлов стилей, ведь разработчик темы наверное понимал, что делает?

    Ответ — из плагинов.

    Например плагин «Contact Form 7» подключает свою собственную таблицу стилей, и хотя сама по себе она невелика, то лучше всё же избежать лишних HTTP-запросов.

    Давайте пошагово разберем как.

  • Копируете содержимое таблицы стилей плагина и вставляете его в конец основного файла стилей — .
  • Проверяете, проставлены ли в данных стилях относительные ссылки на изображения, например. Если да, то либо заменяете их на абсолютные, либо переносите изображения из плагина в папку с темой.
  • Заходите в настройки плагина и смотрите, есть ли возможность где-нибудь снять галочку и не подключать CSS плагина. В «Contact Form 7» такой возможности нет, а значит мы переходим к следующему пункту.
  • Отрубаем файлы через. Для стилей «Contact Form 7» код будет следующий:
  • Также иногда при помощи условных тегов файлы плагинов (как CSS, так и JS) отключают только с тех страниц, на которых они не используется.

    Ок, с «Contact Form 7» разобрались, а как узнать ID файлов CSS других плагинов?

    Да легко, открываем исходный код страницы и видим там подобную картину:

    Также есть плагин, который позволит выполнить объединение CSS и JavaScript автоматически — JS & CSS Script Optimizer.

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

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

    Браузер загружает страницу последовательно. Особенно это актуально для внешних ссылках на файлы — css и javascript. Возьмем для примера блок для сайта lesnoy.name.

    Блог Лесного Владислава

    На данном сайте подгружается всего три внешних файла.

    2 из них — css стили, и один — js-файл. Но это пример простого сайта, зачастую подгружаются десятки внешних файлов и это существенно влияет на скорость загрузки страницы.

    Ускорение отображения страницы в браузере

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

    Т.е., из примера выше видно, что браузер загрузит заголовок сайта (title), затем встретит ссылку на внешний css файл main.css и пойдет загружать его. После загрузки он его обрабатывает и идет дальше — встречает второй css-файл, опять откладывает обработку страницы на потом и работает с prettify.css. Так же и с prettify.js. И лишь потом он принимается за отображения остальной страницы, уже применяя все обработанные ранее css-правила из css файлов и js-кол из javascript файлов.

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

    Можно, конечно. Самый банальный, но от этого не менее действенный метод — перенос всех не приоритетных внешних файлов с хедера сайта в футер. Т.е. с head-блока как можно ближе к тегу.

    Под не приоритетными файлами я подразумеваю те, которые не критичны для функциональности или внешнего вида сайта. Хороший способ разделить большой css или js файл на два — первый маленький хранит в себе то, что должно загрузиться как можно быстрее и размещается в head-секции, а второй и объемный содержит все остальное и располагается как можно ниже в html-коде страницы, не влияя на скорость отображения контента страницы.

    Но с приходом html5 можно сделать это проще и красивее. У тега script добавлен параметр async и defer .

    Атрибут async

    Атрибут тега script async делает загрузку js-файлов асинхронным. Те, кто умеют программировать на JS точно знают, как это — асинхронно. Тем же, кто не умеет — расскажу: браузер встречает ссылку на внешний javascript файл (тег script с параметром src), начинает выполнять его загрузку и обработку, но не останавливает при этом загрузку и обработку основной страницы.

    Т.е. делает это параллельно. Как раз то, что нам и нужно! И при этом не требуется переносить этот тег в футер (тем более не во всех CMS-системах это просто сделать).

    Недостаток атрибута async

    У асинхронной загрузки js-файла асинхронность является как плюсом так и минусом. Ведь размеры файлов скорее всего разные, скорость загрузки и обработки файлов так же не является детерминированной. А значит при асинхронной загрузки нескольких файлов нет никакой гарантии, что файл, который стал загружаться позже не загрузиться в итоге раньше (из-за размера в основном).

    В данном примере я не могу точно сказать, какая последовательность выполнения этих js-файлов будет. Я могу точно сказать лишь то, что script4 загрузиться после script3 из-за отсутствия у них атрибута async. Но какой файл из script1.js, script2.js и script5.js загрузиться раньше я не знаю, т.к. они загружаются асинхронно.

    Вставить/изменить ссылку

    «Да и какая нам разница?» — спросите вы. Но она появляется в том случае, если выполнения одного js-скрипта зависит от другого. Такое сейчас сплошь и рядом и самый простой пример такой зависимости — jQuery.

    В данном случае очень велика вероятность получения ошибки JavaScript из-за того, что какой-либо из jQuery плагинов начнет выполнятся раньше, чем загрузиться сам jQuery.

    Что же делать?

    Атрибут defer

    Тут нас и выручает другой атрибут script-тега — defer.

    Deferred переводиться с английского языка как «отложенный».

    Соответственно deferred javascript load — отложенная загрузка javascript. Если у ссылки на внешний js-файл браузер встречает атрибут defer, то он откладывает загрузку и выполнения этих файлов до тех пор, когда вся страница не будет загружена и отображена. При этом он гарантирует такой же порядок выполнения скриптов, который изначально и был установлен в html-коде.

    Соответственно, в нашем примере с jQuery и его плагинами defer нас выручает, выполняя две задачи: время отображения страницы существенно уменьшается (браузер не блокирует отрисовку страницы для загрузки js-файлов, он откладывает загрузку на потом) и при этом мы избавляется от возможных ошибках, связанных с асинхронной загрузкой зависимых друг от друга js файлов.

    В примере выше скрипт other_script.js загрузиться асинхронно, т.к. он не зависит от какого-либо другого файла, а jQuery и его плагины загрузятся сразу после отображения страницы в следующем порядке: сначала jquery.min.js, затем по порядку plugin1.jquery.js, plugin2.jquery.js, plugin3.jquery.js.

    В итоге с приходом html5 и атрибутов defer и async мы можем намного гибче управлять порядком загрузки внешних js-файлов, тем самым повышая скорость отрисовки веб-страницы . А, главное, для пользователя будет создаваться впечатления значительного повышения скорости загрузки всего веб-сайта в целом , ведь уже через несколько секунд он увидит то, зачем пришел на сайт — информацию.

    ) я писала о том, какой эффект оказывают JavaScript-файлы на Критический Путь Рендеринга(CRP).


    JavaScript является блокирующим ресурсом для парсера. Это означает, что JavaScript блокирует разбор самого HTML-документа. Когда парсер доходит до тега <script> (не важно внутренний он или внешний), он останавливается, забирает файл (если он внешний) и запускает его.

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


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

    Нормальное выполнение

    Прежде чем понять разницу между этими двумя атрибутами, давайте посмотрим что происходит в их отсутствие. Как было сказано ранее, по умолчанию файлы JavaScript прерывают парсинг HTML-документа до тех пор, пока не будут получены и выполнены.
    Возьмём пример, в котором элемент расположен где-то в середине страницы:


    ... ... ....

    Вот что произойдёт, когда парсер будет обрабатывать документ:

    Парсинг HTML приостанавливается, пока скрипт не будет загружен и выполнен, тем самым увеличивая количество времени до первой отрисовки.

    Атрибут async

    Async используется для того, чтобы указать браузеру, что скрипт может быть выполнен асинхронно.
    Парсеру HTML нет необходимости останавливаться, когда он достигает тега для загрузки и выполнении. Выполнение может произойти после того, как скрипт будет получен параллельно с разбором документа.



    Атрибут доступен только для файлов, подключающихся внешне. Если внешний файл имеет этот атрибут, то он может быть загружен в то время как HTML-документ ещё парсится. Парсер будет приостановлен для выполнения скрипта, как только файл скрипта будет загружен.



    Атрибут defer

    Атрибут defer указывает браузеру, что скрипт должен быть выполнен после того, как HTML-документ будет полностью разобран.



    Как и при асинхронной загрузке скриптов - файл может быть загружен, в то время как HTML-документ парсится. Однако, даже если файл скрипта будет полностью загружен ещё до того, как парсер закончит работу, он не будет выполнен до тех пор, пока парсер не отработает до конца.



    Асинхронное, отложенное или нормальное выполнение?

    Итак, когда же следует использовать асинхронное, отложенное или нормальное выполнение JavaScript? Как всегда, это зависит от ситуации и существуют несколько вопросов, которые помогут принять вам правильное решение.

    Где расположен элемент ?

    Асинхронное и отложенное выполнения наиболее важны, когда элемент не находится в самом конце документа. HTML-документы парсятся по порядку, с открытия до его закрытия. Если внешний JavaScript-файл размещается непосредственно перед закрывающим тегом , то использование async и defer становится менее уместным, так как парсер к тому времени уже разберёт большую часть документа, и JavaScript-файлы уже не будут оказывать воздействие на него.

    Скрипт самодостаточен?

    Для файлов, которые не зависят от других файлов и/или не имеют никаких зависимостей, атрибут async будет наиболее полезен. Поскольку нам не важно, когда файл будет исполнен, асинхронная загрузка - наиболее подходящий вариант.

    Полагается ли скрипт на полностью разобранный DOM?

    Во многих случаях файл скрипта содержит функции, взаимодействующие с DOM. Или, возможно, существует зависимость от другого файла на странице. В таких случаях DOM должен быть полностью разобран, прежде чем скрипт будет выполнен. Как правило, такой файл помещается в низ страницы, чтобы убедиться, что для его работы всё было разобрано. Однако, в ситуации, когда по каким-либо причинам файл должен быть размещён в другом месте - атрибут defer может быть полезен.

    Скрипт небольшой и зависим?

    Наконец, если скрипт является относительно небольшим и/или зависит от других файлов, то, возможно, стоит определить его инлайново. Несмотря на то, что встроенный код блокирует разбор HTML-документа, он не должен сильно помешать, если его размер небольшой. Кроме того, если он зависит от других файлов, может понадобиться незначительная блокировка.

    Поддержка и современные браузерные движки

    Поддержка атрибутов async и defer очень распространена:




    Стоит отметить, что поведение этих атрибутов может немного отличаться в разных движках JavaScript. Например, в V8 (используется в Chromium), сделана попытка разобрать все скрипты, независимо от их атрибутов, на отдельном выделенном потоке для выполнения скрипта. Таким образом, «блокирующая парсер» природа JavaScript-файлов должна быть минимизирована по умолчанию.

    Я пытаюсь исключить 2 файла CSS, которые блокируют рендеринг на моем сайте, - они появляются в Google Page Speed ​​Insights. Я придерживался разных методов, ни один из которых не был успешным. Но недавно я нашел сообщение о Thinking Async и когда я применил этот код: он устранил проблему.

    Однако после публикации страница потеряла стиль. Я не слишком уверен в том, что происходит, потому что код работает, но это стиль после загрузки, который не работает. Поблагодарите вашу помощь в этом. Благодаря

    4 ответов

    Уловкой запуска асинхронной загрузки стилей является использование элемента и установка недопустимого значения для атрибута media (я использую media = "none", но любое значение будет делать). Когда медиа-запрос оценивается как false, браузер все равно будет загружать таблицу стилей, но он не будет ждать, пока контент будет доступен до отображения страницы.

    После того, как таблица стилей закончила загрузку, атрибут media должен быть установлен на допустимое значение, поэтому правила стиля будут применены к документу. Событие onload используется для переключения свойства media на все:

    Этот метод загрузки CSS будет доставлять полезный контент посетителям намного быстрее, чем стандартный подход. Критический CSS все еще может быть использован с обычным блокирующим подходом (или вы можете встроить его для максимальной производительности), а некритические стили могут быть постепенно загружены и применены позже в процессе синтаксического анализа/рендеринга.

    Этот метод использует JavaScript, но вы можете обслуживать не-JavaScript-браузеры, обертывая эквивалентные блокирующие элементы в элементе :

    Вы можете увидеть операцию в www.itcha.edu.sv

    вы можете попробовать получить его несколькими способами:

    1. Использование media="bogus" и a на ноге

    2. Включение DOM по-старому

    (function(){ var bsa = document.createElement("script"); bsa.type = "text/javascript"; bsa.async = true; bsa.src = "https://s3.buysellads.com/ac/bsa.js"; (document.getElementsByTagName("head")||document.getElementsByTagName("body")).appendChild(bsa); })();

    3.если вы можете попробовать плагины, которые вы могли бы попробовать loadCSS

    // include loadCSS here... function loadCSS(href, before, media){ ... } // load a file loadCSS("path/to/mystylesheet.css");

    Будущее представляется preload keyword для link элементов.

    Версия синхронизации

    Версия Async

    К сожалению...

    Известные браузеры, которые еще не поддерживают эту функцию включают Edge и iOS Safari.

    Однако...

    loadCSS представляется потенциальным решением, которое позволяет вам использовать preload сегодня (с резервными копиями).



    Рекомендуем почитать

    Наверх