AAA Главная
Примеры PHP Примеры JavaScript Примеры Ajax Примеры CSS,HTML

Паралельная загрузка скрипта 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>

.

© Copyright 2008-2016 by KDG