Загрузка JavaScript является одним из самых больших узких мест в производительности. При обычных обстоятельствах тег script
заставляет браузер остановить рендеринг, загрузить файл и запустить код. Браузер заблокирован от выполнения другой полезной работы, потому что ваш JavaScript может писать на страницу, изменять существующие элементы или перенаправлять на другой URL. По этой причине рекомендуется размещать теги script
в нижней части HTML, непосредственно перед </ тело>. Браузер может не отвечать на секунду или две, но это незаметно, поскольку основной контент уже загружен. Однако даже это решение не подходит для современных мультимегабайтных клиентских приложений. В крайних случаях необходимо загружать большие библиотеки кода, используя инъекции тегов script
или методы Ajax. Это предотвращает блокировку, но требует дополнительного кода и тщательного тестирования, чтобы гарантировать, что сценарии работают в правильном порядке во всех браузерах.
Атрибут defer
Атрибут defer
дает торжественное обещание браузеру. В нем говорится, что ваш JavaScript не содержит никаких изменений в document.write
или DOM:
<script src="file.js" defer></script>
Браузер начнет загружать файл.js и другие отложенные сценарии параллельно, не останавливая обработку страницы. defer
была реализована в Internet Explorer версии 4.0 — более 12 лет назад! Он также доступен в Firefox начиная с версии 3.5. Хотя все отложенные сценарии гарантированно выполняются последовательно, трудно определить, когда это произойдет. Теоретически, это должно произойти после полной загрузки DOM, незадолго до события DOMContentLoaded. На практике это зависит от операционной системы и браузера, от того, кэшируется ли скрипт и какие другие скрипты делают в данный момент.
async
атрибут
async
был введен в HTML5:
<script src="file.js" async></script>
async
идентичен defer
, за исключением того, что скрипт выполняется при первой возможности после загрузки (необязательный атрибут onload
может быть добавлен для запуска определенной функции). Вы не можете гарантировать, что сценарии будут выполняться последовательно, но они будут загружены к моменту запуска события onload
окна. Существует поддержка async
в Firefox 3.6, Opera 10.5 и последней сборке WebKit, поэтому она должна появиться в следующем версии Chrome и Safari. IE9 еще не поддерживает async
, но команда IE может легко добавить его в качестве псевдонима для defer
. Вы можете использовать async
и defer
для поддержки всех браузеров — даже IE4.Возможно, через несколько месяцев у нас наконец появится собственный, неблокирующий метод загрузки JavaScript, который работает во всех браузерах.
Opera предоставляет экспериментальное средство отложенного выполнения сценариев, которое можно включить в about: config . Он запоминает, где на странице был загружен async
скрипт, поэтому можно использовать document.write
или изменить DOM. Эта функция сразу же принесет пользу виджетам и объявлениям, которые блокируют загрузку страницы. Будем надеяться, что Microsoft, Mozilla и WebKit последуют примеру Opera.