У меня есть удаленный скрипт, на который ссылается в HEAD моей страницы HTML. Этот первый скрипт загружает и вставляет другой скрипт, добавляя его в DOM. Оба сценария существуют в другом домене, чем страница, на которой они встроены.Как сделать вставленную загрузку javascript перед DOMContentLoaded?
содержимое первого сценария выглядит следующим образом:
(function(){
var siteIdentifier = ...
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = '//blah.com/foo/' + siteIdentifier + '/second_script.js';
scriptTag.async = true;
document.getElementsByTagName('head')[0].appendChild(scriptTag);
})();
Когда я пытаюсь это в Chrome (версия 43.0.2357.81, 64-разрядная версия), я вижу, что первый сценарий загружается очень рано временной шкале. Но второй скрипт никогда не загружается сразу после события DOMContentLoaded.
На следующем скриншоте показана временная шкала загрузки/выполнения для двух сценариев. Первый скрипт - это верхний элемент, а второй - нижний. Игнорируйте элемент в середине, который является другим артефактом, который я не мог отфильтровать из временной шкалы для снимка экрана. Вертикальная синяя линия - это событие DOMContentLoaded.
Я попытался с и без асинхронной и отложить, но это, кажется, не имеют никакого эффекта. Есть ли способ заставить загрузку второго скрипта быть мгновенным, вместо того, чтобы ждать, пока произойдет событие DOMContentLoaded?
Update:
Я создал пример, чтобы показать проблему с помощью RawGit и GIST:
Открыть инструменты разработчика Chrome и смотрите на вкладке сети как страница загружается. Вы можете использовать ползунки на временной шкале, чтобы узко на определенный период времени и посмотреть, какие сценарии были загружены, когда. Возможно, вам придется обновиться несколько раз, чтобы убедиться, что shim.js был загружен задолго до события DOMContentLoaded, но вы заметите, что second.js никогда не загружается до DOMContentLoaded независимо от того, загружается ли shim.js и завершается выполнение.
Примечание: Я не мог использовать JSFiddle, потому что он не загружает все, что вы определяете, включая внешние скрипты, до тех пор, пока DOMContentLoaded.
Update 2:
Для некоторого фона: Мы строим 3-й продукт партии, который внедренный на сотни различных сайтов. Первый скрипт фактически является прокладкой, которая извлекает некоторую идентифицирующую информацию, а затем вызывает второй скрипт, используя идентифицирующую информацию как часть URL-адреса. Мы переводим всех, чтобы использовать второй скрипт напрямую, но пока все наши клиенты не перейдут к использованию второго скрипта напрямую, нам нужна прокладка, чтобы эффективно маршрутизировать их автоматически. И первый, и второй скрипты являются динамически генерируемыми (то есть серверными) сценариями, которые находятся за CDN.
Я полагаю, это потому, что вы не можете использовать 'document.getElementsByTagName' до тех пор, пока' document' не будет полностью доступен. – Blazemonger
Единственный способ действительно гарантировать, что это вместо 'document.write()' тег, но в целом это плохая идея, поскольку он заставляет браузер ждать 'document.write()', чтобы разрешить, что означает браузер должен дождаться загрузки сценария * и *. Alt alt должен помещать тег скрипта непосредственно на странице (как фактический тег скрипта, поэтому он блокируется) –
В этом случае, я думаю, 'document.write' может быть правильным решением. – Blazemonger