Оптимизация FCP (First Contentful Paint)
FCP — время до появления первого видимого контента: текст, изображение, SVG, canvas. Хорошее значение: ≤ 1.8 секунды. FCP напрямую влияет на восприятие скорости — пользователь видит, что что-то происходит.
Разница FCP и LCP
- FCP — первый пиксель контента (любого)
- LCP — самый крупный элемент
Плохой FCP почти всегда означает плохой LCP. Хороший FCP не гарантирует хороший LCP.
Render-blocking ресурсы — главная причина плохого FCP
Браузер останавливает рендеринг на каждый <link> CSS и <script> в <head>.
<!-- Плохо -->
<head>
<link rel="stylesheet" href="/css/app.css"> <!-- блокирует -->
<link rel="stylesheet" href="/css/plugins.css"> <!-- блокирует -->
<script src="/js/analytics.js"></script> <!-- блокирует -->
</head>
<!-- Хорошо -->
<head>
<!-- Critical CSS inline -->
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
.header { height: 64px; background: #fff; }
/* ... минимальный CSS для above-the-fold контента ... */
</style>
<!-- Non-critical CSS async -->
<link rel="preload" href="/css/app.css" as="style"
onload="this.onload=null;this.rel='stylesheet'">
<!-- Scripts — defer или async -->
<script defer src="/js/app.js"></script>
<script async src="/js/analytics.js"></script>
</head>
Critical CSS — автоматическая генерация
// vite.config.ts с плагином critters
import { defineConfig } from 'vite';
import { critters } from 'critters';
export default defineConfig({
plugins: [
critters({
preload: 'swap', // preload для некритичных стилей
pruneSource: false, // не удалять CSS из исходного файла
})
]
});
Для Laravel — пакет spatie/laravel-vite-plugin + настройка Nginx для отдачи pre-built страниц.
Server-Side Rendering для React
SPA (Single Page Application) имеют плохой FCP — пользователь видит пустой белый экран пока не выполнится JS.
// Next.js — SSR "из коробки"
// Inertia.js — SSR для Laravel
// vite.config.ts для Inertia SSR
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
laravel({ input: 'resources/js/app.tsx', ssr: 'resources/js/ssr.tsx' }),
react(),
],
});
SSR улучшает FCP на 0.5–2 секунды для медленных соединений и устройств.
Шрифты
/* Системный стек — нулевая задержка */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
/* Если нужен кастомный шрифт — preload + font-display: swap */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-regular.woff2') format('woff2');
font-display: swap; /* показать fallback сразу, заменить когда загрузится */
unicode-range: U+0400-045F, U+0490-0491; /* только кириллица */
}
<link rel="preload" href="/fonts/inter-regular.woff2"
as="font" type="font/woff2" crossorigin>
Измерение FCP
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.name === 'first-contentful-paint') {
console.log('FCP:', entry.startTime);
}
}
}).observe({ type: 'paint', buffered: true });
Быстрый чеклист FCP
- Inline critical CSS (above-the-fold стили)
- Все внешние стили — async через
preload - Скрипты —
deferилиasync - Шрифт — preload +
font-display: swap - TTFB < 600 мс (кеш сервера)
- SSR включён (для React/Vue SPA)
- Убраны неиспользуемые CSS-правила (PurgeCSS/Tailwind purge)
Срок оптимизации: 1–2 дня для настройки critical CSS и render-blocking ресурсов.







