Оптимизация прорисовки таблицы
В-общем, суть задачи, которую никак не могу решить более-менее правильно... И так, и так - не нравится скорость прорисовки - и все тут...
var myTable = [];//Массив строк, длина массива может быть и 1000 var myTableRow = [];//Каждый эл-нт массива myTable имеет еще массив, т.н. столбец. Столбцов может быть до 20ти штук //Каждый столбец имеет свой тип. Например, если там число, то привести его в дату по шаблону "d.m.Y в H:i". Если нарисовать структуру, то она будет такой: myTable = { [Type:'int' or 'text', Value: '0-9' or 'azAZ'], ... [Type:'int' or 'text', Value: '0-9' or 'azAZ'] }; В итоге, получается такой цикл для рисования этой таблицы var rc = myTable.length; var cc = myTable[0].length;//Каждая строка имеет одинаковое кол-во столбцов var ri; var ci; var row; var Result = []; var c; Result.push('<table><tbody>'); for (ri = 0; ri < rc; ri++) { row = []; for (ci = 0; ci < cc; ci++) { c = myTable[ri].Col[ci]; switch(c.Type) { case 'int': { c = new Date(parseInt(c.Value)); c = c.getDate(); } break; case 'text': { c = '"' + c + '"'; } break; } row.push(c); } Result.push('<tr><td>' + row.join('</td><td>') + '</td></tr>'); } Result.push('</tbody></table>'); $(myTableArea).html(Result.join('')); Проблема в том, что скорость такой "сборки" таблицы оставляет желать лучшего... Например, у меня скорость такого алгоритма на 15 строк занимает где-то 300 мс. Если строк не 15, а 100, то алгоритм занимает больше секунды. А если 1000 строк нарисовать... То это вообще можно спать идти :) Кто что подскажет? PS: Разработка не кросс-браузерная, исключительно под Firefox. |
попробуй использовать вместо $().html(), который как я предполагаю является аналогом innerHTML, createElement
думаю этот метод займет чуточку больше времени на генерацию таблицы, но добавление собранной в памяти таблицы займет гораздо меньше времени, наверно |
Цитата:
Заметил, что много времени (где-то 100-150 мс на 15 строк) тратится на удаление прошлой таблицы. Например, мне надо вывести следующие 15 строк. Я удаляю старую таблицу и создаю новую. Так вот, последующие создания (обновления) требуют на 100-150 мс больше... Пытался заменить switch на массив из function, т.е.: var fa = []; for (ci = 0; ci < cc; ci++) { switch(myTable[0].Col[ci].Type) { case 'int': { fa[ci] = function(Col) { Col = new Date(parseInt(Col)); Col = Col.getTime(); }; } break; case 'text': { fa[ci] = function(Col) { Col = '"' + Col + '"'; }; } break; } } И дальше вместо switch сразу вызывать функцию через fa[ci]( myTable[ri].Col[ci].Value). Но это заняло на порядок больше времени, чем простой switch... PS: А что, если в switch манипулировать цифрами, а не текстом? Т.е. вместо int использовать 0, вместо text - 1? С точки зрения машины, будет ли это производительней? |
итерировать сначала по столбцам, а потом по строкам..
|
push умеет принимать несколько параметров
|
Цитата:
|
из дивов её собирать...
|
Цитата:
100 строк по 10 столбцов в каждой - это 1000 DIV'ов... Не будет ли это сложновато для отрисовки? :blink: |
думаешь 1000 ячеек будет проще? х)
|
Цитата:
|
frid-karatel,
попробуй разбить таблицу из 1000 строк на 10 таблиц из 100 строк. |
Дело именно в отрисовке?
Попробуйте найти узкое место - запустите цикл "вхолостую", с записью не в innerHTML, а в какую-нибудь левую переменную; в реальную таблицу, у которой display:none; в реальную таблицу, у которой table-layout: fixed. Просто возможно, что тормозит не математика и DOM, а reflow. |
Код:
TABLE.prototype.Print = function() { this.Sort(); /* Сортировка по принципу вызова доп. функции к эл-ту т.е. if (a > b) return 1; else return -1; return 0; */ for (ri = 0; ri < rc; ri++) { for (ci = 0; ci < cc; ci++) { switch(...) { /* как бы array.push(...) */ } } } document.body.innerHTML = array.join(''); } Вот результаты: - Весь код ~ 296 мс - Без вывода в innerHTML ~ 66 мс - Без вывода в innerHTML + без сортировки ~ 12 мс |
Дело в рендеринге. Быстрее, чем Fx сможет нарисовать эту таблицу, показаться она не сможет.
Кстати, я тут бенчмарк небольшой устроил — вывод таблицы 10×1000 занял… Opera 10: 10 секунд Opera 10.50a: 17 секунд (они делают ее медленнее?!) Firefox 3.5: 24 секунды Chrome: 4 секунды IE8: 14 секунд |
а теперь сделай её фиксированой..
|
Цитата:
Кстати, был у меня интересный вариант в плане "усовершенствования"... В частности, на C++ такой вариант работал - это создание сразу 1000 строк, а потом скрывать те, которые не нужны... То есть создать один раз таблицу, а затем ее заполнять... Если строк всего 100 штук, то остальные 900 штук сделать display:none.. Как такой вариант? |
Цитата:
|
table-layout:fixed
|
Цитата:
Блин, почему же у лиса такой "не шустрый" JS движок... мне кажется, это должно быть одним из основных направлений разработки браузеров, т.к. все активней используется генерация страницы на компьютере пользователя... Вот запустил этот код на Chrome - 88 мс (!) против ~300 Firefox'а... капец... :blink: |
Часовой пояс GMT +3, время: 08:58. |