В одном из ваших последних комментариев вы упомянули, что данные поступают поэтапно, а не все одновременно. Но Array.prototype.sort()
должен каждый раз перерабатывать весь массив, хотя он в основном уже отсортирован; только несколько элементов находятся вне того места, где они должны быть.
Для случая, как у вас, я бы соблазн пойти с вставки рода вместо встроенного метода сортировки в JavaScript (который, как правило, вариант сортировка слиянием или быстрой сортировки, в зависимости от двигатель). Вставка сортировки не очень хороша как универсальный алгоритм сортировки, но это хорошо, когда вам просто нужно добавить пару элементов в уже отсортированный массив. Вот что вы здесь делаете, так что это звучит неплохо.
Вот базовая реализация алгоритма.
/**
* Compare two items as though they were strings.
*
* This is like the default comparison for Array.prototype.sort()
*
* @param {*} a The first item
* @param {*} b The second item
*
* @return -1 if a is less, 1 is b is less, 0 otherwise
*/
function compareStrings(a, b) {
var sa = String(a),
sb = String(b);
if (sa < sb) {
return -1;
}
if (sa > sb) {
return 1;
}
return 0;
}
/**
* Insert a new item into a sorted array.
*
* The compareFunction callback function works as for the analogous argument
* in Array.prototype.sort(). Leave unspecified to compare lexically.
*
* @param {Array} data A sorted array, into which to put this item
* @param {*} newItem The item to add to the data.
* @param {Function=} compareFunction Optional comparison function.
*/
function arrayInsert(data, newItem, compareFunction) {
var stop = data.length,
i = 0;
compareFunction = compareFunction || compareStrings;
while (i < stop) {
if (compareFunction(newItem, data[i]) < 0) {
data.splice(i, 0, newItem);
return;
}
i += 1;
}
// If we got this far, then this should be the last item.
data.push(newItem);
}
Весь массив еще должен быть отсортирован раз, когда страница загружается, и вы не должны использовать вставки рода для этого (это было бы лучше, если вы получаете сервер для отправки вам уже отсортированных данных, но если вы не можете этого сделать, используйте вместо этого обычную функцию Array.prototype.sort
). Затем, когда вы получите новые данные, вызовите arrayInsert(data, newItem, /* your comparison function */)
один раз для каждого нового элемента данных, который вы получите. Это должно ускорить процесс.
Если это все еще слишком медленно, вы можете поместить свои новые элементы данных в очередь и добавить короткий таймер на страницу. Каждые несколько миллисекунд этот таймер проверяет очередь, и если есть какие-то элементы ожидания, он добавляет один из них в массив. На самом деле это не ускорит работу (на самом деле, это сделает их немного медленнее), но страница больше не должна замерзать.
Случается ли это в каждом браузере? Как вы определили, что именно это вызывает замораживание? – Moeri
Если он работает, но замораживает браузер, вы должны установить его по частям (из-за однопоточности) с помощью 'setTimeout()'. – loveNoHate
Имеет ли эти данные какой-то запрос? Если это так, вероятно, было бы лучше, если бы сервер отсортировал данные перед их передачей. –