Каковы плюсы и минусы добавления элементов <script> и <link> с помощью JavaScript?

StackOverflow https://stackoverflow.com/questions/5302623

Вопрос

Недавно я видел HTML с одним <script> элемент в своем <head>...

<head>
    <title>Example</title>
    <script src="script.js" type="text/javascript"></script>
    <link href="plain.css" type="text/css" rel="stylesheet" />
</head>

Этот script.js затем добавляет любые другие необходимые <script> элементы и <link> элементы в документ с помощью document.write(...):(или он может использовать document.createElement(...) и т. д)

document.write("<link href=\"javascript-enabled.css\" type=\"text/css\" rel=\"styleshet\" />");
document.write("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js\" type=\"text/javascript\"></script>");
document.write("<script src=\"https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js\" type=\"text/javascript\"></script>");
document.write("<link href=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/trontastic/jquery-ui.css\" type=\"text/css\" rel=\"stylesheet\" />")
document.write("<script src=\"validation.js\" type=\"text/css\"></script>")

Обратите внимание, что существует plain.css CSS-файл в документе <head> и script.js просто добавляет все CSS и JavaScript, которые будут использоваться пользовательским агентом с поддержкой JS.

Каковы плюсы и минусы этой техники?

Это было полезно?

Решение

Блокирующий характер документа.

document.write сделает паузу всего, что браузер работает на странице (включая анализ). Настоятельно рекомендуется избегать Из -за этого блокирующего поведения. Браузер не может знать, что вы собираетесь перетасовать в текстовый поток HTML в этот момент, или будет ли запись полностью уничтожить все на дереве DOM, поэтому он должен остановиться, пока вы не закончите.

По сути, загрузка списаний таким образом заставит браузер прекратить анализ HTML. Если ваш сценарий встроен, то браузер также выполнит эти сценарии, прежде чем он будет продолжаться. Следовательно, в качестве боковой ноты всегда рекомендуется отложить сценарии нагрузку до тех пор, пока после Ваша страница проанализирована, и вы показали для пользователя разумный пользовательский интерфейс.

Если ваши сценарии загружаются из отдельных файлов в атрибуте «SRC», то сценарии могут не быть последовательно выполняться во всех браузерах.

Потеря оптимизации скорости браузера и предсказуемости

Таким образом, вы теряете много оптимизации производительности, сделанных современными браузерами. Кроме того, когда ваши скрипты могут быть непредсказуемыми.

Например, некоторые браузеры выполнят сценарии сразу после вас «написать» их. В таких случаях вы теряете параллельные загрузки сценариев (потому что браузер не видит второй тег сценария, пока не загрузится и не выполнит первое). Вы теряете параллельные загрузки сценариев, таблиц стилей и других ресурсов (многие браузеры могут загружать ресурсы, таблицы стилей и сценарии одновременно).

Некоторые браузеры откладывают сценарии до тех пор, пока после конца их выполняют.

Браузер не может продолжать анализировать HTML во время документа. document.write, поэтому ваша страница отображается намного медленнее.

Другими словами, ваш сайт стал таким же медленным, как и загрузка в многолетнего браузера без оптимизации.

Зачем кому -то это делать так?

Причина, по которой вы можете использовать что -то подобное, обычно для обслуживания. Например, у вас может быть огромный сайт с тысячами страниц, каждый из которых загружает один и тот же набор сценариев и таблиц стилей. Однако, когда вы добавляете файл скрипта, вы не хотите редактировать тысячи файлов HTML, чтобы добавить теги скрипта. Это особенно хлопотно при загрузке библиотек JavaScript (например, Dojo или jQuery) - вы должны изменить каждую HTML -страницу при обновлении до следующей версии.

Проблема в том, что у JavaScript нет оператора @include или @import, который вы можете включить другие файлы.

Некоторые решения

Решение об этом, вероятно, не путем инъекции сценариев через document.write, но по:

  1. Использование директив @Import на таблицах стилей
  2. Использование языка сценариев сервера (например, PHP) для управления вашей «главной страницей» и для создания всех других страниц (однако, если вы не можете использовать это и должны сохранить множество HTML -страниц по отдельности, это не решение)
  3. Избегать document.write, но загрузите файлы JavaScript через XHR, затем Eval () их - это могут иметь проблемы с безопасностью, хотя
  4. Используйте библиотеку JavaScript (например, Dojo) с функциями загрузки модуля, чтобы вы могли сохранить мастер-файл JS, который загружает другие файлы. Вы не сможете избежать необходимости обновлять номера версий файла библиотеки, хотя ...

Другие советы

Одним из основных недостатков является несовместимость браузера. Не все браузеры правильно приносят и включают ресурсы в DOM, поэтому рискованно использовать этот подход. Это больше верно для таблиц стилей, чем сценариев.

Другая проблема - это санитивность. Согласование и написание строк для добавления элементов DOM на клиенту может стать кошмаром для обслуживания. Лучше использовать методы DOM, такие как Createlement для семантически создания элементов.

