Я использую несколько плагинов, пользовательских виджетов и некоторые другие библиотеки из JQuery. в результате у меня есть несколько файлов .js и .css. Мне нужно создать загрузчик для моего сайта, потому что он загружается некоторое время. было бы хорошо, если бы я мог отобразить загрузчик перед импортом всех:
<script type="text/javascript" src="js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="js/myFunctions.js"></script>
<link type="text/css" href="css/main.css" rel="stylesheet" />
...
....
etc
Я нашел несколько руководств, которые позволяют мне асинхронно импортировать библиотеку JavaScript. например, я могу сделать что-то вроде:
(function () {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'js/jquery-ui-1.8.16.custom.min.js';
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
})();
по какой-то причине, когда я делаю то же самое для всех своих файлов, страницы не работают. Я так долго пытался найти причину проблемы, но никак не мог ее найти. Сначала я подумал, что это, вероятно, потому, что некоторые функции javascript зависят от других. но я загрузил их в правильном порядке, используя функцию тайм-аута, когда одно завершилось, я перешел к следующему, и страница по-прежнему ведет себя странно. например, я не могу нажимать ссылки и т. д ... анимация все равно работает ..
В любом случае
Вот о чем я подумал ... Я считаю, что в браузерах есть кеш, поэтому загрузка страницы в первый раз занимает много времени, а в следующий раз загрузка происходит быстро. поэтому я собираюсь заменить мою страницу index.html страницей, которая загружает все эти файлы асинхронно. когда ajax будет загружен, все эти файлы будут перенаправлены на страницу, которую я планирую использовать. при использовании этой страницы загрузка не займет много времени, поскольку файлы уже должны быть включены в кеш браузера. на моей индексной странице (страница, где файлы .js и .css загружаются асинхронно), я не забочусь об ошибках. Я просто покажу загрузчик и перенаправлю страницу, когда закончу ...
Это хорошая альтернатива? или я должен продолжать попытки реализовать асинхронные методы?
РЕДАКТИРОВАТЬ
способ загрузки всего асинхронного:
importScripts();
function importScripts()
{
//import: jquery-ui-1.8.16.custom.min.js
getContent("js/jquery-1.6.2.min.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
//s.async = true;
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext1,1);
});
//import: jquery-ui-1.8.16.custom.min.js
function insertNext1()
{
getContent("js/jquery-ui-1.8.16.custom.min.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext2,1);
});
}
//import: jquery-ui-1.8.16.custom.css
function insertNext2()
{
getContent("css/custom-theme/jquery-ui-1.8.16.custom.css",function (code) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel ="stylesheet";
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext3,1);
});
}
//import: main.css
function insertNext3()
{
getContent("css/main.css",function (code) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel ="stylesheet";
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext4,1);
});
}
//import: jquery.imgpreload.min.js
function insertNext4()
{
getContent("js/farinspace/jquery.imgpreload.min.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext5,1);
});
}
//import: marquee.js
function insertNext5()
{
getContent("js/marquee.js",function (code) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext6,1);
});
}
//import: marquee.css
function insertNext6()
{
getContent("css/marquee.css",function (code) {
var s = document.createElement('link');
s.type = 'text/css';
s.rel ="stylesheet";
s.innerHTML=code;
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
setTimeout(insertNext,1);
});
}
function insertNext()
{
setTimeout(pageReadyMan,10);
}
}
// get the content of url and pass that content to specified function
function getContent( url, callBackFunction )
{
// attempt to create the XMLHttpRequest and make the request
try
{
var asyncRequest; // variable to hold XMLHttpRequest object
asyncRequest = new XMLHttpRequest(); // create request object
// register event handler
asyncRequest.onreadystatechange = function(){
stateChange(asyncRequest, callBackFunction);
}
asyncRequest.open( 'GET', url, true ); // prepare the request
asyncRequest.send( null ); // send the request
} // end try
catch ( exception )
{
alert( 'Request failed.' );
} // end catch
} // end function getContent
// call function whith content when ready
function stateChange(asyncRequest, callBackFunction)
{
if ( asyncRequest.readyState == 4 && asyncRequest.status == 200 )
{
callBackFunction(asyncRequest.responseText);
} // end if
} // end function stateChange
и что странно, так это то, что весь стиль работает плюс все функции javascript. хотя страница почему-то зависла ...
источник
document.head.appendChild
, однако есть некоторые нишевые проблемы с добавлением скриптов в<head>
; ничего, что могло бы помешать загрузке и выполнению скриптов.document.write
до загрузки документа, скрипт будет выполняться синхронно как часть загрузки страницы и сам по себе не будет включать в себя какое-либо асинхронное поведение обратного вызова. Если вы создаете элемент сценария и добавляете его на страницу, у вас будет доступ для добавления прослушивателей событий для асинхронного запуска. tl; dr: это зависит от того, как вы загружаете скрипт с помощью JS.Новый атрибут HTML5 async должен помочь. 'defer' также поддерживается в большинстве браузеров, если вам небезразличен IE.
async - HTML
defer - HTML
При анализе нового кода рекламного блока AdSense я заметил атрибут, и поиск привел меня сюда: http://davidwalsh.name/html5-async
источник
async
илиdefer
он будет блокировать рендеринг во время загрузки. Настройкаasync
скажет ему не блокировать и запустить скрипт как можно скорее. Настройкаdefer
скажет ему не блокировать, а подождать с запуском скрипта, пока страница не будет готова. Обычно запускать скрипты как можно скорее не проблема, если у них нет никаких зависимостей (например, jQuery). Если один сценарий зависит от другого, используйте,onLoad
чтобы дождаться этого.Я загрузил скрипты асинхронно (эта функция есть в html 5), когда все скрипты, где они загрузились, я перенаправил страницу на index2.html, где index2.html использует те же библиотеки. Поскольку в браузерах есть кеш после перенаправления страницы на index2.html, index2.html загружается менее чем за секунду, потому что в нем есть все необходимое для загрузки страницы. На моей странице index.html я также загружаю изображения, которые планирую использовать, чтобы браузер поместил эти изображения в кеш. поэтому мой index.html выглядит так:
Еще одна приятная вещь в этом заключается в том, что я могу разместить загрузчик на странице, и когда страница будет загружена, загрузчик уйдет, и через несколько миллисекунд будет запущена новая страница.
источник
Пример из гугла
источник
Несколько примечаний:
s.async = true
не очень правильно для документа HTML5, правильноs.async = 'async'
(на самом деле использованиеtrue
правильно , спасибо amn, который указал на это в комментарии чуть ниже)Поскольку недавно появилась причина загружать файлы асинхронно, но по порядку, я бы порекомендовал немного более функциональный способ по сравнению с вашим примером (удалите
console.log
для производственного использования :)):источник
s.async = true
является правильным . Свойствоasync
явно указано как логическое в рекомендации W3C HTML 5 по адресу w3.org/TR/html5/scripting-1.html#attr-script-async . Вы путаетеasync
атрибут соasync
свойством, предоставляемым объектами, реализующимиHTMLScriptElement
интерфейс DOM. В самом деле, при манипулировании соответствующим атрибутом элемента с помощью чего-то вродеElement.setAttribute
этого следует использовать,element.setAttribute("async", "async")
поскольку все атрибуты HTML - это прежде всего текст.Благодаря HTML5 теперь вы можете объявить скрипты, которые хотите загружать асинхронно, добавив в тег «async»:
Примечание. Атрибут async предназначен только для внешних сценариев (и должен использоваться только при наличии атрибута src).
Примечание. Существует несколько способов выполнения внешнего сценария:
См. Это: http://www.w3schools.com/tags/att_script_async.asp
источник
Я бы завершил ответ zzzzBov проверкой наличия обратного вызова и разрешил передачу аргументов:
источник
Вот отличное современное решение для асинхронной загрузки скрипта, хотя оно обращается только к js-скрипту с async false .
На www.html5rocks.com есть отличная статья - Погрузитесь в мутные воды загрузки скриптов .
Рассмотрев множество возможных решений, автор пришел к выводу, что добавление js-скриптов в конец основного элемента - лучший способ избежать блокировки рендеринга страницы js-скриптами.
Тем временем автор добавил еще одно хорошее альтернативное решение для тех людей, которые отчаянно пытаются загружать и выполнять скрипты асинхронно.
Учитывая, что у вас есть четыре названных скрипта,
script1.js, script2.js, script3.js, script4.js
вы можете сделать это, применив async = false :Теперь Spec говорит : «Загрузите вместе, выполните по порядку, как только все загрузятся».
Firefox <3.6, Opera говорит: я понятия не имею, что это за «асинхронность», но так получилось, что я выполняю сценарии, добавленные через JS, в том порядке, в котором они добавляются.
Safari 5.0 говорит: я понимаю «async», но не понимаю, как устанавливать для него значение «false» с помощью JS. Я выполню ваши сценарии, как только они появятся, в любом порядке.
IE <10 говорит: « Нет представления об« асинхронности », но есть обходной путь с использованием« onreadystatechange ».
Все остальное говорит: я твой друг, мы сделаем это по книге.
Теперь полный код с обходным решением IE <10:
источник
Одна из причин, по которой ваши скрипты могут загружаться так медленно, заключается в том, что вы запускали все свои скрипты во время загрузки страницы, например:
вместо того:
Этот второй фрагмент сценария ожидает, пока браузер полностью загрузит весь ваш код Javascript, прежде чем он начнет выполнение любого из ваших сценариев, заставляя пользователя казаться, что страница загружается быстрее.
Если вы хотите улучшить взаимодействие с пользователем, уменьшив время загрузки, я бы не стал использовать вариант «экран загрузки». На мой взгляд, это раздражало бы гораздо больше, чем просто медленная загрузка страницы.
источник
Я предлагаю вам взглянуть на Modernizr . Это небольшая легкая библиотека, в которую вы можете асинхронно загружать свой javascript с функциями, которые позволяют вам проверять, загружен ли файл, и выполнять сценарий в другом указанном вами файле.
Вот пример загрузки jquery:
источник
Я написал небольшой пост, чтобы помочь с этим, вы можете прочитать больше здесь https://timber.io/snippets/asynchronously-load-a-script-in-the-browser-with-javascript/ , но я прикрепил вспомогательный класс ниже. Он будет автоматически ждать загрузки скрипта и, как только это произойдет, вернуть указанный атрибут окна.
Использование такое:
источник
Эта статья в вики может показаться вам интересной: http://ajaxpatterns.org/On-Demand_Javascript
В нем объясняется, как и когда использовать такую технику.
источник
Что ж,
x.parentNode
возвращает элемент HEAD, поэтому вы вставляете скрипт непосредственно перед тегом head. Может в этом проблема.Попробуйте
x.parentNode.appendChild()
вместо этого.источник
Посмотрите этот https://github.com/stephen-lazarionok/async-resource-loader . В нем есть пример, показывающий, как загрузить JS, CSS и несколько файлов одним выстрелом.
источник
Вы можете использовать LABJS или RequreJS
Загрузчики скриптов, как
LABJS
, например ,RequireJS
улучшат скорость и качество вашего кода.источник
Вы рассматривали возможность использования Fetch Injection? Я развернул библиотеку с открытым исходным кодом под названием fetch-inject для обработки подобных случаев. Вот как может выглядеть ваш загрузчик с использованием библиотеки:
Для обратной совместимости используйте функцию обнаружения и возврата к XHR Injection или Script DOM Elements, или просто вставьте теги в страницу, используя
document.write
.источник
Вот мое собственное решение для устранения JavaScript, блокирующего рендеринг:
Короче говоря, он загружает все ваши скрипты асинхронно, а затем выполняет их последовательно.
Репозиторий Github : https://github.com/mudroljub/js-async-loader
источник
No 'Access-Control-Allow-Origin' header is present on the requested resource
Вот небольшая функция ES6, если кто-то хочет использовать ее, например, в React
источник
Я бы посоветовал сначала изучить возможность минимизации файлов и посмотреть, даст ли это вам достаточно большой прирост скорости. Если ваш хост работает медленно, можно попробовать разместить этот статический контент в CDN.
источник