\n\n// ХОРОШО: Асинхронная загрузка\n\n\n// ЛУЧШЕ: Отложенная загрузка\n\n\n// В Next.js\nimport Script from 'next/script';\n\nexport function App() {\n return (\n <>\n \n \n );\n}\n```\n\n## Проверка производительности\n\n```javascript\n// Используем Web Vitals API для мониторинга\nimport { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';\n\ngetCLS(console.log); // Cumulative Layout Shift\ngetFID(console.log); // First Input Delay\ngetFCP(console.log); // First Contentful Paint\ngetLCP(console.log); // Largest Contentful Paint\ngetTTFB(console.log); // Time to First Byte\n```\n\nКомбинация этих стратегий значительно улучшает первый рендер и пользовательский опыт.","dateCreated":"2026-04-03T17:52:01.299023","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как оптимизировать первый рендер страницы?

2.2 Middle🔥 181 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Критические операции для первого рендера

Первый рендер (First Contentful Paint, FCP) критичен для пользовательского опыта. Есть несколько основных стратегий оптимизации.

1. Code Splitting и ленивая загрузка

// ПЛОХО: Загружаем весь код сразу
import HeavyComponent from './HeavyComponent';

export function App() {
  return <HeavyComponent />;
}

// ХОРОШО: Загружаем компонент только когда нужно
import dynamic from 'next/dynamic';

const HeavyComponent = dynamic(
  () => import('./HeavyComponent'),
  { 
    loading: () => <div>Loading...</div>,
    ssr: false  // Не рендерим на сервере
  }
);

export function App() {
  return <HeavyComponent />;
}

2. Image Optimization

// ПЛОХО: Обычные img теги
export function Hero() {
  return <img src="/hero.jpg" alt="Hero" />;
}

// ХОРОШО: Next.js Image компонент
import Image from 'next/image';

export function Hero() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero"
      width={1200}
      height={600}
      priority  // Загружаем критичные изображения первыми
      sizes="(max-width: 768px) 100vw, 50vw"
    />
  );
}

3. Минимизация JavaScript

// ПЛОХО: Большой bundle
import * as lodash from 'lodash';
const items = lodash.sortBy(data, 'name');

// ХОРОШО: Импортируем только нужное
import sortBy from 'lodash/sortBy';
const items = sortBy(data, 'name');

// ЛУЧШЕ: Используем встроенные методы JavaScript
const items = [...data].sort((a, b) => a.name.localeCompare(b.name));

4. Критический CSS

// Инлайним критичный CSS для выше сгиба контента
// next.config.js
module.exports = {
  experimental: {
    optimizeCss: true,  // Включаем оптимизацию CSS
  },
};

// Используем критичные стили напрямую
export function Header() {
  return (
    <style>{`
      .header {
        display: flex;
        justify-content: space-between;
        padding: 1rem;
        background: white;
      }
    `}</style>
  );
}

5. Предзагрузка ресурсов

// В Next.js layout или компоненте
import Link from 'next/link';

export function Navigation() {
  return (
    <>
      <Link href="/posts" prefetch={true}>
        Posts
      </Link>
      <Link href="/about">About</Link>
    </>
  );
}

// Вручную предзагружаем ресурсы
export function Head() {
  return (
    <>
      <link rel="preload" as="script" href="/script.js" />
      <link rel="prefetch" href="/api/data" />
      <link rel="dns-prefetch" href="https://external-api.com" />
    </>
  );
}

6. Server-Side Rendering (SSR) и Static Generation

// ПЛОХО: Рендеримся только на клиенте
export default function Page() {
  const [data, setData] = useState(null);
  useEffect(() => {
    fetch('/api/data').then(r => r.json()).then(setData);
  }, []);
  return <div>{data?.title}</div>;
}

// ХОРОШО: Static Generation (самый быстрый вариант)
export async function getStaticProps() {
  const data = await fetch('https://api.example.com/data');
  return {
    props: { data },
    revalidate: 3600  // Переиндексируем каждый час
  };
}

export default function Page({ data }) {
  return <div>{data.title}</div>;
}

// АЛЬТЕРНАТИВА: Server-Side Rendering
export async function getServerSideProps() {
  const data = await fetch('https://api.example.com/data');
  return {
    props: { data },
    revalidate: 60
  };
}

7. Мемоизация компонентов

// ПЛОХО: Пересчитываем на каждый рендер
export function ExpensiveComponent({ items }) {
  const sorted = items.sort((a, b) => a.value - b.value);
  return <div>{sorted.map(i => <div key={i.id}>{i.value}</div>)}</div>;
}

// ХОРОШО: Мемоизируем
import { memo, useMemo } from 'react';

export const ExpensiveComponent = memo(function({ items }) {
  const sorted = useMemo(
    () => items.sort((a, b) => a.value - b.value),
    [items]
  );
  return <div>{sorted.map(i => <div key={i.id}>{i.value}</div>)}</div>;
});

8. Минимизация блокирующих скриптов

// ПЛОХО: Скрипт блокирует парсинг HTML
<script src="/analytics.js"></script>

// ХОРОШО: Асинхронная загрузка
<script async src="/analytics.js"></script>

// ЛУЧШЕ: Отложенная загрузка
<script defer src="/analytics.js"></script>

// В Next.js
import Script from 'next/script';

export function App() {
  return (
    <>
      <Script
        src="/analytics.js"
        strategy="lazyOnload"  // Загружаем после интерактивности
      />
    </>
  );
}

Проверка производительности

// Используем Web Vitals API для мониторинга
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';

getCLS(console.log);    // Cumulative Layout Shift
getFID(console.log);    // First Input Delay
getFCP(console.log);    // First Contentful Paint
getLCP(console.log);    // Largest Contentful Paint
getTTFB(console.log);   // Time to First Byte

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

Как оптимизировать первый рендер страницы? | PrepBro