Мегафон

Динамически-создаваемые «асинхронные скрипты» являются вредными. Асинхронная загрузка JavaScript - ускоряем загрузку страниц Text javascript async src загруженное

The HTML element is used to embed or reference executable code; this is typically used to embed or refer to JavaScript code. The element can also be used with other languages, such as WebGL "s GLSL shader programming language.

Content categories Permitted content Tag omission Permitted parents Permitted ARIA roles DOM interface
Metadata content , Flow content , Phrasing content .
Dynamic script such as text/javascript .
None, both the starting and ending tag are mandatory.
Any element that accepts metadata content , or any element that accepts phrasing content .
None
HTMLScriptElement
Attributes async HTML5

For classic scripts, if the async attribute is present, then the classic script will be fetched in parallel to parsing and evaluated as soon as it is available.

crossorigin Normal script elements pass minimal information to the window.onerror for scripts which do not pass the standard CORS checks. To allow error logging for sites which use a separate domain for static media, use this attribute. See CORS settings attributes for a more descriptive explanation of its valid arguments. defer

This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded .

Scripts with the defer attribute will prevent the DOMContentLoaded event from firing until the script has loaded and finished evaluating.

This attribute must not be used if the src attribute is absent (i.e. for inline scripts), in this case it would have no effect.

Examples Basic usage

These examples show how to import (an external) script using the element.

And the following examples show how to put (an inline) script inside the element.

alert("Hello World!");

Module fallback

Browsers that support the module value for the type attribute ignore any script with a nomodule attribute. That enables you to use module scripts while also providing nomodule -marked fallback scripts for non-supporting browsers.

Specifications Specification Status Comments
HTML Living Standard
The definition of "" in that specification.
Living Standard Removed the charset attribute
HTML5
The definition of "" in that specification.
Recommendation
HTML 4.01 Specification
The definition of "" in that specification.
Recommendation
Browser compatibility

The compatibility table in this page is generated from structured data. If you"d like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

Desktop Mobile Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet script async crossorigin defer integrity language

Deprecated Non-standard

nomodule

Experimental

referrerPolicy src text type type.module type: The version parameter of the type attribute

Non-standard

Chrome Full support 1 Edge Full support 12 Firefox Full support 1

Notes

Full support 1

Notes

Notes Starting in Firefox 4, inserting elements that have been created by calling document.createElement("script") no longer enforces execution in insertion order. This change lets Firefox properly abide by the specification. To make script-inserted external scripts execute in their insertion order, set .async=false on them.
IE Full support Yes Opera Full support Yes Safari Full support Yes
Chrome Full support 1 Edge Full support 12 Firefox Full support 1 IE Full support Yes Opera Full support Yes Safari Full support Yes WebView Android Full support Yes Chrome Android Full support Yes Firefox Android Full support 4 Opera Android Full support Yes Safari iOS Full support Yes Samsung Internet Android Full support Yes
Chrome Full support 30 Edge Full support ≤18 Firefox Full support 13 IE No support No Opera Full support 12 Safari Full support Yes

Notes

Full support Yes

Notes

Notes The crossorigin attribute was implemented in WebKit in WebKit bug 81438 .
WebView Android Full support Yes Chrome Android Full support Yes Firefox Android Full support 14 Opera Android ? Safari iOS ? Samsung Internet Android Full support Yes
Chrome Full support Yes

Notes

Full support Yes

Notes

Notes Chromium Issue #611136 , Chromium Issue #874749
Edge Full support 12 Firefox Full support 3.5

Notes

Full support 3.5

Notes

Notes Since Firefox 3.6, the defer attribute is ignored on scripts that don"t have the src attribute. However, in Firefox 3.5 even inline scripts are deferred if the defer attribute is set.
IE Full support 10

Notes

Full support 10

Notes

Notes In versions prior to Internet Explorer 10, it implemented defer by a proprietary specification. Since version 10 it conforms to the W3C specification.
Opera Full support Yes

Notes

Full support Yes

Notes

Notes Chromium Issue #611136 , Chromium Issue #874749
Safari Full support Yes WebView Android Full support Yes

Notes

Full support Yes

Notes

