SlideShare a Scribd company logo
Non-Blocking JavaScript
Dmitriy Yakubovskiy
Параллельные загрузки
Потоки по браузерам *
Firefox 3+
6 потоков
Chrome
6 потоков
Safari 3-4
4 потока
Safari 5
6 потоков
Opera 12
6 потоков
IE 6-7
2 потока
IE 8-9
6 потоков
IE 10
8 потоков
* - число параллельных соединений к одному хосту
Процесс отрисовки
Исходный HTML DOM дерево Дерево отрисовки
DOMContentLoaded
- событие срабатывает при загрузке документа, кроме IE<9
- ждет css, если после него идет скрипт
- ждёт загрузки и выполнения скриптов (кроме скриптов с
async/defer, если есть поддержка и динамических)
- в FF/Chrome формы автозаполняются по
DOMContentLoaded
- интерфейсы обычно инициализируются по
DOMContentLoaded
DOMContentLoaded (Firefox)
Скрипты на странице*
Во время загрузки
Во время выполнения
- блокируется отрисовка страницы
- блокируют вообще все загрузки (IE<8, Opera<15)
- блокируют все загрузки, кроме стилей и скриптов
(IE8, FF, Chrome, Safari)
- остальные загрузки не блокируются (IE>8)
- ждет пока загрузятся предшествующие css файлы
- блокируют вообще всё
* - распространяется на скрипты со всех хостов
Скрипты в HEAD
IE6-7
Скрипты в HEAD
IE8
Скрипты в HEAD
IE9
Скрипты в HEAD
Сhrome / Safari / FF
Скрипты в конце BODY
Chrome
- не блокируется рендеринг страницы
- не блокируются загрузки предыдущих ресурсов
- страница доступна до инициализации скриптов
Заглушки интерфейсов
<link rel="stylesheet" type="text/css" href="styles.css" />
<!--[if lte IE 8]>
<link rel="stylesheet" type="text/css" href="ie.css">
<![endif]-->
Conditional Comments (IE)
Conditional Comments (IE)
<!--[if IE]><![endif]-->
<link rel="stylesheet" type="text/css" href="styles.css" />
<!--[if lte IE 8]>
<link rel="stylesheet" type="text/css" href="ie.css">
<![endif]-->
Не блокирующие скрипты
- document.write
- script in iframe
- script defer
- script async
- XMLHttpRequest Eval
- XMLHttpRequest Injection
- Script DOM
document.write
IE6
document.write('<scr'+'ipt src="jquery.js"></scr'+'ipt>');
document.write('<scr'+'ipt src="scripts.js"></scr'+'ipt>');
- не блокирует другие скрипты
- сохраняет порядок выполнения
- блокирует рендеринг, загрузку css/img
- актуально только для IE<8, Opera<15
script in iframe
- не блокирует рендеринг / загрузки
- необходимо вносить изменения в скрипты
- ограничение по домену
<iframe src='script.html' id="f1"></iframe>
<iframe src='script2.html' id="f2"></iframe>
script defer
- по стандарту только для внешних скриптов
- не блокирует рендеринг / загрузки
- выполнение после рендеринга страницы
- сохраняется порядок выполнения (кроме IE<10)
- IE4+, FF3.1+, Chrome 8+, Safari 5.1+, Opera 15+
<script src="jquery.js" defer></script>
<script src="scripts.js" defer></script>
script async
- по стандарту только для внешних скриптов
- не блокирует рендеринг / загрузки
- выполнение сразу после загрузки
- не сохраняется порядок выполнения
- IE10+, FF3.6+, Chrome 8+, Safari 5.1+, Opera 15+
<script src="script1.js" async></script>
<script src="script2.js" async></script>
XMLHttpRequest Eval
var xhr = getXmlHttp();
xhr.open("GET", "script.js", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
eval.call(window, xhr.responseText);
}
}
xhr.send(null);
- не блокирует рендеринг / загрузки
- не сохраняется порядок выполнения
- ограничение по домену
- нет индикации загрузки
XMLHttpRequest Injection
- не блокирует рендеринг / загрузки
- не сохраняется порядок выполнения
- ограничение по домену
- нет индикации загрузки
var xhr = getXmlHttp();
xhr.open("GET", "script.js", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var s=document.createElement('script');
document.getElementsByTagName('head')[0]
.appendChild(s);
s.text = xhr.responseText;
}
} xhr.send(null);
Script DOM
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = 'app.js';
document.getElementsByTagName('head')[0]
.appendChild(script);
- не блокирует рендеринг / загрузки
- не сохраняется порядок выполнения, кроме Opera<15
- async:true для Firefox 3.6, чтобы не сохранять порядок
- нет ограничений на домен
Script DOM + async:false
- не блокирует рендеринг / загрузки
- сохраняется порядок выполнения (кроме браузеров,
которые не поддерживают async, но не FF<3.6 и Opera)
- нет ограничений на домен
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = false;
script.src = 'app.js';
document.getElementsByTagName('head')[0]
.appendChild(script);
Script DOM + onreadystatechange
- не блокирует рендеринг / загрузки
- позволяет гибко управлять загрузкой / выполнением
- нет ограничений на домен
- только IE6+
var js = document.createElement('script');
js.onreadystatechange = function() {
if (js.readyState == 'loaded') {
document.body.appendChild(js); // execution
}
};
js.src = 'app.js';
Порядок загрузки не важен
Цель:
- Загрузить скрипты параллельно
- Выполнить сразу после загрузки
- Не блокировать рендеринг
- Не блокировать загрузку других ресурсов
- Кроссбраузерное решение
Решение: Script DOM
Порядок загрузки важен
Цель:
- Загрузить скрипты параллельно
- Выполнить последовательно
- Не блокировать рендеринг
- Не блокировать загрузку других ресурсов
- Кроссбраузерное решение
Решение: Script DOM + async:false / onreadystatechange
для IE / document.write для остальных браузеров
Техники связывания
- window onload
- timer
- script onload
- callback (m)
- degrading script tags (m)
m - требует модификации скриптов
Техники связывания
<script type="text/javascript">
function init() {
...
App.start();
...
}
init();
</script>
<script type="text/javascript" src="app.js"></script>
window onload
if ( window.addEventListener ) {
window.addEventListener("load", init, false);
}
else if ( window.attachEvent ) {
window.attachEvent("onload", init);
}
- просто в реализации
- инициализация срабатывает слишком поздно
timer
function timer(interval) {
if ( typeof(jQuery) === "undefined" ) {
setTimeout(timer, interval);
}
else {
init();
}
}
timer(300);
- просто в реализации
- лишние расходы ресурсов на выполнение скрипта
- задержка при слишком большом интервале
script onload
js.onload = function() {
if ( !js.done ) {
js.done = true; init();
}
};
js.onreadystatechange = function() {
if ( !js.done &&
js.readyState.match(/loaded|complete/) ) {
js.done = true; init();
}
};
- выполнение инлайн скрипта максимально быстро
- немного сложнее в реализации
callback (m)
- выполнение инлайн скрипта максимально быстро
- вызов init() в конце app.js
- не гибкое решение
- требует модификации скриптов
function init() { ... }
var js = document.createElement('script');
js.src = "app.js"; document.getElementsByTagName('head')
[0].appendChild(js);
degrading script tags (m)
function init() { ... }
var js = document.createElement('script');
js.src = "app.js";
js.text = "init();"; document.getElementsByTagName('head')
[0].appendChild(js);
- гибкое решение
- требует модификации скриптов
inline script
<script type="text/javascript" src="app.js">
init();
</script>
degrading script tags (m)
var fs = document.getElementsByTagName("script");
var len = fs.length;
while ( len ) {
var s = fs[len-1];
if ( s.src.indexOf('app.js') != -1 ) {
eval( s.innerHTML );
break;
}
len--;
}
app.js
Загрузчики
- $script.js
- YepNope.js
- Control.js
- LAB.js
- Head.js
- Load.js
- Require.js
Как будем загружать
сам загрузчик?
Загрузка виджетов
● Добавление через DOM
● Связывание через
onload/onreadystatechange
● document.write()
○ Делаем свой document.write()
○ Выносим виджет в отдельный
невидимый элемент
○ Загружаем в скрытый iframe,
по onload копируем на страницу
Загрузка виджетов
(function(d, s) {
var js, fjs = d.getElementsByTagName(s)[0],
load = function(url, id) {
if (d.getElementById(id)) {return;}
js = d.createElement(s);
js.src = url;
js.id = id;
fjs.parentNode.insertBefore(js, fjs);
};
load('widget1.js', 'fbjssdk');
load('widget2.js', 'gplus1js');
load('widget3.js', 'tweetjs');
}(document, 'script'));
Преимущества подхода
Страница не виснет из-за сторонних виджетов
Управление виджетами из одного места
Гарантия подключения узла всего один раз (ID)
Постзагрузка виджетов
Постзагрузка виджетов
Полезные материалы
Ресурсы
www.browserscope.org
www.stevesouders.com
Книга
Steve Souders - Even Faster Web Sites
Таблица сравнения загрузчиков
https://spreadsheets.google.com/a/sysiq.com/lv?
key=tDdcrv9wNQRCNCRCflWxhYQ
● WebPageTest Online (www.webpagetest.org)
● Webkit Developer Toolbar (Timeline Tab)
● Firebug for FF (YSlow add-on, Net Tab)
● Fiddler (Web Debugging Proxy)
● DynaTrace Ajax Edition
● Sloppy (proxy server)
Инструменты
Вопросы?
Задавайте умные вопросы.
Получайте умные ответы.
Dmitriy Yakubovskiy
d.iakubovskiy@sysiq.com

