Что такое отложенная загрузка и зачем она нужна?
Отложенная загрузка (lazy loading) — это техника, которая позволяет загружать ресурсы только тогда, когда они становятся необходимыми. Например, изображения, которые находятся за пределами видимой области страницы, можно не загружать сразу, а подгружать, когда пользователь скроллит вниз и они попадают в поле зрения.
Почему это важно?
- Скорость загрузки: меньше ресурсов загружается сразу, поэтому страница отображается быстрее.
- Экономия трафика: пользователи загружают только те ресурсы, которые им действительно нужны.
- Лучший пользовательский опыт: всё работает быстрее, а пользователям не приходится ожидать.
Согласно исследованиям, если страница загружается больше трёх секунд, 40% пользователей закрывают её. Оптимизированная загрузка помогает избежать этого!
Базовая идея реализации
Отложенная загрузка часто применяется к изображениям. Представьте длинный список карточек с фото, где фотографии изначально не загружаются. Изображение загружается только тогда, когда оно попадает в область видимости экрана (viewport).
Для реализации отложенной загрузки мы будем использовать комбинацию JavaScript, React и HTML5 API, а также познакомимся с библиотеками, которые могут упростить эту задачу.
Реализация отложенной загрузки изображений
Существует два популярных способа реализации:
- Intersection Observer API: нативный способ отслеживать, когда элемент попадает в область видимости.
- Плейсхолдеры: сначала показываются "заглушки" (плейсхолдеры), а изображение загружается позже.
Создаём базовый компонент для lazy loading
Мы начнём с компонента, который загружает изображения только тогда, когда они попадают в область видимости. Используем Intersection Observer API.
Шаг 1: Настройка проекта
Мы продолжаем работать с нашим текущим React-приложением. Убедитесь, что всё настроено.
Файл: LazyImage.tsx
import React, { useState, useEffect, useRef } from "react";
// Интерфейс для пропсов
interface LazyImageProps {
src: string; // URL изображения
alt?: string; // Альтернативный текст
placeholder?: string; // Заглушка, которая будет отображаться до загрузки
}
// LazyImage компонент
const LazyImage: React.FC<LazyImageProps> = ({ src, alt = "", placeholder }) => {
const [isVisible, setIsVisible] = useState(false); // Видимость элемента
const imgRef = useRef<HTMLImageElement | null>(null); // Реф для изображения
// Хук useEffect для наблюдения за элементом
useEffect(() => {
const observer => new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsVisible(true);
observer.disconnect(); // Останавливаем наблюдение
}
});
},
{
threshold: 0.1, // 10% элемента должны быть видимы
}
);
const refElement = imgRef.current;
if (refElement) {
observer.observe(refElement);
}
return () => observer.disconnect();
}, []);
return (
<img
ref={imgRef}
src={isVisible ? src : placeholder} // Отображаем изображение или плейсхолдер
alt={alt}
style={{
width: "100%",
height: "auto",
transition: "opacity 0.5s", // Плавный переход
}}
/>
);
};
export default LazyImage;
Использование компонента LazyImage
Теперь давайте применим наш компонент к списку изображений.
Файл: App.tsx
import React from "react";
import LazyImage from "./LazyImage";
const App: React.FC = () => {
const images = [
"https://via.placeholder.com/600/92c952",
"https://via.placeholder.com/600/771796",
"https://via.placeholder.com/600/24f355",
"https://via.placeholder.com/600/d32776",
];
return (
<div style={{ padding: "20px" }}>
{images.map((image, index) => (
<LazyImage
key={index}
src={image}
alt={`Image ${index + 1}`}
placeholder="https://via.placeholder.com/600/CCCCCC"
/>
))}
</div>
);
};
export default App;
Теперь наш список изображений загружается только тогда, когда пользователь прокручивает страницу и изображение попадает в область видимости!
Улучшение пользовательского опыта с помощью фальшивых заглушек
Мы уже добавили плейсхолдеры. Однако, чтобы сделать загрузку более плавной, можно добавить эффект размытия при появлении изображения.
Измените LazyImage.tsx:
return (
<img
ref={imgRef}
src={isVisible ? src : placeholder}
alt={alt}
style={{
width: "100%",
height: "auto",
filter: isVisible ? "none" : "blur(10px)",
transition: "filter 0.5s",
}}
/>
);
Теперь при появлении изображение будет плавно переходить из размытого состояния в чёткое. Это визуально приятно и добавляет интерактивности.
Библиотеки для отложенной загрузки
Реализовать всё с нуля — это здорово. Но иногда удобно использовать готовые решения. Вот несколько популярных библиотек:
React-lazyload
Одна из самых простых библиотек для отложенной загрузки. Она предоставляет компоненты для создания lazy loading.
npm install react-lazyload
Использование:
import LazyLoad from "react-lazyload";
const App: React.FC = () => {
return (
<LazyLoad height={200} offset={100}>
<img src="https://via.placeholder.com/600/92c952" alt="Lazy Loaded" />
</LazyLoad>
);
};
Особенности и типичные ошибки
При реализации отложенной загрузки могут возникнуть ошибки:
Неправильное определение области видимости: если
IntersectionObserverотслеживает что-то не то, проверьте настройкиthresholdиrootMargin.Слишком много изображений: если у вас тысячи изображений, лучше использовать оптимизированные инструменты, такие как
react-lazyload.Преждевременная загрузка: иногда изображения загружаются заранее. Проверьте, правильно ли вы используете
useRefи обновляете состояние.
Отложенная загрузка необходима в реальных проектах: от онлайн-магазинов с тысячами товаров до соцсетей. На собеседованиях такие задачи могут показаться простыми, но знание нюансов и готовность объяснить выбор подхода добавят вам очков как кандидату.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