Your SlideShare is downloading. ×

non-blocking java script

3,426

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,426
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
11
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Non-Blocking JavaScript Dmitriy Yakubovskiy
  • 2. Параллельные загрузки
  • 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
  • 6. DOMContentLoaded (Firefox)
  • 7. Скрипты на странице* Во время загрузки Во время выполнения - блокируется отрисовка страницы - блокируют вообще все загрузки (IE<8, Opera<15) - блокируют все загрузки, кроме стилей и скриптов (IE8, FF, Chrome, Safari) - остальные загрузки не блокируются (IE>8) - ждет пока загрузятся предшествующие css файлы - блокируют вообще всё * - распространяется на скрипты со всех хостов
  • 8. Скрипты в HEAD IE6-7
  • 9. Скрипты в HEAD IE8
  • 10. Скрипты в HEAD IE9
  • 11. Скрипты в HEAD Сhrome / Safari / FF
  • 12. Скрипты в конце BODY Chrome - не блокируется рендеринг страницы - не блокируются загрузки предыдущих ресурсов - страница доступна до инициализации скриптов
  • 13. Заглушки интерфейсов
  • 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)
  • 40. Постзагрузка виджетов
  • 41. Постзагрузка виджетов
  • 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) Инструменты
  • 44. Вопросы? Задавайте умные вопросы. Получайте умные ответы.
  • 45. Dmitriy Yakubovskiy d.iakubovskiy@sysiq.com

×