poniedziałek, 11 maja 2009

Duża ilość elementów w GWT

GWT generalnie jest fajną platformą, ale niestety sam javascript nie jest najszybszy. Okazuje się, że dodanie dużej ilości elementów załadowanych z bazy i wstawienie ich do tabeli stanowi spory problem. Na przykład, ładując 500 elementów i wstawiając je do FlexTable albo do Grid, strona ładuje się dość długo, szczególnie na słabszych komputerach. Ponieważ zależało mi na szybkości ładowania elementów, postanowiłem temat zbadać i spróbować coś z nim zrobić.

Zarówno Grid jak i FlexTable, a w zasadzie również VerticalPanel oraz HorizontalPanel są oparte o tablice. Tablica jako taka jest elementem dość skomplikowanym w budowie, a dodatkowo GWT dodaje dość dużo kodu sprawdzającego, warunkowego oraz debugu. Cały ten kod powoduje, że Całość działa o wiele wolniej.

Ponieważ efekt zbliżony do tabeli można osiągnąć również przy pomocy arkusza styli CSS oraz zwykłych div, postanwoiłem spróbować przerobić standardową tabelę na pseudotabelę zrobioną przy pomocy DIV z flow:left; GWT posiada kilka elementów które mi na to pozwalają. Pierwszy z nich to FlowPanel który jest tłumaczony na DIV i pozwala na dodanie innych komponentów do środka. Drugi to Label, SimplePanel oraz Hyperlink pozwalające na dodanie innych elementów.

Są dwie zasady jeżeli chcemy osiągnąć efekt właściwy.
  • Wszystkie elementy muszą mieć na stałe ustawioną wysokośc oraz szerokość
  • Sumaryczna szerokość elemtnów wewnątrz "tabeli" musi być równa szerokości "tabeli"
Wygenerowany kod będzie wyglądał tak:


<div style="width:200px;display:block;">
<div style="float:left;width:100px;height:20px;">Nazwa 1</div>
<div style="float:left;width:100px;height:20px;">Wartosc 1</div>
<div style="float:left;width:100px;height:20px;">Nazwa 2</div>
<div style="float:left;width:100px;height:20px;">Wartosc 2</div>
</div>


Efekt wyglada tak:
Nazwa 1
Wartosc 1
Nazwa 2
Wartosc 2


Z wygladu mamy tabele, a wiec to o co chodzi.

To samo mozna osiagnac w GWT, tylko style nalezy przeniesc do arkusza styli.

FlowPanel content = new FlowPanel();
Label l1 = new Label("Nazwa 1");
Label w1 = new Label("Wartosc 1");
Label l2 = new Label("Nazwa 2");
Label w2 = new Label("Wartosc 2");

content.setStyleName("table_main");
l1.setStyleName("table_field");
l2.setStyleName("table_field");
w1.setStyleName("table_field");
w2.setStyleName("table_field");

content.add(l1);
content.add(l2);
content.add(w1);
content.add(w2);

initWidget(content);

STYLE:

.table_main{
width:200px;
display:block;
}

.table_field{
float:left;
width:100px;
height:20px;
}



Ponieważ FlowPanel nie wymaga dużo sprawdzeń i inicjalizacji to jego utworzenie jest bardzo proste. Dodanie kolejnych elementów nie wymaga tworzenia struktury drzewa, tak jak w przypadku kontenerów opartych o tablice. Dzięki temu, ilość kodu javascript który musi zostać wykonany jest dużo mniejsza, a co za tym idzie jest mocno zauważalny wzrost wydajności tego rozwiązania w stosunku do standardowej tabeli.
Wada tego rozwiązania jest taka, że jednak nie jest to standardowa tabela, a co za tym idzie, nie ma możliwości skalowania tabeli. Na szczęście w większości dzisiejszych layoutów wielkości są zablokowane na stałe, a więc ten problem dotyczy niewielkiej ilości przypadków.

PS. Nie mieżyłem wzrostu wydajności, ale wzrost wydajności był zauważalny bez mieżenia. Strona oparta o tabele ładowała się wolno. Strona oparta o to rozwiązanie ładowała się w zasadzie odrazu.

0 komentarze:

Prześlij komentarz