Каковы плюсы и минусы добавления элементов и использования JavaScript?

недавно я видел 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.

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

9 ответов


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

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

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

если ваши скрипты загружаются из отдельных файлов в атрибуте "src", то скрипты могут не выполняться последовательно во всех броузеры.

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

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

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

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

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

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

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

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

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

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

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

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

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

другой вопрос ремонтопригодности. Объединение и писать строки для добавления элементов в DOM на клиенте'side может стать кошмаром техническое обслуживание. Для семантического создания элементов лучше использовать методы DOM, такие как createElement.

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


. Это существенная часть системы управления зависимостями, которая обеспечивает "закрытие", и является огромным преимуществом при создании сложного, многофайльного, библиотечного приложения javascript-он позволяет предварительным условиям файла/кода определять порядок загрузки. В настоящее время мы используем этот метод и у меня не было с этим проблем. TBH, у нас не было ни одной проблемы с совместимостью браузера, и мы регулярно тестируем IE 6/7/8, FF3/2, Safari 4/5 и Chrome latest.

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

EDIT: Я сделал несколько комментариев к этой природе, но я подумал, что лучше подвести итог в моем ответе: Есть некоторые проблемы с додзе.require () и jQuery.getScript () (оба, которые в конечном итоге выполняют запрос ajax и eval).

  1. загрузка через ajax означает отсутствие перекрестных сценариев-т. е. нет загрузки javascript, который не с вашего сайта. Это будет проблемой, если вы хотите включить https://ajax.googleapis.com как указано в описании.
  2. eval'D скрипты не будут отображаться в списке сценариев страницы отладчика javascript, что делает отладку довольно сложной задачей. Последние выпуски firebug покажет вам eval'D код, однако имена файлов теряются, что делает акт установки точек останова утомительным. AFAIK, консоль javascript Webkit и IE8 инструменты разработчика не показать Эвальд скрипты.

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


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


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

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


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


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

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

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

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

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


  1. Если JavaScript отключен - <script> and <link> элементы не будут добавлены на всех.

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