Ревизия кода Ext JS/ GridView

    В свое время я прибывал в уверенности, что код
    js обычно не нужно писать так, чтобы он был
    наиболее оптимальным. «Клиентская часть» — говорил я, — «на сервер никак не
    повлияет, а посему, можно забить». К сожалению, оказалось, что это не совсем
    так.

    Данная статья содержит технические сведения. Если вы не понимаете о чем здесь написано, пожалуйста, не минусуйте.


    Началось все с использования библиотеки
    EXT JS на нашем проекте, а
    конкретно – виджета EditableGrid. Первоначально
    библиотека очень понравилась. Прежде всего своей объектно-ориентированной
    структурой. Проблемы начались позже. Забегая вперед скажу, что я все еще
    остаюсь поклонником EXTJS. Другой библиотеки, которая была бы такой же
    логичной и предлагала такие возможности я не знаю. Кроме того, следует
    отметить, что очевидные проблемы с производительностью начинались либо при
    большом количестве колонок в таблице, либо при большом количестве строк (про
    это разработчики библиотеки, впрочем, предупреждали).

    Про некоторые общие проблемы js вы можете прочесть здесь


     

    CSSCascadingStyleSheets – “а для чего слово
    каскадные?”


     

    На самом деле, на эту проблему мне указал наш
    html кодер (Женя, привет!
    J)

    Взгляните на css файл,
    который используется.

    Да, иногда стили специфицируются каскадно, но в
    подавляющем большинстве – НЕТ. «В чем же проблема» — спросите Вы. Для меня,
    как для программиста на java, проблемы не
    существовало до тех пор, пока я не внедрил грид на отверстанную страницу. И…
    у меня поплыли все стили. Грид выглядел ужасно. В чем дело? Дело в том, что на
    странице использовался общие css стили для всего
    проекта и они имели приоритет выше, чем те стили что описаны в
    grid.css. Почему
    так – я Вам не объясню. Я понимаю это как «чем точнее задан путь, тем выше
    приоритет у стиля», по крайней мере такой объяснение для меня работает. Есть
    еще модификатор «!important», но как мне рассказали, этим лучше не
    злоупотреблять. Надеюсь, учитывая количество профессиональных дизайнеров
    здесь, в комментариях будет объяснение.

    Итак, для себя я сделал вывод – использовать слово
    «каскадные» в определении CSS.

     

    Обновление CSSправил или первые тормоза

     

    Вышло так, что по требованиям в одном из гридов нужно
    было отображать 20 колонок. «Небольшая цифра» — как я думал. Оказалось, что
    нет.

    Ext.grid.GridViewиспользует забавный механизм для указания ширины колонок. При отрисовке
    создается узел <style> в который
    записываются пустые стили вида:

     

    #[идентификатор грида]
    .x-grid-col-[номер
    колонки] {

    2}

     

    Например:

     

    #grid-example .x-grid-col-0 {

    2}

     

     

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

     

    Ext.util.CSS.updateRule

     

    Надо сказать, что это не дешевая операция. А для 20ти
    колонок наблюдались заметные тормоза. Таким образом пришлось оптимизировать
    этот механизм, чтобы убрать ощутимую паузу, которая происходила с момента
    загрузки, до того момента, когда пользователь мог реально что-то сделать.
    Кроме того, загрузка процессора была 100%.

    Первоначально я генерировал не пустые стили, а сразу
    создавал заполненные с установленными значениями ширины
    (width). Прокатило, но потом и это пришлось
    убирать (см. ниже).

    Итак, для себя я сделал вывод – не использовать
    динамическое обновление таблиц CSS.

     

    Большое количество элементов или «ну сколько можно
    пихать?»


     

    Примерно такой код Вы увидите для каждой ячейке в
    гриде:

     

    <td class=«x-grid-col x-grid-td-1
    x-grid-cell-5-1» tabindex=«0»>

    <div class=«x-grid-col-1
    x-grid-cell-inner»>

    <div class=«x-grid-cell-text» unselectable=«on»>$31.61</div>

    </div>

    </td>

     

    Это только ОДНА ячейка. Получается, что кроме
    td, несчастному броузеру нужно будет держать еще
    как минимум два DOM объекта. Это занимает память
    и ресурсы.

    На мой взгляд, этого нужно избегать.

     

    Работа с DOMтаблицей или «ну вот оно и умерло»

    Надо отметить, что на форумах разработчики честно
    предупреждают о том, что работа с большим количеством строк будет тормозить и
    следует использовать разбивку на страницы. Но… пользователи всегда правы и
    страницы видеть не захотели. На самом деле, существует простой способ
    оптимизировать грид для работы с довольно большим количеством строк (у меня
    работает с 500 без тормозов).

     

    Какая была проблема? Дело в том, что
    GridView для представления использует таблицу.
    Операции по удалению/вставке/редактированию работали очень медленно, если
    количество строк было больше 20 (при количестве колонок больше 15ти). Оно и
    понятно, таблица – это не просто массив, а целый объект, которые нужно
    пересчитать/перерисовать. Кроме того, при изменении всех значений в какой-либо
    колонке (например, вычисляемая колонка, которая зависит от внешнего параметра)
    броузер просто умирал и в себя уже не приходил.

     

    Как это решилось? Из профайла я понял, что работа с
    большими таблицами (> 20-30 строк) занимает на порядок больше времени, чем
    с маленькими (< 20 строк). После этого я глянул на реализацию
    Google Spreadsheet. Вот
    что я там обнаружил: они не используют одну большую таблицу, а разбивают на
    много маленьких, которые располагаются одна под одной. Кроме того, ширина
    колонок задается не стилями, а, что более логично, через ширину первой строки
    с использованием стиля
    table-layout:
    fixed.

     

    Результат

    Таким образом, GridViewбыл переписан с учетом следующих правил:

    — Использовать КАСКАДНЫЕ стили

    — Не добавлять лишних элементов в
    DOM

    — Не использовать динамическое обновление стилей

    — Разбивать большие таблицы на несколько
    маленьких

    В результате я получил
    EditableGrid, который может работать с большим
    количеством строк.

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 21

      +2
      Спасибо за статью. В апстрим не пробовали концепции/патчи пропихнуть?
        0
        пока нету времени
          0
          спасибо за коммент
          +1
          А где же сам EditableGrid? :) Линка не вижу
            0
            и, кстати, вроде публикация на эту тему с этим решением уже была. Или я ошибаюсь?
              0
              подскажите где
                0
                вероятно я перепутал с ru-extjs... Хотя нет, ваша же статья «EXT js Grid - проблемы с производительностью» в «AJAX» http://www.habrahabr.ru/blog/AJAX/14307.…
                  0
                  вспомнил, там и файлик есть и я его пробовал. Ну и память... забывать стал ;)
                    0
                    да, моё :) но там были только оптимизации, связанные с колонками и динамическим обновлением правил css при загрузке страници. в итоге я вообще избавился от обновления стилей.
                0
                ой, сорри. да, на самом деле, нужно вставить линк на оригинальный грид. а своего пока я не выкладывал.
                0
                Актуальная информация, спасибо — та же проблема с 20+ колонками и 50+ строками…
                  0
                  [quote]Операции по удалению/вставке/редактированию работали очень медленно, если количество строк было больше 20 (при количестве колонок больше 15ти). Оно и понятно, таблица – это не просто массив, а целый объект, которые нужно пересчитать/перерисовать. [/quote]

                  Мда, верно тут было недавно сказано, про тормознутость современных систем: на 486 с DOS, такая операция бы летала.
                    +2
                    >> Данная статья содержит технические сведения. Если вы не понимаете о чем здесь написано, пожалуйста, не минусуйте.

                    Докатились... :(
                      0
                      внимание! при чтении данной заметки придется задействовать головной мозг! при отсутствии головного мозга разрешается поставить посту минус.
                        0
                        для чтения данной статьи требуется не быть мудаком. если вы все таки мудак, то, пожалуйста, не минусуйте. :)
                      0
                      >> я все еще остаюсь поклонником EXT JS. Другой библиотеки, которая была бы такой же логичной и предлагала такие возможности я не знаю.

                      А на чём написан проект? Если на java, то GWT даёт максимальные возможности использовать ООП при написании аяксовой клиентской части (в том числе и полноценное unit-тестирование). А некоторые из многочисленных библиотек виджетов для JSF (например, IceFaces) вполне покрывают возможности EXT JS.

                      Это не исключает, впрочем, проблем с большими гридами у них у всех :) Но, имхо, проще и приятнее делать ревизию java-кода, чем javascript.
                        0
                        мы используем java. но GWT решено было не использовать из-за рисков: нет реальных сделанных проектов на GWT в компании, кроме того, GWT генерит странные странички и мы немножно испугались :) , что не всегда сможем нарисовать то, что уже есть отверстанное на прототипе.
                        0
                        Принимаю участие в разработке интерфейса пользователя платежной системы ОДНО.КАСАНИЕ который выполнен на как 100% HTA под IE6, работает в режиме самообслуживание более чем на 500 терминалах. Проекту 2 года.

                        Более 5000 строк JSCript кода. Используется технологии ActiveX (для работы с оборудованием), AJAX (для взаимодействия с сервером), DOM (для визуального интерфейса пользователя) и ряд других менее значимых.

                        На протяжении проекта решали массы задач, начиная с каскадных стилей и скорости работы HTA в IE, заканчивая Memory leak в IE при активном использовании DOM-модели.

                        Выбранная технология при встрече с определенными проблемами, типа Memory leak разочаровывала, но в целом, HTML позволяет сделать более красочный и удобный интерфейс-пользователя, интерпретирующий язык позволяет производить более оперативную разработку кода.

                        Flash-технология рассматривалась, но была отвергнута из-за компилятора, меньшего количества доступных профессиональных разработчиков и некоторых сложностей при работе с оборудованием.

                        HTA - отличная технология, но не всегда, например, сейчас мы ее, наверное отклоним, при выборе технологии для нового проекта, т.к. интерпретирующая форма с открытым кодом хороша, но если HTA установлен у пользователя-человека, то он может внести изменения в код, которые могут быть злонамерянными. Конечно, можно предупредить эти возможности, вот например, использовав технологию "Asynchronous Pluggable Protocol".
                          0
                          пробуйте WPF, он крут, особенно в этой области ;)
                            0
                            шо такое WPF ?
                          0
                          Когда мы реализовывали редактируемый датагрид в одном проекте — мы не использовали таблицы вообще. В IE таблицы работают ужасно медленно.


                          <div class="row">
                          <div class="col col-price"><span>$13.68</span><input value="$13.68"/><i/></div>
                          </div>


                          Как-то так :) Последний тэг i используется для плавного фэйда в конце ячейки :)

                          Only users with full accounts can post comments. Log in, please.