Одно очевидное преимущество заключается в том, что это значительно облегчает использование ресурсов. Вы можете иметь логику, которая определяет, какие ресурсы загружать, тем самым уменьшая потребление полосы пропускания и общее время обработки для страницы. Я бы использовал библиотечный вызов, такой как jQuery $ .getScript () для загрузки сценариев против Document.Write. Преимущество заключается в том, что такой подход более чисто, а также позволяет выполнять код при выполнении запроса или сбоя.

Ну, я могу также бросить свою шляпу в кольцо на этом ...

Если вы изучите библиотеку закрытия Google, base.js, вы увидите, что документ. Writh используется в их writeScriptTag_() функция Это неотъемлемая часть системы управления зависимостями, которая предоставляет «закрытие» и является огромным преимуществом при создании сложного многопрофильного приложения JavaScript в библиотеке-оно позволяет предварительным условиям файла/кода определять порядок загрузки. В настоящее время мы используем эту технику, и нам было мало проблем с этим. TBH, у нас не было ни одной проблемы с совместимостью браузера, и мы регулярно тестируем на IE 6/7/8, FF3/2, Safari 4/5 и Chrome.

Единственный недостаток, который у нас был до сих пор, - это то, что может быть сложно отслеживать проблемы, вызванные дважды загрузкой ресурса, или не загружает его вообще. Поскольку акт загрузки ресурсов является программным, он подвержен программным ошибкам, и, в отличие от добавления тегов непосредственно в HTML, может быть трудно понять, каков точный заказ на загрузку. Тем не менее, эта проблема может быть в значительной степени преодолена с помощью библиотеки с какой -либо формой системы управления зависимостями, такой как закрытие или додзё.

РЕДАКТИРОВАТЬ: Я сделал несколько комментариев к этой природе, но я подумал, что лучше всего подытожить в своем ответе: есть некоторые проблемы с Dojo.require () и jQuery.getScript () (оба сразу же выполняют запрос Ajax и Eval).

  1. Загрузка с помощью AJAX не означает без сценариев - т.е. без загрузки JavaScript, который не с вашего сайта. Это будет проблемой, если вы хотите включить https://ajax.googleapis.com как указано в описании.
  2. Сценарии Eval'd не будут отображаться в списке сценариев страниц отладчика JavaScript, что делает отладку довольно сложной. Недавние выпуски Firebug покажут вам оценку кода, однако имена файлов теряются, делая акт установления точек останова утомительными. AFAIK, Webkit JavaScript Console и инструменты разработчика IE8 не надо Показать сценарии оценки.

У него есть преимущество, что вам не нужно повторять ссылки на скрипт в каждом файле HTML. Недостатком является то, что браузер должен Получите и выполните основной файл JavaScript, прежде чем он может загрузить другие.

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

В Google PageSpeed ​​настоятельно не рекомендуют использовать этот метод, поскольку он замедляет работу.Помимо последовательной загрузки вашего скрипт.js раньше всех остальных, есть еще одна загвоздка:

Современные браузеры используют спекулятивные парсеры для более эффективного обнаружения внешних ресурсов [...] Таким образом, использование JavaScript document.write() для извлечения внешних ресурсов делает невозможным обнаружение этих ресурсов спекулятивным парсером, что может задержать загрузку, анализ и рендеринг этих ресурсов.

Также возможно, что это было написано как рекомендация SEO-фирмы, чтобы сделать элемент головы короче, если это возможно, поэтому уникальный контент ближе к верхней части документа, а также создает более высокое соотношение текста к HTML. Хотя это звучит, все в общем, как не очень хороший способ сделать это; Несмотря на то, что это сделало бы техническое обслуживание более трудоемким, лучшим подходом, вероятно, заключался бы в том, чтобы превратить JavaScript в один файл .JS и CSS в один файл .CSS, если бы он был признан совершенно необходимым для уменьшения размера элемента головы.

Большой недостаток в том, что добавление scriptS в голову приостановит обработку документа, пока эти сценарии не будут полностью загружены и выполнены (потому что браузер думает, что они могут использовать document.write) - Это повредит отзывчивости.

Теперь дни рекомендуются поставить свои теги сценария, чтобы </body>. Анкет Конечно, это невозможно 100% раз, но если вы используете Неизвестный JavaScript (Как и вы должны), все сценарии могут быть искажены в конце документа.

HTML5 придумал async Атрибут, который предполагает браузер только для выполнения сценариев после загрузки основного документа. Это поведение сценариев сценариев во многих браузерах, но не все они.

я советую против с использованием document.write любой ценой. Даже без него это приводит к одному дополнительному запросу на сервер. (Нам нравится внедрить количество запросов, например, с Спрайты CSS.)

И да, как упоминалось другие ранее, если сценарии отключены, ваша страница будет показана без CSS (что делает его потенциально непригодным).

  1. Если JavaScript есть инвалид - <script> and <link> Элементы не будут добавлены вообще.

  2. Если вы разместите функции init javaScript внизу своей страницы (которая является хорошей практикой) и связывает CSS с JavaScript, это может привести к некоторой задержке до загрузки CSS (разбитая макет будет видна в течение короткого времени).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top