More Related Content

PDF
Современный фронтенд -- как не утонуть в море хайпа?
PDF
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
PDF
Dump-IT Загрузка и инициализация JavaScript
PPTX
base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)
PPTX
Как сделать проект с 1 500 000 просмотров в сутки, который не ломается - IzhD...
PDF
Как мы разрабатываем новый фронтенд / Филипп Нехаев (Tinkoff.ru)
PDF
Фронтенд разработка без боли
PDF
Николай Сиварев "Приручая сайты"
Современный фронтенд -- как не утонуть в море хайпа?
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
Dump-IT Загрузка и инициализация JavaScript
base.network — пиринговый веб на JavaScript / Денис Глазков (Lazada Rus)
Как сделать проект с 1 500 000 просмотров в сутки, который не ломается - IzhD...
Как мы разрабатываем новый фронтенд / Филипп Нехаев (Tinkoff.ru)
Фронтенд разработка без боли
Николай Сиварев "Приручая сайты"

What's hot (20)

PDF
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
PDF
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
PDF
#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...
PPTX
JavaScript-модули "из прошлого в будущее"
PDF
HTML5 Web Components: следующий шаг к модульности вашего проекта / Андрей Рах...
PDF
Изоморфный JavaScript — будущее уже здесь
PPT
Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)
PDF
Как Webpack сделал меня счастливее
PDF
Современный фронтенд за 30 минут.
PDF
Евгений Батовский, Николай Птущук "Современный станок верстальщика"
PPTX
Webpack integration
PPT
Воюем за ресурсы (ZFConf2011)
PDF
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
PPTX
Безопасность Node.js / Илья Вербицкий (Независимый консультант)
PPTX
Виталий Ратушный "Vue: webcomponents"
PPT
ZFConf 2011: Воюем за ресурсы: Повышение производительности Zend Framework пр...
PPTX
Первые шаги с RabbitMQ
PPTX
Применяем Ansible
PDF
HTML GL - возьмите столько FPS, сколько вам нужно, и немного эффектов в прида...
PDF
«​Масштабируемый DevOps​» Александр Колесень
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
#3 "Webpack и Vue.JS: Создание больших приложений и их расширение" Кирилл Кай...
JavaScript-модули "из прошлого в будущее"
HTML5 Web Components: следующий шаг к модульности вашего проекта / Андрей Рах...
Изоморфный JavaScript — будущее уже здесь
Стажировка-2014, занятие 8. Обзор Sails framework (Node.js)
Как Webpack сделал меня счастливее
Современный фронтенд за 30 минут.
Евгений Батовский, Николай Птущук "Современный станок верстальщика"
Webpack integration
Воюем за ресурсы (ZFConf2011)
55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)
Безопасность Node.js / Илья Вербицкий (Независимый консультант)
Виталий Ратушный "Vue: webcomponents"
ZFConf 2011: Воюем за ресурсы: Повышение производительности Zend Framework пр...
Первые шаги с RabbitMQ
Применяем Ansible
HTML GL - возьмите столько FPS, сколько вам нужно, и немного эффектов в прида...
«​Масштабируемый DevOps​» Александр Колесень
Ad