Notes WebView does not defer scripts with the defer attribute when the page is served as XHTML (application/xhtml+xml) - Chromium Issue #611136 , Chromium Issue #874749
Chrome Android Full support Yes

Notes

Full support Yes

Notes

Notes Chrome does not defer scripts with the defer attribute when the page is served as XHTML (application/xhtml+xml) - Chromium Issue #611136 , Chromium Issue #874749
Firefox Android Full support 4 Opera Android Full support Yes

Notes

Full support Yes

Notes

Notes Opera does not defer scripts with the defer attribute when the page is served as XHTML (application/xhtml+xml) - Chromium Issue #611136 , Chromium Issue #874749
Safari iOS Full support Yes Samsung Internet Android Full support Yes

Notes

Full support Yes

Notes

Notes Samsung Internet does not defer scripts with the defer attribute when the page is served as XHTML (application/xhtml+xml) - Chromium Issue #611136 , Chromium Issue #874749
Chrome Full support 45 Edge Partial support 17 Firefox Full support 43 IE No support No Opera Full support Yes Safari Full support Yes WebView Android Full support 45 Chrome Android Full support 45 Firefox Android Full support 43 Opera Android ? Safari iOS No support No Samsung Internet Android Full support 5.0
Chrome Full support 1 Edge Full support 12 Firefox Full support 1 IE Full support Yes Opera Full support Yes Safari Full support Yes WebView Android Full support Yes Chrome Android Full support Yes Firefox Android Full support 4 Opera Android Full support Yes Safari iOS Full support Yes Samsung Internet Android Full support Yes
Chrome Full support 61 Edge Full support 16 Firefox Full support 60 Full support 60 No support 55 - 60

Disabled

Disabled
IE No support No Opera Full support 48 Safari Full support 11 Firefox Android Full support 60 Full support 60 No support 55 - 60

Disabled

Disabled From version 55 until version 60 (exclusive): this feature is behind the dom.moduleScripts.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
Safari iOS Full support 11
Chrome Full support 70 Edge Full support ≤79 Firefox Full support 65 IE No support No Opera Full support Yes Safari No support No WebView Android Full support 70 Chrome Android Full support 70 Firefox Android Full support 65 Opera Android ? Safari iOS No support No Samsung Internet Android Full support 10.0
Chrome Full support 1 Edge Full support 12 Firefox Full support 1 IE Full support Yes Opera Full support Yes Safari Full support Yes WebView Android Full support Yes Chrome Android Full support Yes Firefox Android Full support 4 Opera Android Full support Yes Safari iOS Full support Yes Samsung Internet Android Full support Yes
Chrome Full support 1 Edge Full support 12 Firefox Full support 1 IE Full support Yes Opera Full support Yes Safari Full support Yes WebView Android Full support Yes Chrome Android Full support Yes Firefox Android Full support 4 Opera Android Full support Yes Safari iOS Full support Yes Samsung Internet Android Full support Yes
Chrome Full support 1 Edge Full support 12 Firefox Full support 1 IE Full support Yes Opera Full support Yes Safari Full support Yes WebView Android Full support Yes Chrome Android Full support Yes Firefox Android Full support 4 Opera Android Full support Yes Safari iOS Full support Yes Samsung Internet Android Full support Yes
Chrome Full support 61 Edge Full support 16 Firefox Full support 60 Full support 60 No support 54 - 60

Disabled

Disabled
IE No support No Opera Full support 48 Safari Full support 10.1 WebView Android Full support 61 Chrome Android Full support 61 Firefox Android Full support 60 Full support 60 No support 54 - 60

Disabled

Disabled From version 54 until version 60 (exclusive): this feature is behind the dom.moduleScripts.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
Opera Android Full support 45 Safari iOS Full support 10.3 Samsung Internet Android Full support 8.0
Chrome No support No Edge No support No Firefox No support ? - 59 IE No support No Opera No support No Safari No support No WebView Android No support No Chrome Android No support No Firefox Android No support ? - 59 Opera Android No support No Safari iOS No support No Samsung Internet Android No support No
Legend Full support Full support Partial support Partial support No support No support Compatibility unknown Compatibility unknown Experimental. Expect behavior to change in the future. Experimental. Expect behavior to change in the future. Non-standard. Expect poor cross-browser support. Non-standard. Expect poor cross-browser support. Deprecated. Not for use in new websites. Deprecated. Not for use in new websites. See implementation notes. See implementation notes. User must explicitly enable this feature. Compatibility notes

