Я хотел бы знать, когда мне следует включать внешние скрипты или писать их в HTML-коде с точки зрения производительности и простоты обслуживания.
Какая для этого общая практика?
Реальный сценарий - у меня есть несколько HTML-страниц, которым требуется проверка формы на стороне клиента. Для этого я использую плагин jQuery, который я включаю на все эти страницы. Но вопрос в том, могу ли я:
Спасибо.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


На момент публикации этого ответа (2008 г.) правило было простым: все сценарии должны быть внешними. И для обслуживания, и для производительности.
(Почему производительность? Потому что, если код отдельный, его легче кэшировать в браузерах.)
JavaScript не входит в HTML-код, и если он содержит специальные символы (например, <, >), это даже создает проблемы.
В настоящее время веб-масштабируемость изменилась. Уменьшение количества запросов стало допустимым соображением из-за задержки выполнения нескольких HTTP-запросов. Это усложняет ответ: в большинстве случаев рекомендуется использовать внешний JavaScript по-прежнему. Но в некоторых случаях, особенно в очень маленьких фрагментах кода, встраивание их в HTML-код сайта имеет смысл.
@zach: размещение тега сценария в вашем HTML - это навязчивый JS нет. @konrad: вы можете легко преодолеть проблемы <>, заключив свой код в раздел CDATA.
@Nick: большинство проблем можно преодолеть. Однако лучше вообще не создавать их.
@nickf В HTML нет такой вещи, как CDATA, и никто никогда не обслуживает свои страницы как XHTML, даже если они пишут XHTML в DOCTYPE, потому что, если бы они это сделали, их страницы не загрузились бы в IE.
@Daniel Я действительно сделал это для одного веб-сайта, только не поддерживающие браузеры (= MSIE) получили тип документа HTML. Тем не менее, некоторое время назад в поддержке Firefox CDATA были серьезные ошибки (не знаю, изменилось ли это).
Иногда вы получаете лучшую производительность при встраивании. Посмотрите на источник google.com. Они знают, что делают.
@callum Google использует другой вариант использования, нежели 99,999999% веб-сайтов. Конечно, они тщательно измеряют очень сильно, и даже самая маленькая разница имеет значение. Но только потому, что они обнаружили, что в их конкретном сценарии использования встраивание работает лучше (возможно, потому, что сценарий меняется очень часто?), Не означает, что мы можем вывести из этого общее правило или даже что мы должны игнорировать «обычные» правило (для экстернализации скриптов).
@KonradRudolph - Согласен, из подхода Google не следует выводить никаких общих правил. Я просто говорю, что это намек на то, что, возможно, стоит подвергнуть сомнению правило в вашем ответе. В любом случае, я думаю, что причина, по которой Google делает это, состоит в том, чтобы уменьшить количество HTTP-запросов, и это может принести пользу более чем 0,000001% сайтов. Пропускная способность растет, но время приема-передачи остается прежним. Удаление всего последовательного HTTP-запроса иногда лучше, чем кеширование внешнего JS. Конечно, зависит от размера вашего JS.
@callum Хотя это правда, вопрос о кешировании все еще остается и остается важным. Уменьшение количества обращений важно только в том случае, если ваши посетители не возвращаются (и тогда вы не получите достаточного количества обращений к странице, чтобы это было важно) или если ваш контент меняется так часто, что кеширование файлов сценариев не приносит никакой пользы.
тогда как вы собираетесь иметь материалы для конкретной страницы?
@Parhs Загружает скрипты, специфичные для страницы. Или, если это очень маленькая конфигурация, просто сделайте ее встроенной.
-1 это наивное утверждение, конечно, бывают случаи, когда производительность выше встроенного по сравнению с HTTP-запросом (даже кешированным).
@Chris ... это обсуждалось до смерти в комментариях выше.
@Konrad Rudolph: Google делает противоположное тому, что рекомендует вам, посмотрите на их веб-сайты. Это Google, разберись с этим!
@machineaddict Точно: это Google. Вы не гугл. Их рекомендации не для вас. Кроме того, я предлагаю вам прочитать существующие комментарии, прежде чем комментировать себя в следующий раз.
Разве документ не кэшируется так же легко, как файл javascript? Если бы у вас было большое количество страниц, каждую из них нужно было бы кэшировать, но если бы у вас была только одна страница, вставка ее в строку сохраняет запрос. Вероятно, есть момент, когда количество страниц и размер скрипта делают сохранение запроса менее выгодным, чем кеширование файла js.
@Dave Если страница не меняется. Вся суть в том, чтобы иметь отдельные файлы, чтобы иметь возможность кэшировать одни файлы при изменении других.
Не согласен. Небольшой скрипт может и должен быть встроен в производительность. Больше внешних файлов, больше звонков.
@Vladd Что вы имеете в виду, говоря «больше звонков»? Больше HTTP-запросов / циклов приема-передачи? Конечно. А для веб-сайтов с высоким трафиком (Google, Stack Overflow и т. д.) Это очень важный показатель. Для 99,999% веб-сайтов в Интернете это совершенно неактуально.
@Konrad, я полностью не согласен. Проблема не в "количестве" HTTP-вызовов, а в задержке каждого вызова. По крайней мере, согласно моему опыту, единственное, что действительно чувствует конечный пользователь в конце, - это поездки туда и обратно. Если все ваши клиенты не живут по соседству с центром обработки данных, где хранятся ваши js-файлы, или вы не разрабатываете приложение для интрасети, для 99,999% веб-сайта это время очень актуально. то, что обычно не имеет значения, - это еще 1–300 КБ данных, которые вам нужно будет передать по сети, которые можно было бы кэшировать, если бы js были разделены
@ user2033402 Если ваши конечные пользователи ощущают задержку при загрузке внешнего JavaScript, вероятно, в конфигурации вашего сервера есть ошибка (возможно, что-то, что препятствует одновременной загрузке). Этого не должно (и обычно не бывает).
может быть, или я просто уезжаю в Израиль, главный сервер находится в США, а наши клиенты разбросаны по всем уголкам земного шара. Конечно, мы могли бы инвестировать деньги в репликацию нашего веб-сайта во многих местах, но мы любим деньги и предпочитаем оставлять их себе. да, мы могли бы поместить наш скрипт в CDN и не забыть обновлять их, мы могли бы делать много вещей, которые требуют денег и времени. Или мы могли бы просто использовать встроенные скрипты, хотя у нас нет реальной причины этого не делать. «не должно происходить» в общем случае - забавное слово. Я хотел бы сослаться на ответ Глено, похоже, он пришел к такому же выводу
@YuvalPerelman Если js является внешним и кешированным, задержка для кешированных битов составляет ~ 0, кроме первого посещения. С HTTP / 2 многие из предыдущих передовых практик также больше не применяются, поэтому следует также учитывать, какой протокол используется.
@KonradRudolph Мне интересно, что вы сказали в своем ответе о преимуществах внешнего обслуживания. Вы можете уточнить?
@jinglesthula, почему вы решили игнорировать первое посещение, которое во многих случаях было бы единственным? первое посещение важно, иногда самое важное. Что касается обслуживания, гораздо проще поддерживать сценарий, который сохраняется в отдельном файле, это дает вам разделение проблем. Файлы HTML (или php, cshtml и т. д.) Имеют тенденцию быть большими и трудными для навигации, если у вас есть скрипты внутри, они могут быть ужасными. Когда вам нужно что-то изменить, это сложно найти, и единственный способ обновить это - обновить все вместе. До определенной степени детализация очень удобна.
@YuvalPerelman Согласен - первый визит очень важен. Я просто указываю на то, что при последующих посещениях кешированные ресурсы больше не извлекаются, что стоит учитывать. Безусловно, вам нужно учитывать поведение ваших пользователей. Если 90% ваших посетителей запрашивают страницу только один раз, это сильно отличается от того, если 90% посещают страницу 2+ раза.
re: преимущество обслуживания, я перечитал и увидел, что это относится к 2008 году (до модулей babel / es6 / реакции и т. д., и когда файлы HTML действительно обычно содержали большие объемы кода). Теперь мы можем разместить весь код для решения проблем - поведения (js), разметки и стилей - в очень маленьких файлах компонентов (определенно легче поддерживать, чем при распределении по разным файлам в разных каталогах, а также для js / css, часто смешанных с код для несопоставимых проблем), так что мысль о том, пытаясь даже внедренной JS в HTML-файле становится спорным вопросом. "js в моем файле .html? Нет! Поместите его с разметкой!" : D
В вашем сценарии это звучит так, как будто запись внешнего материала в один файл, совместно используемый страницами, будет вам полезна. Я согласен со всем сказанным выше.
Во время раннего прототипирования держите свой код встроенным, чтобы ускорить итерацию, но обязательно сделайте его внешним к тому моменту, когда вы достигнете производства.
Я бы даже осмелился сказать, что если вы не можете разместить весь свой Javascript извне, значит, у вас в руках плохой дизайн, и вам следует реорганизовать свои данные и скрипты.
Ремонтопригодность, безусловно, является причиной для сохранения их внешними, но если конфигурация однострочная (или, в общем, короче, чем накладные расходы HTTP, которые вы получили бы для того, чтобы сделать эти файлы внешними), с точки зрения производительности лучше сохранить их встроенными. Всегда помните, что каждый HTTP-запрос создает некоторые накладные расходы с точки зрения времени выполнения и трафика.
Естественно, все это становится неактуальным в тот момент, когда ваш код длиннее пары строк и не привязан к одной странице. В тот момент, когда вы захотите повторно использовать этот код, сделайте его внешним. Если нет, посмотрите на его размер и решите.
Это одна из моих проблем. Отдельный HTTP-запрос для нескольких строк кода кажется расточительным.
Не могли бы вы опубликовать образец конфигурации для своего кода? ИМО, если он меньше 300 символов и абсолютно привязан к странице, встроите его.
Это должен быть главный ответ имо
@Dan имейте в виду, что отдельный запрос выполняется только в первый раз. Если вы ожидаете, что ваши пользователи будут загружать страницу более одного раза, внешнее кэширование (даже для нескольких строк) явно быстрее, чем ожидание байтов для этих нескольких строк по сети при загрузке страницы n = 2 +.
@HorstGutmann, как внешняя помощь файла связана с ремонтопригодностью? Я лично предпочитаю внешние js, когда это возможно, но есть ли что-то объективное, что упрощает поддержку?
@jinglesthula одним из примеров может быть, если вы хотите использовать один и тот же код (или что-то очень похожее) на нескольких страницах. Наличие одного и того же кода в нескольких местах затрудняет ремонтопригодность. Конечно, есть способы обойти это, но давайте просто возьмем самую наивную реализацию здесь. Также гораздо проще статически анализировать код, когда он находится в выделенных файлах (eslint et al.).
Экстернализация javascript - одно из правил производительности Yahoo: http://developer.yahoo.com/performance/rules.html#external
Хотя жесткое правило, что вы всегда должны экстернализировать скрипты, обычно будет хорошей ставкой, в некоторых случаях вы можете захотеть встроить некоторые скрипты и стили. Однако вам следует встраивать только те вещи, которые, как вы знаете, улучшат производительность (потому что вы это измерили).
Я думаю, Yahoo также рекомендует добавить весь Javascript в один HTTP-вызов - это не означает, что все сценарии должны находиться в одном файле во время разработки, хотя
Кроме того, как отмечалось выше, HTTP / 2 также меняет практику «1 звонок».
Я бы посмотрел на требуемый код и разделил его на столько отдельных файлов, сколько нужно. Каждый файл js будет содержать только один «логический набор» функций и т. д., Например. один файл для всех функций, связанных с входом в систему.
Затем при разработке сайта на каждой странице html вы включаете только те, которые необходимы. Когда вы запускаете свой сайт, вы можете оптимизировать его, объединив каждый файл js, который нужен странице, в один файл.
Три соображения:
я думаю, что специфично для одной страницы, короткий сценарий сценария - (единственный) оправданный случай для встроенного скрипта
Внешние скрипты также легче отлаживать с помощью Firebug. Мне нравится проводить модульное тестирование моего JavaScript и иметь все внешние подсказки. Я ненавижу видеть JavaScript в коде PHP и HTML, мне это кажется большим беспорядком.
Что касается сохранения внешнего кода JavaScript:
ASP.NET 3.5SP1 недавно представил функциональность для создания ресурса Composite script (слияние нескольких файлов js в один). Еще одно преимущество этого заключается в том, что когда включено сжатие веб-сервера, загрузка одного файла немного большего размера будет иметь лучший коэффициент сжатия, чем многие файлы меньшего размера (также меньше накладных расходов HTTP, двустороннего трафика и т. Я предполагаю, что это экономит на начальной загрузке страницы, а затем запускается кеширование браузера, как упоминалось выше.
Помимо ASP.NET, этот скринкаст более подробно объясняет преимущества: http://www.asp.net/learn/3.5-SP1/video-296.aspx
Еще одно скрытое преимущество внешних сценариев заключается в том, что вы можете легко запускать их с помощью средства проверки синтаксиса, такого как jslint. Это может спасти вас от множества душераздирающих, труднообнаруживаемых ошибок IE6.
На самом деле, есть довольно веские основания для использования встроенного javascript. Если js достаточно мал (однострочный), я предпочитаю встроенный javascript из-за двух факторов:
jQuery, вы можете использовать методы live или delegate, чтобы обойти это, но я считаю, что если js достаточно мал, предпочтительнее просто поместить его в строку.Единственная защита, которую я могу предложить для встроенного javascript, заключается в том, что при использовании строго типизированных представлений с .net MVC вы можете ссылаться на переменные C# в середине javascript, которые я считаю полезными.
Еще одна причина, по которой вы всегда должны использовать внешние скрипты, - это облегчить переход на Политика безопасности контента (CSP). По умолчанию CSP запрещает использование всех встроенных скриптов, что делает ваш сайт более устойчивым к XSS-атакам.
404. Думаю, они передумали.
Если вы заботитесь только о производительности, большинство советов в этом потоке совершенно неверны и становятся все более и более неправильными в эпоху SPA, когда мы можем предположить, что страница бесполезна без JS-кода. Я потратил бесчисленные часы на оптимизацию времени загрузки страницы SPA и проверку этих результатов в разных браузерах. Повсеместно повышение производительности за счет повторной оркестровки вашего html может быть весьма значительным.
Чтобы добиться максимальной производительности, вы должны думать о страницах как о двухступенчатых ракетах. Эти две стадии примерно соответствуют фазам <head> и <body>, но воспринимайте их как <static> и <dynamic>. Статическая часть - это в основном строковая константа, которую вы вставляете в канал ответа так быстро, как только можете. Это может быть немного сложно, если вы используете много промежуточного программного обеспечения, которое устанавливает файлы cookie (они должны быть установлены перед отправкой содержимого http), но в принципе он просто очищает буфер ответа, надеюсь, перед тем, как перейти к некоторому шаблонному коду (razor, php, и т. д.) на сервере. Это может показаться трудным, но тогда я просто объясняю это неправильно, потому что это почти тривиально. Как вы уже догадались, эта статическая часть должна содержать весь встроенный и минифицированный javascript. Это выглядело бы примерно так
<!DOCTYPE html>
<html>
<head>
<script>/*...inlined jquery, angular, your code*/</script>
<style>/* ditto css */</style>
</head>
<body>
<!-- inline all your templates, if applicable -->
<script type='template-mime' id='1'></script>
<script type='template-mime' id='2'></script>
<script type='template-mime' id='3'></script>
Поскольку отправка этой части по сети почти ничего не стоит, вы можете ожидать, что клиент начнет получать ее где-то около 5 мс + задержка после подключения к вашему серверу. Предполагая, что сервер достаточно близко, эта задержка может составлять от 20 мс до 60 мс. Браузеры начнут обрабатывать этот раздел, как только они его получат, и время обработки обычно будет преобладать над временем передачи в 20 или более раз, что теперь является вашим амортизированным окном для обработки части <dynamic> на стороне сервера.
Браузеру требуется около 50 мсек (хром, отдых может быть на 20% медленнее), чтобы обработать встроенный jquery + signalr + angular + ng animate + ng touch + ng routes + lodash. Это довольно удивительно само по себе. В большинстве веб-приложений меньше кода, чем во всех этих популярных библиотеках вместе взятых, но предположим, что у вас столько же, поэтому мы выиграем задержку + 100 мс обработки на клиенте (эта задержка достигается за счет второго фрагмента передачи). К моменту поступления второго чанка мы обработали весь js-код и шаблоны и можем приступить к выполнению преобразований dom.
Вы можете возразить, что этот метод ортогонален концепции встраивания, но это не так. Если вы вместо встраивания ссылаетесь на cdns или свои собственные серверы, браузеру придется открыть другое соединение (я) и отложить выполнение. Поскольку это выполнение в основном бесплатное (поскольку серверная сторона общается с базой данных), должно быть ясно, что все эти переходы будут стоить больше, чем полное отсутствие переходов. Если бы была причуда браузера, которая говорила, что внешний js выполняется быстрее, мы могли бы измерить, какой фактор преобладает. Мои измерения показывают, что лишние запросы убивают производительность на этом этапе.
Я много работаю над оптимизацией SPA-приложений. Люди часто думают, что объем данных имеет большое значение, в то время как на самом деле задержка и выполнение часто преобладают. Минифицированные библиотеки, которые я перечислил, добавляют до 300 КБ данных, и это всего лишь 68 КБ в сжатом виде, или загрузка 200 мс на 2-мегабитный телефон 3g / 4g, что является именно той задержкой, которую потребовалось бы на том же телефоне, чтобы проверить, были ли у него те же данные. в своем кэше уже, даже если он был кэширован прокси, потому что налог на задержку мобильной связи (задержка между телефоном и вышкой) все еще применяется. Между тем, подключения к настольным компьютерам с более низкой задержкой первого прыжка в любом случае обычно имеют более высокую пропускную способность.
Короче говоря, прямо сейчас (2014 год) лучше всего встроить все скрипты, стили и шаблоны.
ИЗМЕНИТЬ (МАЙ 2016)
Поскольку JS-приложения продолжают расти, и некоторые из моих полезных нагрузок теперь складываются до 3+ мегабайт минифицированного кода, становится очевидным, что по крайней мере общие библиотеки больше не должны быть встроены.
Я не получил часть которое теперь является вашим амортизированным окном для серверной обработки части <dynamic> - сервер обрабатывает все, что ему нужно, и только затем обслуживает весь визуализированный html (голова + тело), какая еще обработка сервера потребуется после этого?
@BornToCode Идея состоит в том, чтобы дать клиенту что-то делать, в то время как серверная сторона чем-то занимается. Поскольку клиентские библиотеки необходимо интерпретировать, лучше запустить этот процесс до выполнения вычисления Любые на сервере. Амортизированное окно - это время, необходимое клиенту для обработки JS. Вы получите это окно бесплатно, если будете дирижировать двухступенчатой ракетой.
Google включил время загрузки в свои измерения рейтинга страниц, если вы много встраиваете, паукам потребуется больше времени, чтобы сканировать вашу страницу, это может повлиять на рейтинг вашей страницы, если вам нужно много включить. в любом случае разные стратегии могут повлиять на ваш рейтинг.
Google позволяет скриптам загружаться перед индексацией.
хорошо, я думаю, что вы должны использовать inline при создании одностраничных веб-сайтов, поскольку скрипты не нужно будет совместно использовать на нескольких страницах
Всегда старайтесь использовать внешние JS, поскольку встроенные JS всегда сложно поддерживать.
Более того, профессионально требуется, чтобы вы использовали внешний js, поскольку большинство разработчиков рекомендуют использовать js извне.
Сам использую внешние js.
Профессионально требуется? Почему? Кто так говорит?
Наличие внутренних плюсов JS: Легче управлять и отлаживать Вы можете видеть, что происходит
Внутренние минусы JS: Люди могут все изменить, и это действительно может вас раздражать.
внешние преимущества JS: не менять Вы можете выглядеть более профессионально (по крайней мере, я так думаю)
минусы внешнего JS: труднее управлять трудно понять, что происходит.
Согласовано. И я добавлю, что вы можете поместить тег включения <script> В КОНЕЦ html-кода, поскольку Yahoo рекомендует его также из соображений производительности (developer.yahoo.com/performance/rules.html#postload)