Viewers also liked (20)

PDF
User Behavior: Interacting With Important Website Elements
PDF
Testing schools overview
PPT
Психология восприятия и UX дизайн
PDF
PDF
Developing for e commerce is important
PDF
Speed Up Your Website
PDF
PPT
Модульные сетки в реальном мире - IQLab Frontend Fusion 2012
PPT
Доступность веб-сайтов: WWW для всех?
PPT
Эффективный JavaScript - IQLab Frontend Fusion 2012
PPT
Правила хорошего SEO тона в Frontend разработке
PDF
Databases on Client Side
PDF
Seo and Marketing Requirements in Web Architecture
PPT
Гибкость и Структурированность Oбъектно Oриентированноя CSS
PDF
QA evolution, in pictures
PPT
Mastering Java ByteCode
PDF
Management and Communications (IPAA)
PDF
Lupan big enterprise ecommerce fusion 2013
User Behavior: Interacting With Important Website Elements
Testing schools overview
Психология восприятия и UX дизайн
Developing for e commerce is important
Speed Up Your Website
Модульные сетки в реальном мире - IQLab Frontend Fusion 2012
Доступность веб-сайтов: WWW для всех?
Эффективный JavaScript - IQLab Frontend Fusion 2012
Правила хорошего SEO тона в Frontend разработке
Databases on Client Side
Seo and Marketing Requirements in Web Architecture
Гибкость и Структурированность Oбъектно Oриентированноя CSS
QA evolution, in pictures
Mastering Java ByteCode
Management and Communications (IPAA)
Lupan big enterprise ecommerce fusion 2013
Ad

