Почему бы не вставлять стили / сценарии в HTML вместо ссылок?


41

Мы объединяем файлы CSS и JavaScript, чтобы уменьшить количество HTTP-запросов, что повышает производительность. В результате HTML выглядит так:

<link rel="stylesheet" href="all-my-css-0fn392nf.min.css">
<!-- later... -->
<script src="all-my-js-0fn392nf.min.js"></script>

Если у нас есть логика на стороне сервера / сборки, чтобы сделать все это для нас, почему бы не сделать еще один шаг вперед и не внедрить эти сцепленные стили и сценарии в HTML?

<style>.all{width:100%;}.my{display:none;}.css{color:white;}</style>
<!-- later... -->
<script>var all, my, js;</script>

Это на два меньше HTTP-запросов, но я не видел эту технику на практике. Почему бы нет?


12
Я виню кеширование.

Ответы:


98

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

Например, HTML-код этой страницы сейчас составляет 13 КБ. 180 КБ CSS попали в кеш, как и 360 КБ JS. Оба попадания в кэш занимали незначительное количество времени и практически не потребляли пропускную способность. Извлеките сетевой профилировщик вашего браузера и попробуйте его на некоторых других сайтах.


1
Если вы делаете одностраничный сайт в стиле приложения, тогда где подавляющее большинство кода относится только к одной странице, тогда это все еще может иметь какой-то смысл?
JohnB

3
Джон: если страница посещена только один раз, да. При многократном посещении все встроенные данные передаются несколько раз, а не только один раз, и кэшируются.
Конерак

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

2
@maple_shaft Пожалуйста, опишите подробно, почему вы не можете минимизировать ресурсы как обычно, а затем включить их?

1
@JohnB не забывайте эффекты CDN или локального кэширования на провайдере. Мой запрос на javascript для google, вероятно, никогда не дойдет до google, даже если у меня локально отсутствует кеш, потому что другой человек, который использует тот же isp, уже заставил isp кешировать данные.

19

Просто потому, что веб-производительность действительно имеет значение! 99% раз это даст вам быстрое время отклика конечного пользователя.

Вот несколько примеров из Velocity Conf.

  • Bing - страница, которая была на 2 секунды медленнее, привела к снижению дохода на пользователя на 4,3%.
  • Google - задержка в 400 миллисекунд привела к снижению количества запросов / пользователей на 0,59%.
  • Yahoo ! - Замедление на 400 миллисекунд привело к снижению полностраничного трафика на 5-9%.
  • Shopzilla - Ускорение работы сайта на 5 секунд увеличило коэффициент конверсии на 7-12%, удвоило количество сеансов в поисковом маркетинге и сократило количество необходимых серверов вдвое.
  • Mozilla - сокращение их целевых страниц на 2,2 секунды увеличило конверсию загрузок на 15,4%, что, по их оценкам, приведет к увеличению числа загрузок Firefox на 60 миллионов в год.
  • Netflix - применение единой оптимизации, сжатия gzip, привело к ускорению на 13-25% и уменьшило их исходящий сетевой трафик на 50%.

Стив Соудерс, пионер в области оптимизации веб-производительности,

80-90% времени отклика конечного пользователя тратится на интерфейс - сначала начните здесь.

Использование внешних файлов приводит к созданию более быстрых страниц, поскольку файлы JavaScript и CSS кэшируются браузером / network / proxies (как определено в протоколе HTTP с заголовками Cache). JavaScript и CSS, которые встроены в документы HTML, загружаются каждый раз, когда запрашивается документ HTML. Это уменьшает количество необходимых HTTP-запросов, но увеличивает размер HTML-документа. Если вы используете Jquery-подобные сценарии, легко сослаться на 300 КБ сценариев и не полагать, что у всех есть пропускная способность 100 Мбит / с с низкой задержкой, при этом на вашем веб-сайте запускается одно приложение - браузер. 99% раз это даст вам быстрое время отклика конечного пользователя.

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

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

Вы можете прочитать здесь, почему производительность имеет значение (Отказ от ответственности: я автор)


3

Последняя версия HTTP была создана еще в 1999 году. В 1999 году все подключились к Интернету по телефонной линии. Интернет был очень медленным. 16 лет спустя многое изменилось, а протоколы, которые мы используем, - нет.

Ответы, которые мы не должны указывать «потому что это мешает кешированию», немного вводят в заблуждение, особенно в эпоху сверхбыстрого Интернета. Когда вы на самом деле делаете расчеты, часто существует незначительная разница между временем загрузки для пользователей с высокой и минимальной кэш-памятью, если вы указали. Тот факт , что это небольшая разница не по своей сути , потому что вы встраиваемыми, но из - за негибкой конструкции HTTP / 1.1.

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

HTTP / 2.0 основан на SPDY и, скорее всего, будет реализовывать серверную загрузку, но теоретически вы можете начать использовать SPDY уже сегодня. Таким образом, настоящая причина, по которой мы не подключаемся, заключается в том, что унаследованные протоколы устарели и недостаточно гибки для достижения «встраивания на уровне протокола».


2
Интересный ответ, но вместо того, чтобы «унаследовать», причина, по которой вы отказываетесь от встраивания в настоящее время, заключается в том, что он лучше всего подходит для текущей инфраструктуры веб-протокола. Будет унаследовано, если все будут делать то же самое в течение n лет, когда HTTP / 2.0 / SPDY будет полностью развернут ;-)
andybuckley