In older browsers that don"t support the async attribute, parser-inserted scripts block the parser; script-inserted scripts execute asynchronously in IE and WebKit, but synchronously in Opera and pre-4 Firefox. In Firefox 4, the async DOM property defaults to true for script-created scripts, so the default behaviour matches the behaviour of IE and WebKit.

To request script-inserted external scripts be executed in the insertion order in browsers where the document.createElement("script").async evaluates to true (such as Firefox 4), set async="false" on the scripts you want to maintain order.

Never call document.write() from an async script. In Firefox 3.6, calling document.write() has an unpredictable effect. In Firefox 4, calling document.write() from an async script has no effect (other than printing a warning to the error console).

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

var script = document .createElement("script" ); script.src = "http://somehost.com/awesome-widget.js" ; document .getElementsByTagName("head" ).appendChild(script);

В чем разница? В «плохом» варианте мы блокируем построение DOM дерева, ждем пока скрипт загрузится, выполнится, а только потом продолжаем обрабатывать остальную часть документа. Во втором примере мы сразу начинаем выполнять сценарий, который создает элемент script , указывающий на внешний ресурс, добавляем его в документ, и продолжаем обработку DOM. Различие тонкое, но очень важное: динамически-создаваемые скрипты не блокирующие.

Так, это же здорово, верно? Динамически-создаваемые скрипты - это вещь! Не так быстро.

Встраиваемый JavaScript имеет небольшой, но важный (и часто упускаемый из виду) подводный камень: CSSOM блокирует его перед выполнением. Почему? Браузер не знает, что именно такой скрипт планирует сделать, а поскольку JavaScript может манипулировать CSS свойствами, он блокируется и ждет, пока анализируется CSS и строится CSSOM. Лучше один раз увидеть, чем сто раз услышать, рассмотрим следующий пример:

Погодите секундочку, что происходит? Оба сценария будут загружены заранее и выполнены через ~2.7 секунды после загрузки страницы. Обратите внимание, что скрипты будут по прежнему выполняться только после того, как будет доступен CSS (~2.7 секунды), но поскольку скрипты уже загружены в тот момент когда становится доступен CSSOM, мы можем выполнять их сразу, экономя более секунды времени обработки. Мы всё делали неправильно?

Прежде чем мы ответим на этот вопрос, давайте рассмотрим еще один пример, на этот раз с атрибутом «async» :

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

Атрибут async в теге script реализует два важных свойства: он говорит браузеру, чтобы тот не блокировал построение DOM и не блокировал выполнение скриптов перед построением CSSOM. В результате, скрипты выполняются сразу после того, как загрузятся (~1.6 секунды), не дожидаясь CSSOM. Краткий список результатов:

Так почему мы до сих пор предлагали использовать шаблон, использующий динамически создаваемые скрипты?

Оригинальная статья: Script-injected "async scripts" considered harmful Статью вычитывали: visitorFM , zenwalker , FMRobot

Приветствую, друзья! Знаете ли Вы, что загрузка JavaScript является одним из самых узких мест в производительности сайта? Сегодня моя основная задача — объяснить что такое скрипта и каким образом она влияет на быстродействие и производительность сайта.

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

  • конфигурации ,
  • скорости интернет-соединения,
  • размера файла и других…

По этой причине анализатор скорости загрузки сайта Google PageSpeed Insights рекомендует удалить из верхней части страницы код JavaScript, блокирующий ее отображение. Хорошей практикой является размещение скриптов в нижней части сайта, например, перед закрывающим тегом или настройка асинхронной загрузки.

Если код скрипта влияет на отображение верхней части сайта — не выносите его в отдельный файл, а встраивайте непосредственно в HTML.

JS может изменить содержимое сайта и даже перенаправить на другой URL-адрес. В таком случае подключение скрипта в конце документа приведет к эффекту «подергивания» страницы, подгружая новые или изменяя существующие элементы в верхней части.

