Войти через VK Войти через FB Войти через Google Войти через Яндекс
Поиск по сайту
Паралельная загрузка скрипта javascript и выполнение по onDomReady
Анализируйя скорость загрузки очередного сложного сайта, содержащего много javascript скриптов я задумался как ускорить загрузку.
Проблема заключается в том, что при выносе большинства скриптов в отдельный файл и указания для него паралельной загрузки с помощью параметра
defer=”defer”
:
<script type="text/javascript" src="/js.js" defer="defer"></script>
Вы не сможете обращаться к функциям и переменным находящимся в js.js из html кода страницы до окончания загрузки. Более того, что загрузится раньше js-скрипт или html-страница - тоже неизвестно, т.е. по ходу загрузки js файла делать что-то со страницей тоже нельзя. То ли скрипт то ли объектная модель. Для комплексного решения я использую следующую схему:
Загружаю скрипт в независимом потоке
<script type="text/javascript" src="/js.js" defer="defer"></script>
В файле js.js я добавил следующий код:
if(!document.funcDomReady)document.funcDomReady='';
function onDomReady(func) {
var oldonload = document.funcDomReady;
document.funcDomReady=function(){if(typeof oldonload == 'function')oldonload(); func();};
}
function init() { // функция вызываемая после загрузки объектной можели
if (arguments.callee.done) return;
arguments.callee.done = true;
if(document.funcDomReady){document.funcDomReady();document.funcDomReady='';} // вызываем всю цепочку обработчиков
}
if(document.addEventListener)document.addEventListener("DOMContentLoaded", init, false);
/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=\"__ie_onload\" defer=\"defer\" src=\"javascript:void(0)\"></script>");
var script = document.getElementById("__ie_onload");
script.onreadystatechange = function(){if (this.readyState=="complete")init();};
/*@end @*/
if(/WebKit/i.test(navigator.userAgent)) { // для Safari
var _timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
clearInterval(_timer);
init(); // вызываем обработчик для onload
}
}, 10);
}
var OldOnload = window.onload;
if (typeof OldOnload === "function"){
window.onload = function() {
OldOnload();
init();
};
}else
window.onload = init; // для остальных браузеров
В PHP-скрипте, если нужно выполнить некоторый js-код после загрузки объектной модели DOM,, я по ходу генерации страницы добавляю js-код в переменную $DomLoad:
$DomLoad=(isset($DomLoad)&&$DomLoad ? $DomLoad : "").
"\n".Banner468x60() ; // вывод рекламного блок 468x60
В конце PHP-скрипта я добавил следующий код:
if(!empty($DomLoad))echo "\n<script type=\"text/javascript\">
var oldonload = document.funcDomReady;
document.funcDomReady=function() {
if(typeof oldonload == 'function')oldonload();
".str_replace("\r","",$DomLoad)."};
</script>
";
Если нужна загрузка кода javascript по DomReady в js-вставке, то я использую следующий код:
if(!document.funcDomReady)document.funcDomReady=function(){NewInit()};
else onDomReady(NewInit);
Если же нужна загрузка кода javascript по DomReady во множестве javascript-вставках, то я использую следующий код:
<script type="text/javascript">
var oldonload1 = document.funcDomReady;
document.funcDomReady=function() {
if(typeof oldonload1 == 'function')oldonload1();
LoadScript('http://api-maps.yandex.ru/2.0-stable/?load=package.standard&lang=ru-RU',function(){ymaps.ready(Y_Geocoder);});
};
if(document.location.hash){
var oldonload3 = document.funcDomReady;
document.funcDomReady=function() {
if(typeof oldonload3 == 'function')oldonload3();
hide('l0');layer_();
};
}
var oldonload2 = document.funcDomReady;
document.funcDomReady=function(){
if(typeof oldonload2 == 'function')oldonload2();hide('a0');
};
</script>
.
Прокомментировать/Отблагодарить