2016-04-07 9 views
1

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

<script type="text/javascript"> 
    function importScript (sSrc, fOnload) { 
     var oScript = document.createElement("script"); 
     oScript.type = "text\/javascript"; 
     oScript.defer = true; 
     if (fOnload) { oScript.onload = fOnload; } 
     document.currentScript.parentNode.insertBefore(oScript, document.currentScript); 
     oScript.src = sSrc; 
    } 

    importScript(“//thirdpartysite.com/theirscript.js", function() { doStuff(); }); 
    }); 
</script> 

Это прекрасно работает, кроме как на Mac Firefox (я использую версию 45.0 0,1). В этом браузере страница не отображается, пока этот ресурс не был загружен. Кто-нибудь знает способ отложить загрузку ресурса, не блокируя рендеринг страницы, которая предпочтительно работает как на Chrome, так и на Firefox (все браузеры были бы хороши, но у меня нет времени проверить их все).

+1

не проверено, всего несколько идей: 'oScript.async = true;' then' document.body.appendChild (oScript); 'вместо добавления его в заголовок (скорее всего), и если это не сработает, вы можете попробуйте задержать выполнение кода внутри функции, до 'DOMContentLoaded'. – Thomas

+0

Я удаляю любую из вышеперечисленных строк, чтобы заменить то, что у вас здесь? – Dave

+0

Возможно, этот ответ поможет вам http://stackoverflow.com/questions/7718935/load-scripts-asynchronously –

ответ

1

Поскольку у вас уже есть система, которая принимает URL-адрес, а затем вызывает обратный вызов, вы можете легко вставить в него setTimeout. Что-то вроде

function importScript(sSrc, fOnload) { 
    setTimeout(function() { 
     var oScript = document.createElement("script"); 
     oScript.type = "text\/javascript"; 
     oScript.defer = true; 
     if (fOnload) { 
      oScript.onload = fOnload; 
     } 
     document.currentScript.parentNode.insertBefore(oScript, document.currentScript); 
     oScript.src = sSrc; 
    }, 100); 
} 

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

Однако при добавлении зависимостей система становится чрезвычайно сложной, код должен быть выполнен, только если компонент полностью загружен. Это заставляет меня поверить, что более свободный интерфейс (например, система Promise) может улучшить ваш дизайн, а также, возможно, просочиться тайм-аут и даже отложенное выполнение до тех пор, пока DOMReady не будет запущен во все задействованные элементы.

Вот пример без обещания подобного синтаксиса, но предполагая, что все сценарии сторонних и зависимые начинаются с одной точки только:

var loadingChainStarted = false; 
function importScript(sSrc, fOnload) { 
    if (document.readyState !== "complete") { 
     window.addEventListener("onload", function() { 
      importScript(sSrc, fOnload); 
     }, false); 
     return; 
    } 
    if (!loadingChainStarted) { 
     loadingChainStarted = true; 
     setTimeout(function() { 
      importScript(sSrc, fOnload); 
     }, 100); 
     return; 
    } 
    var oScript = document.createElement("script"); 
    oScript.type = "text\/javascript"; 
    oScript.defer = true; 
    if (fOnload) { 
     oScript.onload = fOnload; 
    } 
    document.currentScript.parentNode.insertBefore(oScript, document.currentScript); 
    oScript.src = sSrc; 
} 

Это будет только выполнить скрипт после DOMReady и, в первый раз , после задержки в 100 миллисекунд. Остальная часть цепочки будет выполняться нормально, так как оба DOMReady были уволены, а время задержки истекло.