Улучшить производительность веб-сайта с помощью параллельных загрузок CSS?


15

Я оптимизировал время загрузки страницы сайта. Одним из способов было объединение нескольких HTTP-запросов для CSS в один комбинированный HTTP-запрос. Но один из рецензентов задал интересный вопрос: не приведет ли параллелизация загрузки нескольких CSS-файлов к сокращению времени загрузки страницы?

Я никогда не рассматривал этот вариант, так как единственное, что я читал в Интернете, - это то, что сокращение количества (блокирующих) HTTP-запросов является ключом к более быстрой веб-странице (хотя Google Pagespeed Insights, кажется, не четко заявляет об этом 1 ).

Я вижу несколько причин, по которым распараллеливание не приведет к повышению производительности или будет иметь незначительное значение (перевесит преимущество использования меньшего количества HTTP-запросов):

  • Установка нового соединения стоит дорого. Хотя настройка нескольких соединений может выполняться параллельно, браузеры будут использовать не более 4-6 соединений (в зависимости от браузера), поэтому параллельная загрузка CSS блокирует загрузку других ресурсов, таких как JavaScript и изображения.
  • Настройка HTTPS-соединения требует дополнительных данных. Я прочитал это легко может быть несколько килобайт данных. Это некоторые дополнительные данные, которые нужно отправлять по проводам, а не CSS, который мы на самом деле хотим отправить.
  • Благодаря алгоритму медленного запуска TCP, чем больше данных было отправлено по соединению, тем быстрее будет соединение. Таким образом, более продолжительные соединения будут отправлять данные гораздо быстрее, чем новые. Посмотрите, например, протокол SPDY, который использует одно соединение для улучшения времени загрузки страницы.
  • TCP является абстракцией: все еще (обычно) только одно базовое соединение. Таким образом, хотя используется несколько запросов, данные, передаваемые по проводной сети, могут вовсе не обязательно использовать несколько соединений для повышения скорости.
  • Интернет-соединения по своей сути ненадежны, особенно на мобильных устройствах. Один запрос может быть выполнен значительно быстрее, чем другой. Использование нескольких запросов для CSS означает, что отображение веб-страницы блокируется до тех пор, пока не завершится последний запрос, что может быть значительно позже, чем среднее соединение.

Итак, есть ли какая-то польза от распараллеливания HTTP-запросов для CSS-файлов?

Примечание / обновление: все CSS-файлы блокируют рендеринг. CSS-файлы, которые еще не были перемещены за пределы критического пути.


Я видел что-то в коде etsy как сайт для рукоделия, где они рекомендовали использовать только один домен без cookie для статических объектов (css, imgs, js). Оказывается, современные браузеры отлично справляются с параллельными загрузками с одного домена. Что касается нескольких файлов из одного домена (10 CSS-файлов против одного большого), я думаю, что вам лучше объединить и свернуть один большой файл и просто сделать его одним запросом. Особенно с CSS, где вашему сайту, вероятно, понадобится вся CSS, чтобы выглядеть правильно.
Фрэнк

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

Ответы:


14

CSS-файлы, связанные с HTML-документами, добавляются в очередь параллельной загрузки при разборе HTML; Ключевым моментом является то, что не асинхронные ссылки JavaScript блокируют анализатор HTML, предотвращая добавление более поздних тегов в очередь загрузки до тех пор, пока этот JavaScript не будет загружен, проанализирован и выполнен. [1]

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

<head>
  <script src="js/fizz.js"></script>
  <link rel="stylesheet" href="css/foo.css"/>
  <script src="js/buzz.js"></script>
  <link rel="stylesheet" href="css/bar.css"/>
</head>

Вот пример, переделанный таким образом, что все 4 файла загружаются параллельно (как минимум, в одну сторону):

<head>
  <link rel="stylesheet" href="css/foo.css"/>
  <link rel="stylesheet" href="css/bar.css"/>
  <script async src="js/fizz.js"></script>
  <script src="js/buzz.js"></script>
</head>

Еще одно замечание: CSS-файлы (по умолчанию) блокируют рендер, а не парсер; страница будет продолжать анализироваться, и DOM будет создан, но рендеринг не начнется, пока не будет создан CSSOM.

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

Таким образом, нет никакой очевидной выгоды от распараллеливания ваших загрузок CSS только ради них самих. Но как всегда, измерить и проверить!

Для дальнейшего чтения я рекомендую эти статьи на тему «Основы Интернета: оптимизация производительности» от Google: https://developers.google.com/web/fundamentals/performance/.

[1]: Это игнорирует функцию спекулятивного анализа в некоторых браузерах:

https://docs.google.com/document/d/1JQZXrONw1RrjrdD_Z9jq1ZKsHguh8UVGHY_MZgE63II/preview?hl=en-GB&forcehl=1

https://developer.mozilla.org/en-US/docs/Web/HTML/Optimizing_your_pages_for_speculative_parsing


1
Еще одна
полезная статья

Стоит отметить, что все файлы .js должны быть связаны в конце кода непосредственно перед закрывающим тегом body, чтобы они ничего не блокировали.
Chaoley

Можете ли вы уточнить «Итак, нет никакой очевидной выгоды от распараллеливания ваших загрузок CSS только ради них самих»? Я как-то не смог понять это из приведенного выше ответа
gaurav5430

@ gaurav5430 Кажется, нет веских причин для разделения CSS-файлов, кроме оптимизации за время рендеринга выше (и, возможно, оптимизацию кэша?)
Роберт К. Белл,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.