← Назад к вопросам
Сталкивался ли с оптимизацией страницы при загрузке
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 тестирования. Главное - понять, что именно замедляет приложение, и исправить критическое первым.