2
Не могли бы вы привести цитату, набросать расчеты или хотя бы дать приблизительное число для «сверхбыстрого»? Люди в цивилизованных странах первого мира, которые тратят значительные средства на онлайн (читай: клиенты), все еще могут иногда - или даже часто - просматривать данные с меньшей пропускной способностью, чем сотни мегабайт в секунду. Я, например, редко достигаю более трех МБ / с, часто менее 700 КБ / с. В качестве отдельного пункта вы не даете повода для включения в способ, который предлагает OP (на самом деле, вы даете причины не делать этого ), вы даете поводы для оптимизации протоколов.

1
Мое 3G-соединение не совсем «супер быстрое», и мой телефонный счет не оценивает ненужные данные. Не забывайте - не все мобильные данные используются на телефоне с модемами и ноутбуками с поддержкой 3G. Особенно с ноутбуками предполагается, что Wi-Fi / Ethernet на домашней широкополосной связи. Не ценится при удаленном подключении ...
подключении AnonJr

3

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

JavaScript, появляющийся в HTML, может столкнуться с проблемами разбора, как в этом примере:

<html>
<head>
<script>
function myfunc() {
    if ("</style> isn't a problem")
        return "but </script> is"
}
</script>
<style>
body::after {
  content: '</script> is okay, but not </style>'
}
</style>
</head>
<body>
<script>document.write(myfunc())</script>
</body>
</html>

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

Если вы используете свой контент как XML, у вас есть возможность обойти это, используя разделы CDATA. CDATA, однако, имеет аналогичную проблему:

<?xml version="1.0" encoding="utf-8"?>
<html>
<head>
<script>
// <![CDATA[
function myfunc() {
    if ("</script> is no longer a problem")
        return "but ]]> is"
}
// ]]>
</script>
<style>
<![CDATA[
body::after {
  content: 'same ]]> issue here'
}
]]>
</style>
</head>
<body>
<script>document.write(myfunc())</script>
</body>
</html>

Инлайнеры остерегаются.


1

Отделение контента от стиля его представления обычно является большим преимуществом, чем меньшее количество http-запросов.

Разделение всех стилей позволяет и поощряет повторное использование и совместное использование файлов.

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

Для вас конкретный вопрос, хотя ... Если сервер выполнен для минимизации, это усложняет обслуживание ресурсов и устраняет проблемы. Однако многие фреймворки теперь делают это на уровне файлов, например, все cs и все js. Например, структура ruby ​​on rails теперь минимизирует свои активы для производства. 5-10 дополнительных http-запросов обычно не являются узким местом, их больше, если есть более 100 http-запросов (которые вы часто получаете с изображениями).

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


Чтобы уточнить, вы говорите, что разделение стиля и контента приносит пользу разработчикам или повышает производительность в браузере конечного пользователя?

Я говорю, что общая выгода для компании - это, как правило, больший выигрыш, чем сокращение запросов в деловом плане.
Майкл Даррант

3
Вы действительно понимаете, что OP выступает за разработку с отдельными файлами и только конкатенацию во время развертывания, наряду с минификацией, запутыванием и «регулярной» конкатенацией? Вы получаете поддерживаемую базу кода и получаете преимущества в производительности. Это обычная практика для других оптимизаций искажения кода, таких как минимизация исходного кода и объединение нескольких файлов JS / CSS в один.

Я не понимаю этого. Слова «встроить эти соединенные стили и сценарии в HTML?» смущай меня.
Майкл Даррант

Просто чтобы прояснить, я действительно хотел предложить то, что @delnan разъяснил от моего имени в своем комментарии. Извините, если формулировка моего вопроса была неоднозначной.
GladstoneKeep

1
  1. Минимизируйте дублирование кодирования. для экономии времени (Вы можете повторно использовать стиль и функцию JS, закодированные для одной страницы).
  2. Минимизируйте усилия по изменению. (Если ваш клиент просит вас изменить цвет кнопки на веб-сайте. Вам нужно перейти на одну страницу за одной).
  3. Сократите время загрузки (если ваши CSS и JS дублируются, это означает, что размер отдельных страниц увеличивается и требуется много времени для загрузки. Но обычные CSS JS не нужно загружать снова и снова).
  4. Удаленное использование. (Вы можете разместить свой обычный CSS js JS в удаленном месте. Не тот же сервер)
  5. Уменьшите время исправления ошибок. Если в одной функции есть ошибка, вам нужно переходить на страницу, чтобы исправить ошибки во встроенных JS и CSS.
  6. Чтобы увеличить SEO (просто разделите контент с метаданными)
  7. Более понятный и понятный код (если вы вложите все в один файл, отладка и ясность кода пропадут. И каждая страница будет очень длинной страницей).
  8. Кроме того, это поможет вам уменьшить размер продукта.
  9. Но все же вы можете рассмотреть возможность встроить самую уникальную вещь на той же странице.

0

Мы не должны вставлять стили / скрипты в HTML, потому что

Встроенные стили / скрипты должны быть загружены с каждым запросом страницы:

Эти стили не могут быть кэшированы браузером и повторно использованы для другой страницы. Из-за этого рекомендуется встраивать как можно меньше CSS / JS.

вместо этого мы используем связывание coz, когда используем связывание для связывания css / scripts

Скорость сайта увеличивается для нескольких запросов страниц:

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.