Что может заблокировать rendering HTML-страницы?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Это критически важный вопрос, потому что проблемы с рендерингом напрямую влияют на скорость загрузки и UX. В контексте Node.js backend обычно речь идёт о серверном рендеринге (SSR), но механизм блокировок универсален.
1. Синхронный JavaScript код на главном потоке
Самая частая причина — длительный синхронный код блокирует event loop браузера.
// ❌ ПЛОХО - блокирует рендеринг на 5+ секунд
const processLargeData = () => {
const items = new Array(100000000);
for (let i = 0; i < items.length; i++) {
items[i] = Math.sqrt(i);
}
return items;
};
document.addEventListener("DOMContentLoaded", processLargeData);
// ✅ ХОРОШО - используем async/await и рассчиваем работу
const processLargeDataAsync = async () => {
let items = [];
for (let i = 0; i < 100000000; i++) {
items.push(Math.sqrt(i));
if (i % 100000 === 0) {
await new Promise(resolve => setTimeout(resolve, 0)); // Даём браузеру время рендерить
}
}
return items;
};
2. Блокирующие CSS и JavaScript ресурсы
HTML парсер останавливается при встречении обычного script без атрибутов async или defer:
<!-- БЛОКИРУЕТ рендеринг до загрузки и выполнения-->
<head>
<script src="https://slow-cdn.com/bundle.js"></script>
</head>
<!-- НЕ блокирует -->
<head>
<script src="bundle.js" defer></script>
<link rel="preload" href="styles.css" as="style">
</head>
3. Проблемы с сетью (Network-bound blocking)
Если ресурсы загружаются медленно, браузер ждёт:
// Node.js backend issue: медленные API запросы
app.get("/api/page", async (req, res) => {
// Ждём всё параллельно — если один запрос 10 сек, всё падает
const user = await fetch("https://api.example.com/user").then(r => r.json());
const posts = await fetch("https://api.example.com/posts").then(r => r.json());
const comments = await fetch("https://api.example.com/comments").then(r => r.json());
res.render("page", { user, posts, comments });
});
// ХОРОШО — используем Promise.all
app.get("/api/page", async (req, res) => {
const [user, posts, comments] = await Promise.all([
fetch("https://api.example.com/user").then(r => r.json()),
fetch("https://api.example.com/posts").then(r => r.json()),
fetch("https://api.example.com/comments").then(r => r.json()),
]);
res.render("page", { user, posts, comments });
});
4. Количество DOM элементов
Слишком большой DOM дерево замедляет парсинг и рендеринг:
// ПЛОХО - 10000 элементов в одном рендере
const bigList = items.map(item => `<li>${item}</li>`).join("");
container.innerHTML = bigList;
// ХОРОШО - виртуализация/пагинация
const ITEMS_PER_PAGE = 50;
const renderPage = (pageNum) => {
const start = pageNum * ITEMS_PER_PAGE;
const end = start + ITEMS_PER_PAGE;
const html = items.slice(start, end)
.map(item => `<li>${item}</li>`)
.join("");
container.innerHTML = html;
};
5. Layout Thrashing и Forced Reflows
Если код чередует чтение и запись DOM свойств, браузер вынужден пересчитывать layout:
// ПЛОХО - 1000 reflows
for (let i = 0; i < elements.length; i++) {
elements[i].style.width = elements[i].offsetWidth + 10 + "px"; // Читаем + пишем
}
// ХОРОШО - batch операции
const widths = Array.from(elements).map(el => el.offsetWidth); // Все чтения
widths.forEach((width, i) => {
elements[i].style.width = (width + 10) + "px"; // Все записи
});
6. Шрифты и FOUT/FOIT
Блокирующие веб-шрифты могут задержать rendering:
@font-face {
font-family: 'CustomFont';
src: url('font.woff2');
font-display: auto;
}
@font-face {
font-family: 'CustomFont';
src: url('font.woff2');
font-display: swap;
}
7. Недостаточно памяти или CPU
Если сервер перегружен, он не может обработать запросы для статики/HTML:
// Node.js: следи за памятью и CPU
const os = require("os");
app.use((req, res, next) => {
const used = process.memoryUsage().heapUsed / 1024 / 1024;
const cpuUsage = os.loadavg()[0];
if (used > 500 || cpuUsage > 0.8) {
return res.status(503).send("Server overloaded");
}
next();
});
Итого: главное помнить, что рендеринг блокируется синхронным кодом, медленными ресурсами и проблемами с сетью. Решение — асинхронность, параллелизм и оптимизация.