Ответ
Для предотвращения зависания интерфейса при обработке больших массивов используй:
- Web Workers - выноси тяжелые вычисления в отдельный поток:
// main.js
const worker = new Worker('worker.js');
worker.postMessage(largeArray);
worker.onmessage = (e) => {
// Обновляем UI с результатами
};
// worker.js
onmessage = (e) => {
const result = processLargeArray(e.data);
postMessage(result);
};
- Разбиение на чанки с
requestIdleCallbackилиsetTimeout:
function processInChunks(array, chunkSize, callback) {
let index = 0;
function next() {
const chunk = array.slice(index, index + chunkSize);
callback(chunk);
index += chunkSize;
if (index < array.length) {
setTimeout(next, 0); // Даем браузеру время на рендер
}
}
next();
}
- Virtualization для списков - рендери только видимые элементы (React-window, React-virtualized).
Ответ 18+ 🔞
А, ну это ж классика, блядь! Вечный вопрос — как не повесить весь интерфейс, когда твоя функция пытается перемножить матрицы размером с ебучую Вселенную.
Смотри, первое и самое простое — Web Workers. Это как взять своего самого умного, но унылого друга, поселить его в сарай и заставить там в одиночку перебирать эти гребаные данные. Главный поток в браузере отдыхает, интерфейс не дёргается, а в это время воркер в соседней вкладке ебёт мозг процессору.
// main.js — тут мы, красавцы, в основном потоке
const worker = new Worker('worker.js');
worker.postMessage(largeArray); // Швыряем ему в лицо твой терабайтный массив
worker.onmessage = (e) => {
// А тут просто получаем готовый результат, как пиццу на дом
};
// worker.js — а это уже его, лоха, проблемсы
onmessage = (e) => {
const result = processLargeArray(e.data); // Пусть тут обосрётся с вычислениями
postMessage(result);
};
Но если воркер — это слишком жирно, или задача не настолько ебейшая, можно по-старинке, разбить на кусочки. Типа не жрать целого борова за раз, а отрезать по куску, прожевать, глотнуть, и дать браузеру передохнуть, сука.
function processInChunks(array, chunkSize, callback) {
let index = 0;
function next() {
const chunk = array.slice(index, index + chunkSize); // Отрезал ломоть
callback(chunk); // Пережёвываешь
index += chunkSize;
if (index < array.length) {
setTimeout(next, 0); // Вот эта магия — даём браузеру глотнуть воздуха, сказать «ёпта»
}
}
next();
}
Ну и святое — виртуализация. Это когда у тебя список из десяти тысяч элементов, а ты вьебываешь в DOM только те двадцать, которые юзер прямо сейчас видит. Остальные лежат, грубо говоря, в жопе, и ждут своего часа. Библиотеки всякие для этого есть — React-window, React-virtualized. Без них рендерить длинные списки — это просто идти нахуй с сознанием, что ты всё делаешь правильно.