Какие плюсы и минусы: поместить javascript в голову и положить непосредственно перед закрытием тела

87

В большинстве книг / статей по javascript и веб-разработке говорится, что вы должны помещать CSS в тег заголовка и javascript внизу страницы.

Но когда я открываю html-код известных веб-сайтов, таких как этот stackoverflow, я обнаруживаю, что они помещают некоторые js-файлы в тег head.

В чем плюсы и минусы обоих подходов и когда какой?

Нашел еще один вопрос по той же проблеме: где я должен объявить файлы JavaScript, используемые на моей странице? В <head> </head> или рядом </body>?

Амр Элгархи
источник

Ответы:

63

Из рекомендаций Yahoo по ускорению работы вашего веб-сайта :

Проблема, вызванная скриптами, заключается в том, что они блокируют параллельные загрузки. Спецификация HTTP / 1.1 предполагает, что браузеры загружают не более двух компонентов параллельно на одно имя хоста. Если вы обслуживаете свои изображения с нескольких имен хостов, вы можете получить более двух загрузок параллельно. Однако во время загрузки сценария браузер не будет запускать другие загрузки, даже с другими именами хостов.

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

Часто возникает альтернативное предложение - использовать отложенные скрипты. Атрибут DEFER указывает, что сценарий не содержит document.write, и указывает браузерам, что они могут продолжить рендеринг. К сожалению, Firefox не поддерживает атрибут DEFER. В Internet Explorer выполнение сценария можно отложить, но не настолько, насколько хотелось бы. Если сценарий можно отложить, его также можно переместить в нижнюю часть страницы. Это ускорит загрузку ваших веб-страниц.

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

Дэвид Джонстон
источник
У меня есть пример, который перемещает квадрат на холсте, и он не будет работать, если я помещу javascript в заголовок HTML. Он должен быть внизу тела после объявления Canvas. Есть ли причина для этого или как мне сохранить весь свой Javascript в разделе <head> файла.
Дуг Хауф,
@DougHauf Не уверен, что я прав, но вы добавили слушателя DOMContentLoaded? Я спрашиваю, потому что, если у вас есть сценарий внизу, и он отлично отображается на холсте; это потому, что холст уже был загружен на экран до того, как вы попытались написать на нем. Теперь, если вы поместите сценарий в заголовок, он не будет рисовать на холсте, потому что холста еще нет. Поэтому, если вы добавите слушателя, он запустит ваш код холста ПОСЛЕ загрузки холста.
Мэтью Д Олд
1
Я не знаю, сколько лет документу, который вы цитируете, но похоже, что атрибут defer уже довольно давно поддерживается в Firefox .
user2428118
Спасибо, это мне очень
помогло
31

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

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

Если вы добавляете стили или элементы (и т. Д. Переключаете текстовые поля с помощью более обширного редактора), это будет видно пользователю как мерцающее.

Если вы добавляете события щелчка к элементам, они не будут доступны для щелчка, пока сами элементы не станут видимыми.

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

ИМХО (полностью против YSlow и множества умных людей), вы должны хранить свои скрипты в теге head и просто полагаться на их кеширование большую часть времени.

AHM
источник
9

Как правило, ссылки на скрипты следует размещать внизу страницы. Сценарии не только должны быть загружены, они также должны быть оценены и выполнены до того, как блок будет освобожден и страница продолжит процесс рендеринга. Такие вещи, как Modernizr, следует размещать наверху, потому что он обнаруживает некоторые функции, а также прокладки HTML5, которые вам, вероятно, понадобятся.

Еще одна причина, по которой вы хотите попытаться разместить скрипты внизу страницы, - это единичные точки отказа или SPOF. Здесь время ожидания вызова сценария или по какой-либо другой причине блокируется выполнение страницы. Это может часто случаться со сторонними рекламными библиотеками и т. Д.

Да, вам, возможно, придется немного подумать о том, как вы спроектируете свое приложение, но я обнаружил, что это очень быстро стало для меня очень естественным. За последние 4 года я создал сотни веб-приложений со скриптом внизу, и я могу заметить разницу. Я могу быть 500 мс, может быть 5000 мс, но все это имеет значение.

Крис Лав
источник
5

Это действительно зависит от вашего сайта. Если вы обращаетесь к функциям JavaScript и вызываете их внутри тела, тогда на них должна быть ссылка в заголовке, чтобы он был загружен. В противном случае, если вы собираетесь вызывать JavaScript только тогда, когда весь документ загружен, разумно разместить JavaScript в конце тела. Помещая файл .JS в конце, вы загружаете всю страницу, а затем получаете файл .JS. Таким образом, пользователь сможет быстро просмотреть страницу, и к тому времени, когда он / она ознакомится со страницей, файл .JS уже будет загружен.

азамшарп
источник
4

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

Draemon
источник
2
Не могли бы вы упомянуть, как jQuery решает эту проблему из интереса?
Мэтью Лок
jQuery имеет API для привязки обработчиков к событиям
Draemon