четверг, 23 сентября 2010 г.

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

Ночная версия WebKit отныне поддерживает свойства async и defer тэга script, появившиеся в HTML5. Таким образом скорость загрузки страницы возрастает, так как одновременно происходит и загрузка скриптов и рендеринг страницы.

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


<script src="myBlockingscript.js"></script>

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

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


<script async src="myAsyncscript.js" onload="myInit()"></script>
<script defer src="myDeferscript.js" onload="myInit()"></script>

В обоих случаях скрипты, помеченные как async или defer, начинают незамедлительно скачиваться, не вызывая при этом остановок парсера, причем оба скрипта поддерживают onload обработчик, позволяющий вызвать те или иные события, когда скрипт будет загружен. Каждый скрипт, помеченный async, будет выполнен в тот момент, когда для это появится возможность после его полной загрузки, но до того как будет выброшено событие о загрузке window. Это означает, что такие скрипты скорее всего будут выполнены не в том порядке, в котором они указаны на странице. А вот наличие deferскриптов гарантирует, что как они указаны, так они и будут загружаться. Их выполнение начнется после завершения работы парсера, но до появления события DOMContentLoaded.

Вот пример, в котором время загрузки внешнего скрипта занимает 1 секунда, следом за ним идет выполнение скрипта, находящегося в теле страницы, на что уходит еще 1 секунда. В итоге загрузка страницы занимает 2 секунды.



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



В дополнении к сказанному, хочется отметить, что Firefox достаточно давно поддерживал свойства defer и onload, а в версии 3.6 была добавлена поддержка async. Internet Explorer так же давно поддерживает параметр defer. Свойство async по-прежнему не будет поддерживать ни в одной из версий, тогда как onload появится уже в 9 версии.

Related Posts by Categories



1 комментарий:

  1. Круто. Про эту вешь я писал в своем блоге: http://plutov.by/post/javascript_memory

    ОтветитьУдалить