Применение атрибутов async и defer для тега script

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

< src ="example.js" >

В наглядном примере я буду использовать следующие условные обозначения:

— обработка страницы
— загрузка скрипта
— выполнение скрипта

Таким образом последовательность обработки происходит по следующей схеме:

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

Атрибут defer

Атрибут defer позволяет браузеру начать загрузку js-файлов параллельно, не останавливая дальнейшую обработку страницы. Их выполнение происходит после полного разбора объектной модель документа (от англ. Document Object Model, сокращенно DOM), при этом браузер гарантирует последовательность на основе порядка подключения файлов.

< defer src ="example.js" > Атрибут async

Поддержка атрибута async появилась в HTML5, он разрешает браузеру загружать js-файлы параллельно и выполнять сразу после загрузки, не дожидаясь обработки остальной части страницы.

< async src ="example.js" >

Схема последовательности обработки:

Это асинхронная загрузка. Атрибут рекомендуется применять для таких скриптов, которые не оказывают значительного влияния на отображение документа. К ним относятся счетчики сбора статистики (Google Analytics, Яндекс Метрика), коды рекламных сетей (Рекламная сеть Яндекса, Google AdSense), кнопки социальных сетей и так далее.

Скорость загрузки сайта — один из факторов ранжирования в Google.

Асинхронное подключение JavaScript снижает время загрузки страниц за счет отсутствия задержки. Наряду с этим я рекомендую сжимать и объединять js-файлы в один, например, с помощью библиотеки . Пользователям нравятся быстрые сайты 😎

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

Есть несколько подходов. Начну по порядку.

script src= type= "text/javascript" >

Асинхронная загрузка скрипта HTML5

Стандарт HTML5 поддерживает возможность асинхронной загрузки скриптов, что может значительно ускорить общее время получения страницы. Просто добавьте async или defer .

< script async src= "http://www.site.ru/script.js" type= "text/javascript" >

< script defer src= "http://www.site.ru/script.js" type= "text/javascript" >

Чем же отличаются атрибуты async и defer

В обоих случаях мы получаем асинхронную загрузку скриптов. Разница заключается только в моменте, когда скрипт начинает выполнятся. Скрипт с атрибутом async выполнится при первой же возможности после его полной загрузки, но до загрузки объекта window. В случае использования атрибута defer – скрипт не нарушит порядок своего выполнения по отношению к остальным скриптам и его выполнение произойдет после полной загрузки и парсинга страницы, но до события DOMContentLoaded объекта document.

К сожалению, этот механизм на сегодняшний день не работает во всех браузерах (особенно это касается IE). Также не будет работать, если в файле script.js есть строки document.write .

Асинхронная загрузка javascript скриптом от Google

Как известно всем мастерам, Google уделяет особое внимание скорости загрузки сайтов, и понижает медленные в поисковой выдаче. Что бы помочь, Гугл разработал специальный скрипт, при помощи которого можно сделать асинхронную загрузку javascript.

Чтобы использовать, просто заменяем

на

И подключаем файл скрипта extsrc.js

Получится так:

< script src= "http://extsrcjs.googlecode.com/svn/trunk/extsrc.js" > < script extsrc= "...." >

К сожалению, этот способ тоже не подойдет к файлам с document.write

Лучшая рабочая асинхронная загрузка javascript

Универсальный способ для всех браузеров. Работает даже с document.write

В том месте страницы, где нужно реально отобразить наш элемент создаем пустой div блок:

< div id= "script_block" class = "script_block" >

В самом конце страницы перед вставляем скрипт для асинхронной загрузки файлов:

< div id= "script_ad" class = "script_ad" style= "display:none;" > Здесь любой файл или скрипт, который нужно загрузить. < script type= "text/javascript" > // переместить его в реальную позицию отображения document. getElementById("script_block" ) . appendChild(document. getElementById("script_ad" ) ) ; // показать document. getElementById("script_ad" ) . style. display = "block" ;

В самых старых версиях IE (6 и ниже) асинхронная загрузка к сожалению не работает, но таких пользователей уже практически нет. Все остальные браузеры и сервисы успешно пользуются современной ускоренной загрузкой web-страниц.