Similar to non-blocking java script (19)

PPT
параллельная загрузка Java script и css файлов без прерывания
PPT
Web весна 2013 лекция 9
PDF
Асинхронный JavaScript
PPT
Web весна 2012 лекция 9
PDF
FrontDays #1. Илья Кучмин, Оптимизация загрузки тяжелых страниц
PDF
A.pleshkov
PDF
Михаил Давыдов "Масштабируемые JavaScript-приложения"
PPT
Вебинар "Оптимизация производительности мобильных веб-приложений"
PDF
Оптимизация JavaScript в Drupal
PPTX
Async Javascript
PDF
JavaScript Базовый. Занятие 08.
PPTX
Обзор возможностей HTML5
PPTX
Обзор возможностей HTML5
PPTX
Что делать, когда у вас 100 партнеров / Иван Потапов (Lamoda)
PDF
Асинхронная модульность в API Яндекс.Карт — Александр Зинчук
PPT
Эффективное программирование на NodeJS
PDF
Азат Разетдинов "Оптимизация времени загрузки на примере Яндекс.Карт"
PDF
Optimizaciya vremeni zagruzki_azat_razetdinov
PDF
Иван Карев — Клиентская оптимизация
параллельная загрузка Java script и css файлов без прерывания
Web весна 2013 лекция 9
Асинхронный JavaScript
Web весна 2012 лекция 9
FrontDays #1. Илья Кучмин, Оптимизация загрузки тяжелых страниц
A.pleshkov
Михаил Давыдов "Масштабируемые JavaScript-приложения"
Вебинар "Оптимизация производительности мобильных веб-приложений"
Оптимизация JavaScript в Drupal
Async Javascript
JavaScript Базовый. Занятие 08.
Обзор возможностей HTML5
Обзор возможностей HTML5
Что делать, когда у вас 100 партнеров / Иван Потапов (Lamoda)
Асинхронная модульность в API Яндекс.Карт — Александр Зинчук
Эффективное программирование на NodeJS
Азат Разетдинов "Оптимизация времени загрузки на примере Яндекс.Карт"
Optimizaciya vremeni zagruzki_azat_razetdinov
Иван Карев — Клиентская оптимизация

More from Ecommerce Solution Provider SysIQ (15)

PDF
Unexpected achievements 2013
PDF
Getting to know magento
PDF
Developing for e commerce is important
PDF
PDF
Scalability and performance for e commerce
PDF
QA evolution to the present day
PDF
Quick Intro to Clean Coding
PDF
Manifest of modern engineers
PPTX
IGears: Template Architecture and Principles
PPT
Interactive web prototyping
PPT
Модульные сетки в реальном мире
PPT
External Widgets Performance
PPT
Understanding Annotations in Java
PPT
Frontend Servers and NGINX: What, Where and How
Unexpected achievements 2013
Getting to know magento
Developing for e commerce is important
Scalability and performance for e commerce
QA evolution to the present day
Quick Intro to Clean Coding
Manifest of modern engineers
IGears: Template Architecture and Principles
Interactive web prototyping
Модульные сетки в реальном мире
External Widgets Performance
Understanding Annotations in Java
Frontend Servers and NGINX: What, Where and How

