Ответ 1
Это неверно. Вы должны попытаться разделить/разбить код в самой низкой точке. Я думаю, что его маловероятно, что просто разделить каждую итерацию цикла достаточно в долгосрочной перспективе.
Однако вам действительно нужно настроить асинхронный таймер убегания, который дает возможность реализовать достаточно места для обновления очереди UI (или потока пользовательского интерфейса). Обычно это делается с помощью таких методов, как setTimeout()
(клиент), nextTick
(node.js) или setImmediate
(скоро).
Например, скажем, у нас есть массив, и мы хотим обработать каждую запись
var data = new Array(10000).join( 'data-' ).split('-'); // create 10.000 entries
function process( elem ) {
// assume heavy operations
elem.charAt(1) + elem.charAt(2);
}
for(var i = 0, len = data.length; i < len; i++ ) {
process( data[i] );
}
Теперь этот код является классическим циклом, итерацией по массиву и обработкой его данных. Он также будет потреблять 100% процессорного времени и, следовательно, блокирует очередь пользовательских интерфейсов браузера, если требуется, чтобы обрабатывать все записи (что в основном означает, что пользовательский интерфейс браузера замерзнет и перестанет реагировать).
Чтобы этого избежать, мы могли бы создать такую конструкцию:
var data = new Array(10000).join( 'data-' ).split('-'); // create 10.000 entries
function runAsync( data ) {
var start = Date.now();
do {
process( data.shift() );
} while( data.length && Date.now() - start > 100 );
if( data.length ) {
setTimeout( runAsync.bind( null, data ), 100 );
}
}
runAsync( data.concat() );
Что происходит здесь?
В основном мы делаем это:
- Возьмите массив и обработайте как можно больше данных/записей в таймфрейме 100 мс
- После этого прекратите обработку (вызовите
setTimeout
) и дайте UI возможность обновить - сделайте это, пока у нас все еще есть данные в массиве
Любая задержка выше 100 мс обычно распознается глазами человека как "отставание". Все, что ниже этого, кажется плавным и приятным (по крайней мере, наши глаза расскажут нам об этом). 100 мс является хорошим значением в качестве предела для максимального времени обработки. Я даже предлагаю спуститься до 50 мс.
Опасность здесь заключается в том, что общее время обработки увеличится, но я думаю, что лучше иметь более длительную обработку и оставаться отзывчивым, вместо этого быстрее обрабатывать и очень плохой пользовательский интерфейс.
Быстрая демонстрация: