2011-12-27 4 views
16

Я работаю над webapp для управления данными о продуктах, в которых данные продукта отображаются в таблице с 4 столбцами (номер индекса, SKU, описание продукта и запас).Медленный отклик при большой таблице HTML

Проблема, с которой я столкнулся, заключается в том, что когда таблица стала очень большой (> 1000 строк), страница очень лаги, особенно когда я наводил указатель на строку (я определил tr:hover в CSS).

Я попытался это исправить, отображая данные частично и загружать больше, когда пользователь прокручивает вниз, с помощью некоторых JavaScript:

if (tablesDIV.scrollTop> = tablesDIV.scrollHeight - (tablesDIV.clientHeight + 80)) { 
    /*...*/ 
} 

Это дало хорошие результаты, но это не позволяет достичь последнюю строку, нажимая Конец, и когда загружено значительное количество строк, страница снова была ломаной.

Есть ли решение этой проблемы?

EDIT: код CSS, связанный с таблицей.

#tables thead th{border-bottom:1px solid #CCC;background-color:#F5F5F5;background-image:-webkit-gradient(linear,left top,left bottom,from(#F5F5F5),to(#F1F1F1));background-image:-moz-linear-gradient(top,#F5F5F5,#F1F1F1);background-image:-o-linear-gradient(top,#F5F5F5,#F1F1F1);background-image:linear-gradient(top,#F5F5F5,#F1F1F1);font-weight:700;cursor:default} 
#tables tbody th{font-weight:700;text-overflow:none} 
#tables tbody tr{background:#FFF;cursor:pointer} 
#tables tbody tr:nth-child(even){background:#F8F9FC} 
#tables tbody tr:hover{background:#CDE} 

EDIT2: Demo.

Демо: http://jsfiddle.net/4dpGz/

+0

1000 рядов, похоже, не так много. Вы говорите, что это нормально, если вы удалите эффект tr: hover? – nnnnnn

+3

pagination man!зачем загружать 1000 строк? – Joseph

+0

Вы уверены, что это связано с некоторой неэффективностью в стеке переднего плана? Не тогда, когда, например, вы загрузили данные из БД? – moey

ответ

17

Первое, что замедляет ваш цикл: .insertRow(). Вы делаете это в верхней части своего цикла, а затем добавляете к нему ячейки. После добавления строки и после добавления каждой ячейки браузер выполняет вычисления макета.Вместо этого используйте .createElement(), а затем .appendChild() в конце вашего цикла.

Демо: http://jsfiddle.net/ThinkingStiff/gyaGk/

Заменить:

row = tableContent.insertRow(i); 

С:

row = document.createElement('tr'); 

и добавить в конце вашего цикла:

tableContent.tBodies[0].appendChild(row); 

Это будет решать ваша скорость загрузки. Что касается зависания, у вас слишком много правил CSS, влияющих на ваши элементы tr и td с использованием селекторов меток. Я удалил несколько и использовал несколько классов, и подсветка курсора выполняется намного быстрее. В частности, я заметил, что overflow: hidden на элементах td значительно замедлил его. Попробуйте объединить некоторые из ваших правил, используя более простые селектор и добавив классы в элементы для более быстрой обработки CSS. Во время зависания многие вещи должны быть пересчитаны механизмом компоновки, и чем меньше правил CSS, тем лучше. Один из примеров, который я видел в вашем коде, был #tables tbody tr, когда в таблице было только одно tbody. #tables tr было бы достаточно. Лучше, чем любой из них - класс. Я использовал .row в своей демонстрации.

Лучшие практики от Google Page Speed:

  • Избегайте селекторы потомков: table tbody tr td
  • Избегайте избыточных предков: body section article (body никогда не требуется)
  • Избегайте универсальных (*) селекторов: body *
  • Избегайте тегов селекторы в качестве ключа (самый правый): ul li
  • Avoi d ребенок или смежные селекторы: ul > li > a
  • Избегайте чрезмерно квалифицированных селекторы: form#UserLogin (# уже конкретный)
  • Сделайте свои правила как можно конкретнее (класс или идентификатор).
+0

Вау! Это действительно быстро! Спасибо! Перед использованием insertRow я использовал innerHTML для этих случаев, но IE не добавлял строку, я искал причину и, согласно Microsoft, потому, что я не могу использовать innerHTML для встроенного элемента, и мне нужно использовать insertRow для этого случая. –

+3

Я еще оптимизировал, добавив document.createDocumentFragment() перед циклом и добавив tr в documentFragment, а затем добавлю все в таблицу после цикла. Я также заметил, что tr: nth-child (even) очень медленный, поэтому я сделал то же самое с javascript и классом CSS. Это моя демонстрация: http://jsfiddle.net/4dpGz/3/ –

+0

@ Fong-WanChau Отличная идея! Сверх быстрый! – ThinkingStiff

1

Таблицы должны быть загружены и оказывать в полном объеме, прежде чем они будут отображаться, появляясь занять больше времени, чтобы отобразить. Это упущение все зависит от мощности процессора:

Are large html tables slow?

Для количества строк у вас есть Я удивлен, что вы видите какой-либо заметной задержки, хотя вы можете попробовать несколько вещей здесь, чтобы помочь нам помочь вам из:

  • удалить градиентного фон (как они оказываемый браузер)
  • формы постраничных данных
  • вывода образуют ряды в кусках (скажем, 200 строк за один раз)
  • удаляет все css help?
  • указать точную ширину + высоту по строкам таблицы, клетки
+1

Спасибо, что ответили на этот пост, я прочитал этот пост, прежде чем я разместил здесь, но я Думаю, я не могу разбивать этот тип данных. –

3

если таблица имеет регулярные колонки (без Colspan и/или RowSpan) вы можете улучшить чуток время рендеринга применяя table-layout:fixed свойство:

MDN: https://developer.mozilla.org/en/CSS/table-layout

Под «фиксированного» способом компоновки, вся таблица может быть представлена ​​как только первая строка таблицы была загружена и проанализирована. Это может ускорить время рендеринга по методу «автоматического» макета, но последующее содержимое ячейки может не соответствовать ширине столбцов.

+0

Спасибо, что ответили на этот пост, я уже знаю об этом, и 'table-layout: fixed' уже применяется. Вы можете увидеть демо в моем обновленном сообщении. –

0

Я нахожу, что класть большой стол в div, лучше использовать setTimeout. Это, по-видимому, значительно ускоряет его в Chrome при хранении таблицы в глобальном var, а затем вызывает функцию в setTimeout.

setTimeout("setTable(tdata)",1); 

function setTable(d) { 
     $("#myDiv").html(d); 
} 

Cheers! B55

3

Также, как и в любом элементе HTML в хроме, добавление «transform: rotateX (0deg)»; элемент таблицы заставляет ускорить аппаратное ускорение, ускоряя прокрутку значительно (если это проблема).

+0

Можете ли вы немного объяснить, почему это работает? –

+0

Не совсем :) Но вот ссылка, которая делает :-P [Прокрутка производительности] (http://www.html5rocks.com/en/tutorials/speed/scrolling/) –

+0

Вся моя страница была лагги, но этот простой трюк разрешил все , –

0

Если вы работаете с очень большими таблицами (скажем, 5000 или даже 500 000 строк), я рекомендую крошечный плагин под названием Clusterize. Вам даже не нужно использовать jQuery. Идея похожа на ленивые загрузки изображений, и на практике она работает очень хорошо.

Смежные вопросы