Как загрузка CSS влияет на рендеринг страницы

Ответ

При медленной загрузке CSS браузер может отображать нестилизованный контент (Flash of Unstyled Content - FOUC). Это происходит потому, что HTML загружается и парсится быстрее, чем CSS.

Для предотвращения FOUC можно:

  1. Размещать CSS в <head> (блокирует рендеринг до загрузки стилей)
  2. Использовать preload для критического CSS:
<link rel="preload" href="critical.css" as="style" onload="this.rel='stylesheet'">
  1. Встраивать критический CSS прямо в HTML
  2. Для SPA можно скрывать приложение до загрузки стилей:
.app { opacity: 0; transition: opacity 0.3s; }
.app-loaded { opacity: 1; }
window.addEventListener('load', () => {
  document.querySelector('.app').classList.add('app-loaded');
});

Ответ 18+ 🔞

А, слушай, вот это реальная проблема, как же она бесит! Ты только представь: открываешь сайт, а там, блядь, текст голый, как младенец, торчит во все стороны, а потом — бац! — и на него штаны-стили надели. Это и есть тот самый FOUC, ёпта, Flash of Unstyled Content. Просто пиздец какой-то, а не пользовательский опыт.

А происходит эта хуйня потому, что браузер — он торопыга ебаный. HTML ему загрузился, он его быстренько распарсил и уже рисует, а CSS-то ещё где-то ползёт по сети, как черепаха в сиропе. Вот и получается промежуточный кадр: всё есть, но выглядит как говно.

Ну, а теперь, как с этим безобразием бороться, чтобы не охуевать каждый раз:

  1. Первое и самое простое — запихни свои <link> на стили прямо в <head>. Это как поставить охранника на дверь: браузер не начнёт рисовать контент, пока хотя бы не начнёт качать стили. Блокирует рендеринг, конечно, но зато никаких голых задниц.

  2. Хочешь умнее? Используй preload. Скажи браузеру: «Слушай, дружище, вот этот файл — critical.css — он овердохуища важен, качай его в первую очередь, как шпиона за границу». А как загрузит — сразу применяй.

    <link rel="preload" href="critical.css" as="style" onload="this.rel='stylesheet'">

    Смотри, какая хитрая жопа: сначала rel="preload", а потом, когда загрузилось, мы меняем атрибут на stylesheet. Браузер такой: «А, ну окей, теперь ты не просто важный груз, ты инструкция к применению».

  3. Для самых параноидальных — встрой критический CSS прямо в HTML, в <style>. Это гарантия, что самые базовые стили (шапка, основные кнопки, сетка) будут сразу. Остальное можно подгрузить асинхронно. Минус — кэшировать отдельно не получится, но зато FOUC будет похерен.

  4. Ну и для этих ваших модных SPA (Single Page Application) есть свой финт ушами. Прячем всё приложение, пока стили не приехали, а потом плавненько показываем. Элегантно, как хуй в пальто.

    .app {
      opacity: 0;
      transition: opacity 0.3s;
    }
    .app-loaded {
      opacity: 1;
    }
    window.addEventListener('load', () => {
      document.querySelector('.app').classList.add('app-loaded');
    });

    Всё, сука, приложение изначально невидимо (opacity: 0). Ждём события load (когда и стили, и всё прочее готово), и только тогда добавляем класс, который его проявляет. Пользователь даже не успеет охуеть.

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