Ленивая загрузка JavaScript и встроенного JavaScript
Я заметил в <head>
моего сайта (для работы), есть много тегов <link rel="stylesheet" type="text/css" href="" />
и <script type="text/javascript" src="">
. Есть еще больше файлов JavaScript/CSS, которые загружаются только для определенных страниц (мы используем CodeIgniter, и пути к файлам передаются в представление заголовка).
Я рассматривал использование условного/асинхронного загрузчика (например, yepnope.js, head.js и т.д.), но я заметил небольшую проблему с этим.
В наших представлениях есть встроенный JavaScript, некоторые используют $(function(){})
some uses $(document).ready(function(){})
, а некоторые просто имеют код (используя jQuery), который не находится в блоке ready
.
Без редактирования КАЖДОГО файла просмотра, чтобы обернуть свой код в функцию и вызвать это при загрузке JS файлов, существует ли способ отсрочить встроенный код до тех пор, пока JavaScript не будет загружен асинхронно?
Ответы
Ответ 1
Вы можете на самом деле lazyload встроенный javascript:
1- Измените параметр типа inline script на: text/delayscript
С
<!– Inline Script –>
<script type="text/javascript" language="javaScript">
/* Code */
</script>
Для
<!– Inline Script –>
<script type="text/delayscript">
/* Code */
</script>
Придавая тегу script пользовательский текст/записок Mime-типа заставляет браузер игнорировать его содержимое (обратите внимание, что его полное исключение будет по умолчанию равно text/javascript).
2 - ленивая загрузка всех встроенных скриптов
После того, как heads.js(или другая структура, которую вы могли бы использовать), подтверждает, что она ленила загружать все ваши внешние JS, затем вы можете захватить содержимое всех ваших пользовательских тегов script и ввести их на страницу:
<script>
head.ready(function() {
var
_head = document.getElementsByTagName("head")[0],
_script = document.createElement('script'),
_scripts = document.getElementsByTagName("script"),
_txt = "text/delayscript",
_contents = []
;
for(var i=0,l=_scripts.length;i<l;i++){
var _type = _scripts[i].getAttribute("type");
if(_type && _type.toLowerCase() ==_txt)
_contents.push(_scripts[i].innerHTML)
}
_script.type = 'text/javascript';
_script.innerHTML = _contents.join(" ");
_head.appendChild(_script);
});
Чтобы быть еще более изящным, вы можете сохранить встроенные скрипты в своей исходной иерархии в дереве DOM вместо того, чтобы помешать всему их контенту в одном script, как я предложил выше, заменив отмеченный inline script тег новым, который имеет тип mime type/javascript:
head.ready(function() {
var
_scripts = document.getElementsByTagName("script"),
_doc = document,
_txt = "text/delayscript"
;
for(var i=0,l=_scripts.length;i<l;i++){
var _type = _scripts[i].getAttribute("type");
if(_type && _type.toLowerCase() ==_txt)
_scripts[i].parentNode.replaceChild((function(sB){
var _s = _doc.createElement('script');
_s.type = 'text/javascript';
_s.innerHTML = sB.innerHTML;
return _s;
})(_scripts[i]), _scripts[i]);
}
});
Ответ 2
Вам нужно подумать о перемещении встроенного кода "снаружи" и включить его с помощью
<script defer="defer" type="text/javascript" src="">
Ответ 3
Прежде всего, я бы рекомендовал вам очень внимательно проанализировать загрузку скриптов на стороне клиента, а не только для первой загрузки JavaScript, но при загрузке одних и тех же файлов JavaScript во второй раз или при загрузке на другой стр. Если ETag правильно установлен в сценариях веб-сервером или используются другие параметры кеширования HTTP (подробнее см. руководство по кешированию) для файлов JavaScripts, не будет никакой загрузки самих файлов, и будет произведено только повторное повторение кэша. Таким образом, может быть, что проблема, которую вы описываете, не так важна, как выглядит.
Если вы решите загрузить некоторые сценарии динамически, вы можете использовать jQuery.getScript и поместить все зависимые коды внутри обратного вызова success
, Если вам нужно загрузить один или два файла JavaScript, это будет работать очень хорошо, но если вам нужно загрузить список файлов JavaScript с более сложной зависимостью, реализация может быть не такой простой. В случае, если вы можете использовать document.writeln
внутри <head>
. Использование метода внутри <head>
практически не имеет недостатков (подробнее см. здесь).
Ответ 4
В зависимости от вашей настройки вы можете ознакомиться с сервисом от www.cloudflare.com. Их текущая бета-функциональность, называемая ракетным загрузчиком, делает именно это, включая встроенные скрипты.
Это бесплатный сервис. попробуйте его;)
Кроме того, вы получаете бесплатный прокси-сервер кеширования сверху:)
Ответ 5
В HTML5 был добавлен новый параметр async
для скриптов, имеющих определенный src
.
Вы можете добавить его непосредственно в любой элемент <script>
:
<script src='/js/script.js' async></script>
НО: имейте в виду, что он не будет работать на встроенных скриптах!
И если ваши некоторые из ваших страниц смешивают внешние и встроенные скрипты, если вы загружаете внешний асинхронно, это означает, что встроенные скрипты будут фактически выполняться до асинхронными... Что может имеют нежелательные эффекты.
Установите этот логический атрибут, чтобы указать, что браузер должен, если возможно, асинхронно выполнять script. Он не влияет на встроенные скрипты (например, скрипты, которые не имеют атрибута src).
Например, если у вас есть следующая конфигурация:
<script src='/js/jquery.min.js' async></script>
<script>
// --> jQuery won't be loaded when this script will be executed!
// This will throw an error.
$(function () {
$('#element').doSomething();
});
</script>
Ответ 6
Посмотрите на использование headjs. Это хорошая легкая библиотека, которая сделает все это за вас.
Ответ 7
Вместо встроенных скриптов создайте встроенные функции. Затем в конце вашего файла javascript вызовите функцию, если она существует.
function inline_script() {.. code ..}
Внутри вашего объединенного jquery + etc асинхронного javascript файла:
if (typeof(inline_script) == 'function') inline_script()
Вам нужно будет немного перетасовать, чтобы убедиться, что у вас есть только один inline_script на странице, или используйте какое-то кэширование, чтобы соединить их, если вы вызываете его более одного раза.
Это все еще интересная проблема в текущем возрасте, хотя этот вопрос старый, асинхронные скрипты = довольно удивительные