Загрузка и ленивые компоненты
Подтемы:
Какие этапы критического пути рендеринга блокируют первый экран?
Браузер разбирает HTML в DOM и CSS в CSSOM; блокирующие stylesheet задерживают построение render tree. Синхронный script может остановить parser, особенно если ему нужен CSSOM. Затем браузер вычисляет стили, строит render tree, выполняет layout и paint, после чего compositing собирает слои. Первый экран задерживают большой HTML, блокирующие CSS и script, шрифты, долгий main-thread JavaScript и поздно обнаруженные ресурсы. Оптимизация начинается с измерения waterfall и Performance trace: критический CSS уменьшают, некритичный JavaScript откладывают, а ключевые изображения и шрифты загружают с правильным приоритетом.
Ссылки для изучения
Как найти причину Layout Shift на странице?
Сначала находят конкретные layout shift в Performance panel и связывают их с элементами; Lighthouse помогает в лаборатории, а field data показывает реальных пользователей. Частые причины: изображения и iframe без width/height или aspect-ratio, вставка баннера над уже показанным контентом, поздняя замена шрифта и анимация свойств, влияющих на layout. Для динамического блока заранее резервируют место, а движение делают через transform. Сдвиг после недавнего пользовательского действия может не входить в CLS, но всё равно портить опыт. Исправление подтверждают повторным trace и полевым распределением CLS.
Ссылки для изучения
Чем async отличается от defer при загрузке скрипта?
Оба атрибута позволяют загружать внешний classic script параллельно с HTML parsing. async выполняет скрипт сразу после загрузки, поэтому блокирует parser в этот момент и не сохраняет порядок между несколькими скриптами. Он подходит независимым аналитическим скриптам. defer выполняет скрипты после завершения parsing, до DOMContentLoaded, сохраняя порядок документа; это удобно для зависимого кода приложения. Для module scripts поведение отличается: они defer по умолчанию, а async меняет ожидание зависимостей. Без атрибутов classic script обычно блокирует parsing сразу.
Ссылки для изучения
Примеры хороших ответов из реальных собеседований
- СОБЕСЕДОВАНИЕ Middle FRONTEND разработчика | JavaScript REACT TYPESCRIPT · 41:00–44:03Техническое собеседование · Совместный разбор
На примере зависимых скриптов разбирают, почему важен порядок выполнения, как его сохраняет defer и чем отличается связь async/defer с DOMContentLoaded.
Как реализовать lazy loading в React с использованием Suspense?
Lazy loading позволяет загружать компоненты только тогда, когда они
необходимы, улучшая производительность приложения.
Шаги:
-
Используйте
React.lazyдля динамического импорта компонента:const MyComponent = React.lazy(() => import("./MyComponent")); -
Обертайте компонент в
React.Suspenseи укажите fallback-контент:import React, { Suspense } from "react"; const App = () => ( <Suspense fallback={<div>Loading...</div>}> <MyComponent /> </Suspense> ); export default App;
Пример:
import React, { Suspense } from "react";
const MyComponent = React.lazy(() => import("./MyComponent"));
const App = () => (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
export default App;
Для реализации lazy loading в React используйте React.lazy для динамического импорта компонентов и React.Suspense для отображения fallback-контента во время их загрузки.
Ссылки для изучения
Примеры хороших ответов из реальных собеседований
- Собеседование Frontend-разработчика: React и производительность · 49:29–50:24Техническое собеседование · Ответ кандидата
Кандидат объясняет связку React.lazy и Suspense на уровне маршрутов: отдельные чанки, загрузку по необходимости и fallback на время ожидания.
Как работает “ленивая загрузка” (lazy loading) компонентов в React?
Ленивая загрузка — это техника, позволяющая загружать компоненты только тогда, когда они необходимы, что улучшает производительность приложения.
Основные шаги:
-
Динамический импорт с
React.lazy:React.lazyиспользуется для динамического импорта компонентов.
const MyComponent = React.lazy(() => import('./MyComponent')); -
Обертка в
React.Suspense:- Компонент оборачивается в
React.Suspenseс указанием fallback-контента, который отображается во время загрузки компонента.
import React, { Suspense } from 'react'; const App = () => ( <Suspense fallback={<div>Loading...</div>}> <MyComponent /> </Suspense> ); export default App; - Компонент оборачивается в
Пример:
import React, { Suspense } from "react";
// Динамический импорт компонента
const MyComponent = React.lazy(() => import("./MyComponent"));
const App = () => (
<Suspense fallback={<div>Loading...</div>}>
<MyComponent />
</Suspense>
);
export default App;
Ленивая загрузка компонентов в React осуществляется с помощью React.lazy для динамического импорта и React.Suspense для указания fallback-контента, что позволяет загружать компоненты только при необходимости и улучшать производительность приложения.
Ссылки для изучения
Примеры хороших ответов из реальных собеседований
- Собеседование Frontend-разработчика: React и производительность · 49:29–50:24Техническое собеседование · Ответ кандидата
Кандидат объясняет загрузку компонентов отдельными чанками по необходимости и роль Suspense во время ожидания.
Как работает “ленивая загрузка” (lazy loading) сторонних библиотек в React?
Ленивая загрузка сторонних библиотек в React позволяет загружать библиотеки только при необходимости, улучшая производительность приложения.
Основные шаги:
-
Использование динамического импорта:
- Используйте функцию
import()для динамического импорта библиотеки.
- Используйте функцию
-
Работа с импортированной библиотекой:
- Обработайте асинхронный импорт с помощью
async/awaitили.then().
- Обработайте асинхронный импорт с помощью
Пример с async/await:
import React, { useState, useEffect } from "react";
const MyComponent = () => {
const [library, setLibrary] = useState(null);
useEffect(() => {
const loadLibrary = async () => {
const { default: lib } = await import("some-library");
setLibrary(() => lib);
};
loadLibrary();
}, []);
if (!library) {
return <div>Loading library...</div>;
}
// Использование библиотеки после загрузки
return <div>{/* Используйте загруженную библиотеку */}</div>;
};
export default MyComponent;
Пример с .then():
import React, { useState, useEffect } from "react";
const MyComponent = () => {
const [library, setLibrary] = useState(null);
useEffect(() => {
import("some-library").then(({ default: lib }) => {
setLibrary(() => lib);
});
}, []);
if (!library) {
return <div>Loading library...</div>;
}
// Использование библиотеки после загрузки
return <div>{/* Используйте загруженную библиотеку */}</div>;
};
export default MyComponent;
Ленивая загрузка сторонних библиотек в React осуществляется с помощью динамического импорта import(), что позволяет загружать библиотеки только при необходимости, улучшая производительность приложения.
Ссылки для изучения
Как реализовать “ленивую загрузку” (lazy loading) изображений в React?
Для реализации ленивой загрузки изображений в React можно использовать библиотеку react-lazyload или встроенный атрибут loading="lazy".
С использованием react-lazyload:
-
Установка библиотеки:
npm install react-lazyload -
Использование компонента
LazyLoad:import React from "react"; import LazyLoad from "react-lazyload"; const App = () => ( <div> <LazyLoad height={200} offset={100}> <img src="path/to/image.jpg" alt="Lazy loaded example" /> </LazyLoad> </div> ); export default App;
С использованием атрибута loading="lazy":
const App = () => (
<div>
<img src="path/to/image.jpg" alt="Lazy loaded example" loading="lazy" />
</div>
);
export default App;
Для ленивой загрузки изображений в React используйте библиотеку react-lazyload или встроенный атрибут loading="lazy" для элементов <img>.
Ссылки для изучения
Примеры хороших ответов из реальных собеседований
- Frontend-собеседование: оптимизация страницы и задача Tribonacci · 1:00:32–1:00:50Разбор интервью · Ответ кандидата
Кандидат предлагает нативную ленивую загрузку изображений через атрибут loading="lazy".
Что такое “code splitting” (разделение кода) в React?
Code Splitting — это техника оптимизации, которая позволяет
разбивать приложение на небольшие части (чанки), загружаемые по мере
необходимости, что улучшает производительность и уменьшает время загрузки.
Основные методы:
-
Динамический импорт:
- Использование
import()для загрузки модулей по требованию.
const MyComponent = React.lazy(() => import('./MyComponent')); - Использование
-
React.lazy и React.Suspense:
- Для асинхронной загрузки компонентов и отображения fallback-контента.
import React, { Suspense } from 'react'; const MyComponent = React.lazy(() => import('./MyComponent')); const App = () => ( <Suspense fallback={<div>Loading...</div>}> <MyComponent /> </Suspense> ); export default App;
Code Splitting в React улучшает производительность, разбивая приложение на небольшие чанки, которые загружаются по мере необходимости, используя динамические импорты и React.lazy с React.Suspense.
Ссылки для изучения
Примеры хороших ответов из реальных собеседований
- Реальное собеседование Frontend-разработчика Middle/Senior · 52:46–53:16Собеседование · Ответ кандидата
Кандидат объясняет загрузку компонентов и страниц отдельными чанками через React.lazy и Suspense, чтобы не скачивать весь бандл сразу.







