HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p><strong>JS-скрипты, неудачно расположенные в HTML-коде, могут значительно снизить скорость загрузки страницы. Разберемся, как повысить скорость загрузки в старых версиях браузеров и как правильно использовать async и defer, которые поддерживаются в новых версиях.</strong></p>
1 <p><strong>JS-скрипты, неудачно расположенные в HTML-коде, могут значительно снизить скорость загрузки страницы. Разберемся, как повысить скорость загрузки в старых версиях браузеров и как правильно использовать async и defer, которые поддерживаются в новых версиях.</strong></p>
2 <p><em>Это адаптированный перевод статьи<a>Efficiently load JavaScript with defer and async</a>из блога проекта flaviocopes. Повествование ведется от лица автора оригинала.</em></p>
2 <p><em>Это адаптированный перевод статьи<a>Efficiently load JavaScript with defer and async</a>из блога проекта flaviocopes. Повествование ведется от лица автора оригинала.</em></p>
3 <h2>Содержание</h2>
3 <h2>Содержание</h2>
4 <ul><li><a>Расположение имеет значение</a></li>
4 <ul><li><a>Расположение имеет значение</a></li>
5 <li><a>async и defer</a></li>
5 <li><a>async и defer</a></li>
6 <li><a>Производительность</a></li>
6 <li><a>Производительность</a></li>
7 <li><a>Как ускорить загрузку страницы</a></li>
7 <li><a>Как ускорить загрузку страницы</a></li>
8 </ul><h2>Расположение имеет значение</h2>
8 </ul><h2>Расположение имеет значение</h2>
9 <p>Стандартный способ встраивания скрипта в HTML-код страницы выглядит так:</p>
9 <p>Стандартный способ встраивания скрипта в HTML-код страницы выглядит так:</p>
10 <p>Каждый раз, когда встретится такая или похожая строка, будет выполнен запрос на получение данных файла, а парсер продолжит свою работу после выполнения скрипта.</p>
10 <p>Каждый раз, когда встретится такая или похожая строка, будет выполнен запрос на получение данных файла, а парсер продолжит свою работу после выполнения скрипта.</p>
11 <p>Классический подход к обучению HTML предполагает, что теги скрипта должны находиться в &lt;head&gt;:</p>
11 <p>Классический подход к обучению HTML предполагает, что теги скрипта должны находиться в &lt;head&gt;:</p>
12 <p>Однако такой подход приводит к задержкам при загрузке страницы. Когда анализатор доходит до строки со скриптом, он на время останавливается для его извлечения и выполнения, и только после этого переходит к разбору&lt;body&gt;.</p>
12 <p>Однако такой подход приводит к задержкам при загрузке страницы. Когда анализатор доходит до строки со скриптом, он на время останавливается для его извлечения и выполнения, и только после этого переходит к разбору&lt;body&gt;.</p>
13 <p>Распространенное решение проблемы - перенос скрипта в нижнюю часть страницы, перед закрывающим тегом &lt;/body&gt;. В этом случае скрипт выполняется после того, как вся страница уже проанализирована до тега.</p>
13 <p>Распространенное решение проблемы - перенос скрипта в нижнюю часть страницы, перед закрывающим тегом &lt;/body&gt;. В этом случае скрипт выполняется после того, как вся страница уже проанализирована до тега.</p>
14 <p>Это лучшее решение по ускорению загрузки страницы для старых браузеров, которые не поддерживают атрибуты async и defer. О последних поговорим отдельно.</p>
14 <p>Это лучшее решение по ускорению загрузки страницы для старых браузеров, которые не поддерживают атрибуты async и defer. О последних поговорим отдельно.</p>
15 <h2>async и defer</h2>
15 <h2>async и defer</h2>
16 <p>Прежде чем начать, стоит уточнить, что использование обоих атрибутов накладывает некоторые ограничения, а приведенное ниже руководство по времени загрузки - не исчерпывающее.</p>
16 <p>Прежде чем начать, стоит уточнить, что использование обоих атрибутов накладывает некоторые ограничения, а приведенное ниже руководство по времени загрузки - не исчерпывающее.</p>
17 <p>Синтаксически и async и defer - булевые атрибуты, которые используются следующим образом:</p>
17 <p>Синтаксически и async и defer - булевые атрибуты, которые используются следующим образом:</p>
18 <p>Если в коде есть оба атрибута, async имеет приоритет и выполняется в первую очередь в современных версиях браузеров. В старых версиях, напротив, приоритет будет отдан defer.</p>
18 <p>Если в коде есть оба атрибута, async имеет приоритет и выполняется в первую очередь в современных версиях браузеров. В старых версиях, напротив, приоритет будет отдан defer.</p>
19 <blockquote><p>Проверить совместимость атрибутов с разными версиями браузеров можно по этим таблицам:<a>раз</a>и<a>два</a></p>
19 <blockquote><p>Проверить совместимость атрибутов с разными версиями браузеров можно по этим таблицам:<a>раз</a>и<a>два</a></p>
20 </blockquote><p>Важно отметить, что оба атрибута стоит использовать только в верхней части страницы (в &lt;head&gt;): перенос в &lt;body&gt; делает их совершенно бесполезными.</p>
20 </blockquote><p>Важно отметить, что оба атрибута стоит использовать только в верхней части страницы (в &lt;head&gt;): перенос в &lt;body&gt; делает их совершенно бесполезными.</p>
21 <h2>Производительность</h2>
21 <h2>Производительность</h2>
22 <h3>Если async и defer отсутствуют в &lt;head&gt;</h3>
22 <h3>Если async и defer отсутствуют в &lt;head&gt;</h3>
23 <p>Синтаксический анализатор прекращает работу до тех пор, пока скрипт не будет выполнен. Как только этот процесс завершится, анализ продолжится.</p>
23 <p>Синтаксический анализатор прекращает работу до тех пор, пока скрипт не будет выполнен. Как только этот процесс завершится, анализ продолжится.</p>
24 <h3>Если async и defer отсутствуют в &lt;body&gt;</h3>
24 <h3>Если async и defer отсутствуют в &lt;body&gt;</h3>
25 <p>Парсинг выполняется без пауз: сразу по его завершению загружается и выполняется скрипт. Синтаксический анализ выполняется еще до загрузки скрипта, поэтому страница загружается быстрее, чем в предыдущем случае.</p>
25 <p>Парсинг выполняется без пауз: сразу по его завершению загружается и выполняется скрипт. Синтаксический анализ выполняется еще до загрузки скрипта, поэтому страница загружается быстрее, чем в предыдущем случае.</p>
26 <h3>Если async находится в &lt;head&gt;</h3>
26 <h3>Если async находится в &lt;head&gt;</h3>
27 <p>Сценарий загружается асинхронно, а синтаксический анализатор приостанавливает работу на время его выполнения.</p>
27 <p>Сценарий загружается асинхронно, а синтаксический анализатор приостанавливает работу на время его выполнения.</p>
28 <h3>Если defer находится в &lt;head&gt;</h3>
28 <h3>Если defer находится в &lt;head&gt;</h3>
29 <p>Скрипт извлекается асинхронно и выполняется только после завершения анализа HTML.</p>
29 <p>Скрипт извлекается асинхронно и выполняется только после завершения анализа HTML.</p>
30 <p>Парсинг проходит с той же скоростью, как если бы скрипт находился в конце тега body, но в целом выполнение скрипта завершается намного раньше, поскольку он загружается параллельно с парсингом HTML. Таким образом этот вариант - наиболее выигрышный с точки зрения скорости загрузки страницы.</p>
30 <p>Парсинг проходит с той же скоростью, как если бы скрипт находился в конце тега body, но в целом выполнение скрипта завершается намного раньше, поскольку он загружается параллельно с парсингом HTML. Таким образом этот вариант - наиболее выигрышный с точки зрения скорости загрузки страницы.</p>
31 <h3>Блокировка синтаксического анализа</h3>
31 <h3>Блокировка синтаксического анализа</h3>
32 <p>async приостанавливает синтаксический анализ страницы, а defer - нет.</p>
32 <p>async приостанавливает синтаксический анализ страницы, а defer - нет.</p>
33 <h3>Блокировка рендеринга</h3>
33 <h3>Блокировка рендеринга</h3>
34 <p>Ни async, ни defer не блокируют рендеринг - этот процесс полностью зависит от кода на странице. Поэтому важно убедиться, что сценарии запускаются после события onLoad.</p>
34 <p>Ни async, ни defer не блокируют рендеринг - этот процесс полностью зависит от кода на странице. Поэтому важно убедиться, что сценарии запускаются после события onLoad.</p>
35 <h3>domInteractive</h3>
35 <h3>domInteractive</h3>
36 <p>Скрипты defer выполняются сразу после события domInteractive. Последнее, в свою очередь, происходит после загрузки, анализа и построения DOM HTML.</p>
36 <p>Скрипты defer выполняются сразу после события domInteractive. Последнее, в свою очередь, происходит после загрузки, анализа и построения DOM HTML.</p>
37 <p>СSS и изображения на этом этапе еще не проанализированы и не загружены: как только это произойдет, браузер сначала выдаст событие domComplete, а затем - onLoad.</p>
37 <p>СSS и изображения на этом этапе еще не проанализированы и не загружены: как только это произойдет, браузер сначала выдаст событие domComplete, а затем - onLoad.</p>
38 <h3>Порядок выполнения</h3>
38 <h3>Порядок выполнения</h3>
39 <p>Еще один аргумент за использование defer - скрипты, помеченные как async, выполняются в случайном порядке, тогда как скрипты с defer - в строго определенном.</p>
39 <p>Еще один аргумент за использование defer - скрипты, помеченные как async, выполняются в случайном порядке, тогда как скрипты с defer - в строго определенном.</p>
40 <h2>Как ускорить загрузку страницы</h2>
40 <h2>Как ускорить загрузку страницы</h2>
41 <p>Лучший способ - прописать скрипты в &lt;head&gt; и добавить атрибут defer в тег script. Этот сценарий быстро запускает событие domInteractive :</p>
41 <p>Лучший способ - прописать скрипты в &lt;head&gt; и добавить атрибут defer в тег script. Этот сценарий быстро запускает событие domInteractive :</p>
42  
42