← Назад к вопросам

Сталкивался ли с оптимизацией страницы при загрузке

1.0 Junior🔥 112 комментариев
#Оптимизация и производительность

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

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

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

Опыт оптимизации производительности веб-приложения

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

1. Анализ производительности

// Использую Web Vitals для мониторинга производительности
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

// Или через Performance API
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log('Entry:', entry.name, entry.duration);
  }
});

observer.observe({ entryTypes: ['measure', 'navigation', 'resource'] });

// Performance API для custom metrics
performance.mark('image-load-start');
// ... загрузка изображения
performance.mark('image-load-end');
performance.measure('image-load', 'image-load-start', 'image-load-end');

2. Code Splitting и динамическая загрузка

// Next.js dynamic import - загрузка компонента только при необходимости
import dynamic from 'next/dynamic';

const HeavyDashboard = dynamic(
  () => import('@/components/Dashboard'),
  { 
    loading: () => <div>Загружается...</div>,
    ssr: false // Не рендерим на сервере для тяжелых компонентов
  }
);

// React.lazy для обычного React
const LazyComponent = React.lazy(() => import('./LazyComponent'));

// Route-based code splitting в Next.js App Router
// Каждый маршрут автоматически code-splittится
export default function Page() {
  return <HeavyFeature />;
}

3. Image Optimization

// Next.js Image компонент с автоматической оптимизацией
import Image from 'next/image';

export function OptimizedImage() {
  return (
    <Image
      src="/photo.jpg"
      width={800}
      height={600}
      alt="Description"
      priority={false}  // Lazy loading по умолчанию
      quality={75}      // Сжимаем на 75% качества
      placeholder="blur" // Blur при загрузке
    />
  );
}

// Для фона используем srcSet для разных разрешений
<picture>
  <source srcSet="/image-small.jpg 640w, /image-large.jpg 1280w" />
  <img src="/image-large.jpg" alt="Description" />
</picture>

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

// Tree-shaking неиспользуемого кода
// Импортируем только нужные функции
import { debounce } from 'lodash-es'; // Правильно - поддерживает tree-shaking
// import _ from 'lodash'; // Неправильно - загружает всё

// Используем современный синтаксис для меньшего размера
const obj = { ...oldObj, newKey: 'value' }; // Правильно
Object.assign(obj, oldObj, { newKey: 'value' }); // Больше кода

// Удаляем console.logs в продакшене
const isDev = process.env.NODE_ENV === 'development';
if (isDev) {
  console.log('Debug info');
}

5. Кэширование ресурсов

// Service Worker для кэширования
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}

// Кэширование API ответов
const cache = new Map();

async function fetchWithCache(url) {
  if (cache.has(url)) {
    return cache.get(url);
  }
  
  const response = await fetch(url);
  const data = await response.json();
  
  cache.set(url, data);
  return data;
}

// HTTP кэширование заголовки
// Cache-Control: max-age=31536000 для статических асетов
// Cache-Control: no-cache для динамического контента

6. Ленивая загрузка контента (Lazy Loading)

// Intersection Observer для ленивой загрузки изображений
const imageObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      img.classList.remove('lazy');
      observer.unobserve(img);
    }
  });
});

document.querySelectorAll('img.lazy').forEach(img => {
  imageObserver.observe(img);
});

// Виртуализация больших списков
import { FixedSizeList } from 'react-window';

function VirtualList({ items }) {
  return (
    <FixedSizeList
      height={600}
      itemCount={items.length}
      itemSize={35}
      width="100%"
    >
      {({ index, style }) => (
        <div style={style}>{items[index]}</div>
      )}
    </FixedSizeList>
  );
}

7. Критические оптимизации, которые я реализовал

  • First Contentful Paint (FCP): Перенес критические CSS выше в документ (inline critical CSS)
  • Largest Contentful Paint (LCP): Приоритизировал загрузку hero-изображений через атрибут priority
  • Cumulative Layout Shift (CLS): Зарезервировал пространство для изображений через aspect-ratio
  • Время ответа сервера (TTFB): Использовал ISR (Incremental Static Regeneration) в Next.js

8. Инструменты для мониторинга

// Lighthouse CI для автоматической проверки
// Google PageSpeed Insights API
// WebPageTest для детального анализа
// Chrome DevTools Performance tab

// npx lighthouse https://example.com --output-path=./report.html

Результаты оптимизации

На одном из моих проектов я:

  • Сократил размер бандла с 450KB до 180KB (-60%)
  • Улучшил LCP с 3.5s до 1.2s
  • Повысил Lighthouse score с 62 до 95
  • Снизил bounce rate на 25%

Оптимизация - это постоянный процесс, требующий мониторинга и А/B тестирования. Главное - понять, что именно замедляет приложение, и исправить критическое первым.