← Назад к вопросам
Как понять что загрузились все ресурсы?
2.0 Middle🔥 182 комментариев
#JavaScript Core
Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Проверка полной загрузки всех ресурсов
В современных браузерах существует несколько способов определить, когда все ресурсы страницы (скрипты, стили, изображения, шрифты) полностью загружены. Это критично для обеспечения правильной работы приложения и улучшения пользовательского опыта.
События загрузки страницы
Основные события жизненного цикла загрузки:
// 1. DOMContentLoaded - DOM построен, но не все ресурсы загружены
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM готов, можно работать с элементами');
// Скрипты, стили и изображения могут ещё загружаться
});
// 2. Load - все ресурсы загружены (iframe, изображения, стили, скрипты)
window.addEventListener('load', () => {
console.log('Все ресурсы загружены');
// Теперь безопасно обращаться ко всем элементам
});
// 3. beforeunload - перед закрытием страницы
window.addEventListener('beforeunload', () => {
console.log('Пользователь закрывает страницу');
});
Проверка состояния документа
Свойство document.readyState показывает текущее состояние загрузки:
// Состояния readyState:
// "loading" - документ загружается
// "interactive" - загрузка завершена, но ресурсы загружаются
// "complete" - все ресурсы загружены
function waitForFullLoad() {
return new Promise(resolve => {
if (document.readyState === 'complete') {
resolve();
} else {
window.addEventListener('load', resolve);
}
});
}
// Использование
await waitForFullLoad();
console.log('Страница полностью загружена');
Performance API для отслеживания ресурсов
Modern способ - использовать PerformanceObserver:
// Отслеживание загрузки конкретных ресурсов
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.initiatorType === 'script') {
console.log('Скрипт загружен:', entry.name, entry.duration, 'ms');
} else if (entry.initiatorType === 'link') {
console.log('Стиль загружен:', entry.name);
} else if (entry.initiatorType === 'img') {
console.log('Изображение загружено:', entry.name);
}
}
});
observer.observe({ entryTypes: ['resource'] });
Проверка загрузки изображений
// Проверка, загружены ли все изображения на странице
async function waitForAllImages() {
const images = document.querySelectorAll('img');
const promises = Array.from(images).map(img => {
return new Promise((resolve, reject) => {
if (img.complete && img.naturalHeight !== 0) {
// Изображение уже загружено
resolve();
} else {
img.addEventListener('load', resolve);
img.addEventListener('error', reject);
setTimeout(() => reject(new Error('Timeout')), 10000);
}
});
});
return Promise.all(promises);
}
// Использование
try {
await waitForAllImages();
console.log('Все изображения загружены');
} catch (error) {
console.error('Ошибка загрузки изображений:', error);
}
Проверка загрузки шрифтов
// FontFaceSet API - проверка загрузки шрифтов
if (document.fonts) {
document.fonts.ready.then(() => {
console.log('Все шрифты загружены');
// Переотрисуем элементы, если нужно
});
}
// Альтернатива для старых браузеров
async function waitForFonts() {
if (!document.fonts) return;
try {
await document.fonts.ready;
console.log('Шрифты готовы');
} catch (error) {
console.error('Ошибка при загрузке шрифтов:', error);
}
}
Комплексная проверка всех ресурсов
// Функция ждёт полной загрузки всего
async function waitForCompleteLoad() {
// Ждём, пока документ будет готов
await new Promise(resolve => {
if (document.readyState === 'complete') {
resolve();
} else {
window.addEventListener('load', resolve);
}
});
// Ждём шрифтов
if (document.fonts) {
await document.fonts.ready;
}
// Ждём изображений
await waitForAllImages();
// Небольшая задержка для финальной отрисовки
await new Promise(resolve => requestAnimationFrame(resolve));
console.log('Все ресурсы полностью загружены');
}
// Использование
try {
await waitForCompleteLoad();
console.log('Страница готова к работе');
} catch (error) {
console.error('Ошибка при загрузке:', error);
}
Web Vitals для мониторинга загрузки
// Google 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
// Это показывает, насколько хорошо загружается страница
Практический пример для React
import { useEffect, useState } from 'react';
function useLoadingComplete() {
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
const checkLoading = async () => {
if (document.readyState === 'complete') {
setIsLoaded(true);
} else {
await new Promise(resolve => window.addEventListener('load', resolve));
setIsLoaded(true);
}
};
checkLoading();
}, []);
return isLoaded;
}
// Использование
function App() {
const isLoaded = useLoadingComplete();
return (
<div>
{!isLoaded && <Skeleton />}
{isLoaded && <MainContent />}
</div>
);
}
Правильное определение полной загрузки ресурсов улучшает производительность, улучшает взаимодействие с пользователем и обеспечивает корректную работу всех компонентов приложения.