non-blocking java script

  • 3. Потоки по браузерам * Firefox 3+ 6 потоков Chrome 6 потоков Safari 3-4 4 потока Safari 5 6 потоков Opera 12 6 потоков IE 6-7 2 потока IE 8-9 6 потоков IE 10 8 потоков * - число параллельных соединений к одному хосту
  • 4. Процесс отрисовки Исходный HTML DOM дерево Дерево отрисовки
  • 5. DOMContentLoaded - событие срабатывает при загрузке документа, кроме IE<9 - ждет css, если после него идет скрипт - ждёт загрузки и выполнения скриптов (кроме скриптов с async/defer, если есть поддержка и динамических) - в FF/Chrome формы автозаполняются по DOMContentLoaded - интерфейсы обычно инициализируются по DOMContentLoaded
  • 7. Скрипты на странице* Во время загрузки Во время выполнения - блокируется отрисовка страницы - блокируют вообще все загрузки (IE<8, Opera<15) - блокируют все загрузки, кроме стилей и скриптов (IE8, FF, Chrome, Safari) - остальные загрузки не блокируются (IE>8) - ждет пока загрузятся предшествующие css файлы - блокируют вообще всё * - распространяется на скрипты со всех хостов
  • 12. Скрипты в конце BODY Chrome - не блокируется рендеринг страницы - не блокируются загрузки предыдущих ресурсов - страница доступна до инициализации скриптов
  • 14. <link rel="stylesheet" type="text/css" href="styles.css" /> <!--[if lte IE 8]> <link rel="stylesheet" type="text/css" href="ie.css"> <![endif]--> Conditional Comments (IE)
  • 15. Conditional Comments (IE) <!--[if IE]><![endif]--> <link rel="stylesheet" type="text/css" href="styles.css" /> <!--[if lte IE 8]> <link rel="stylesheet" type="text/css" href="ie.css"> <![endif]-->
  • 16. Не блокирующие скрипты - document.write - script in iframe - script defer - script async - XMLHttpRequest Eval - XMLHttpRequest Injection - Script DOM
  • 17. document.write IE6 document.write('<scr'+'ipt src="jquery.js"></scr'+'ipt>'); document.write('<scr'+'ipt src="scripts.js"></scr'+'ipt>'); - не блокирует другие скрипты - сохраняет порядок выполнения - блокирует рендеринг, загрузку css/img - актуально только для IE<8, Opera<15
  • 18. script in iframe - не блокирует рендеринг / загрузки - необходимо вносить изменения в скрипты - ограничение по домену <iframe src='script.html' id="f1"></iframe> <iframe src='script2.html' id="f2"></iframe>
  • 19. script defer - по стандарту только для внешних скриптов - не блокирует рендеринг / загрузки - выполнение после рендеринга страницы - сохраняется порядок выполнения (кроме IE<10) - IE4+, FF3.1+, Chrome 8+, Safari 5.1+, Opera 15+ <script src="jquery.js" defer></script> <script src="scripts.js" defer></script>
  • 20. script async - по стандарту только для внешних скриптов - не блокирует рендеринг / загрузки - выполнение сразу после загрузки - не сохраняется порядок выполнения - IE10+, FF3.6+, Chrome 8+, Safari 5.1+, Opera 15+ <script src="script1.js" async></script> <script src="script2.js" async></script>
  • 21. XMLHttpRequest Eval var xhr = getXmlHttp(); xhr.open("GET", "script.js", true); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { eval.call(window, xhr.responseText); } } xhr.send(null); - не блокирует рендеринг / загрузки - не сохраняется порядок выполнения - ограничение по домену - нет индикации загрузки
  • 22. XMLHttpRequest Injection - не блокирует рендеринг / загрузки - не сохраняется порядок выполнения - ограничение по домену - нет индикации загрузки var xhr = getXmlHttp(); xhr.open("GET", "script.js", true); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var s=document.createElement('script'); document.getElementsByTagName('head')[0] .appendChild(s); s.text = xhr.responseText; } } xhr.send(null);
  • 23. Script DOM var script = document.createElement('script'); script.type = 'text/javascript'; script.async = true; script.src = 'app.js'; document.getElementsByTagName('head')[0] .appendChild(script); - не блокирует рендеринг / загрузки - не сохраняется порядок выполнения, кроме Opera<15 - async:true для Firefox 3.6, чтобы не сохранять порядок - нет ограничений на домен
  • 24. Script DOM + async:false - не блокирует рендеринг / загрузки - сохраняется порядок выполнения (кроме браузеров, которые не поддерживают async, но не FF<3.6 и Opera) - нет ограничений на домен var script = document.createElement('script'); script.type = 'text/javascript'; script.async = false; script.src = 'app.js'; document.getElementsByTagName('head')[0] .appendChild(script);
  • 25. Script DOM + onreadystatechange - не блокирует рендеринг / загрузки - позволяет гибко управлять загрузкой / выполнением - нет ограничений на домен - только IE6+ var js = document.createElement('script'); js.onreadystatechange = function() { if (js.readyState == 'loaded') { document.body.appendChild(js); // execution } }; js.src = 'app.js';
  • 26. Порядок загрузки не важен Цель: - Загрузить скрипты параллельно - Выполнить сразу после загрузки - Не блокировать рендеринг - Не блокировать загрузку других ресурсов - Кроссбраузерное решение Решение: Script DOM
  • 27. Порядок загрузки важен Цель: - Загрузить скрипты параллельно - Выполнить последовательно - Не блокировать рендеринг - Не блокировать загрузку других ресурсов - Кроссбраузерное решение Решение: Script DOM + async:false / onreadystatechange для IE / document.write для остальных браузеров
  • 28. Техники связывания - window onload - timer - script onload - callback (m) - degrading script tags (m) m - требует модификации скриптов
  • 29. Техники связывания <script type="text/javascript"> function init() { ... App.start(); ... } init(); </script> <script type="text/javascript" src="app.js"></script>
  • 30. window onload if ( window.addEventListener ) { window.addEventListener("load", init, false); } else if ( window.attachEvent ) { window.attachEvent("onload", init); } - просто в реализации - инициализация срабатывает слишком поздно
  • 31. timer function timer(interval) { if ( typeof(jQuery) === "undefined" ) { setTimeout(timer, interval); } else { init(); } } timer(300); - просто в реализации - лишние расходы ресурсов на выполнение скрипта - задержка при слишком большом интервале
  • 32. script onload js.onload = function() { if ( !js.done ) { js.done = true; init(); } }; js.onreadystatechange = function() { if ( !js.done && js.readyState.match(/loaded|complete/) ) { js.done = true; init(); } }; - выполнение инлайн скрипта максимально быстро - немного сложнее в реализации
  • 33. callback (m) - выполнение инлайн скрипта максимально быстро - вызов init() в конце app.js - не гибкое решение - требует модификации скриптов function init() { ... } var js = document.createElement('script'); js.src = "app.js"; document.getElementsByTagName('head') [0].appendChild(js);
  • 34. degrading script tags (m) function init() { ... } var js = document.createElement('script'); js.src = "app.js"; js.text = "init();"; document.getElementsByTagName('head') [0].appendChild(js); - гибкое решение - требует модификации скриптов inline script <script type="text/javascript" src="app.js"> init(); </script>
  • 35. degrading script tags (m) var fs = document.getElementsByTagName("script"); var len = fs.length; while ( len ) { var s = fs[len-1]; if ( s.src.indexOf('app.js') != -1 ) { eval( s.innerHTML ); break; } len--; } app.js
  • 36. Загрузчики - $script.js - YepNope.js - Control.js - LAB.js - Head.js - Load.js - Require.js Как будем загружать сам загрузчик?
  • 37. Загрузка виджетов ● Добавление через DOM ● Связывание через onload/onreadystatechange ● document.write() ○ Делаем свой document.write() ○ Выносим виджет в отдельный невидимый элемент ○ Загружаем в скрытый iframe, по onload копируем на страницу
  • 38. Загрузка виджетов (function(d, s) { var js, fjs = d.getElementsByTagName(s)[0], load = function(url, id) { if (d.getElementById(id)) {return;} js = d.createElement(s); js.src = url; js.id = id; fjs.parentNode.insertBefore(js, fjs); }; load('widget1.js', 'fbjssdk'); load('widget2.js', 'gplus1js'); load('widget3.js', 'tweetjs'); }(document, 'script'));
  • 39. Преимущества подхода Страница не виснет из-за сторонних виджетов Управление виджетами из одного места Гарантия подключения узла всего один раз (ID)
  • 42. Полезные материалы Ресурсы www.browserscope.org www.stevesouders.com Книга Steve Souders - Even Faster Web Sites Таблица сравнения загрузчиков https://spreadsheets.google.com/a/sysiq.com/lv? key=tDdcrv9wNQRCNCRCflWxhYQ
  • 43. ● WebPageTest Online (www.webpagetest.org) ● Webkit Developer Toolbar (Timeline Tab) ● Firebug for FF (YSlow add-on, Net Tab) ● Fiddler (Web Debugging Proxy) ● DynaTrace Ajax Edition ● Sloppy (proxy server) Инструменты