08. maj 2010 - 20:11Der er
24 kommentarer og 1 løsning
table rows oprettet med javascript i DOM gør IE langsom
Jeg opretter 500 tablerows med clonenode(true).
Det virker fint nok.
Problemet er, at det gør Internet Explorer ekstremt langsom når jeg aktiverer JQuery plugin'et "TableSorter" på tabellen. Vi snakker 40 sekunder istedet for 4 sekunder i safari, chrome og firefox.
Det mærkværdige er, at når jeg laver tabellen fra serverside med asp.net dataBind() har IE ingen problemer og bruger igen kun 4 sekunder.
Men jeg er nødt til at lave tabellen fra klient siden pga andre performance issues.
Hvordan får jeg Internet Explorer til at lege med uden at være så langt bagefter? Hvorfor er der forskel på en html tabel oprettet i html fra serveren og en tabel oprettet i DOM cachen ?
har du set memory-forbruget på ie, når du har oprettet de tablerows?
Synes godt om
Slettet bruger
08. maj 2010 - 21:11#2
Præfabrikeret ~ stor dum HTML-fil (caches) med alle de DIV'er du skal bruge, stylet display:none
Browserens rendering-engine æder flade html filer hurtigere end bedstemor på youghurt = Ingen scriptet memory alokering, hverken på server eller klient.
Så kan du bare aktivere og positionere de 5-10 elementer (ud af 1089) du har brug for til an start med 4-5 linjers tothepoint script
Splazz: memory forbruget er det samme for IE og Firefox og safari, 30MB forøgelse når tabellen laves i javascript.
T4NKR: Klart underholdende svar. Men som sagt kan jeg ikke lave en stor html fil pga andre performance issues. Og for chrome, safari og ff er der ingen forskel på performance om jeg laver html eller ej.
Jeg vil have IE til at kunne det samme som de andre, der må være noget jeg kan gøre. Det kan ikke passe IE er 10 gange (ja, ti gange) så langsom, helt nøjagtigt.
Det passer heller ikke nødvendigvis. Der er mange måder at gøre den slags på - og de performer meget forskelligt i de forskellige browsere. Hvis du vil have en forklaring, må du vise, hvad du gør.
Hvis du én ad gangen indsætter rækker i en tabel, mens den vises i browseren, vil du misbruge resourcer - big time!
I stedet kan du oprette et dokumentfragment - indsætte rækkerne i det - og slutte af med at indsætte fragmentet i tabellens tbody. En anden metode er at opbevare tbody'en i hukommelsen - indsætte rækkerne - og derefter indsætte tbody'en i tabellen.
- men lad os se, hvad du gøre. Så kan vi højst sandsynligt optimere din kode =)
Tabellen vises ikke i browseren, mens rækkerne indsættes. den ligger i en tab som kun vises hvis man klikker på den senere.
Husk på at tidsproblemet ikke er når jeg laver tabellen, men når jeg aktiverer jquery.tablesorter på den. $(document).ready(function() { $('#Grid0').tablesorter(); } ); Og det virker fint i de andre browsere plus IE hvis det er html.
Derfor tror lidt på den model du forslår med at lave et dokumentfragment og indsætte i tbody. Fordi det lader til at flade html filer er "bedstemor på yoghurt" for IE. Jeg kunne bare godt tænke mig at vide hvorfor......
Her er koden:
function populateSubjectGrid() { /// <summary>Location:PHONER7_Populate</summary> /// <param name=""></param> /// <returns></returns>
for (var z = 0; z < assignment.Subjects.anyType.length; z++) { subject = assignment.Subjects.anyType[z]; grid = grids[0]; newRow = grid.tBodies[0].rows[0].cloneNode(true); grid.tBodies[0].appendChild(newRow);
Nårhh ... jamen, det er ikke usandsynligt. Der er masser af uhensigtsmæssigheder i jQuery, så det er langt fra utænkeligt, at tabelsorteringen er kluntet udført. De gange, jeg har lavet tabelsortering med JS, har jeg ikke haft nævneværdige problemer med IE - heller ikke ved ret store tabeller.
Jeg forstår ikke din metafor med flade filer, IE, bedstemødre og syrnet mælk, men årsagen til at tbody- og dokumentfragment-tricket performer bedre (og det gør det i alle browsere), er temmelig logisk, da browseren så kun skal rendere én gang - i stedet for efter hver række
Ikke umiddelbart. Der er masser af måder at traversere tabellen og udføre DOM-handlinger på. Nogen performer godt - andre performer elendigt.
jQuery er en stor, kompleks suppe, så jeg agter ikke at finde de steder, der gør, at IE performer så dårligt. Jeg kan kun anbefale at skrive funktionen selv =)
Jeg har ingen anelse om, hvad du gør, så det er komplet umuligt for mig at sige, hvad der er skyld i problemet - men der er helt sikkert tale om dårlig kode i et eller andet led.
Der er ikke noget dårlig kode. En sortering kan ikke sortere hvis den ikke kan læse værdierne i cellerne, så man kommer ikke udenom var x=cell.innerHTML.
var x=cell.innerHTML tager for lang tid for IE i scenariet beskrevet (tabellen oprettet på klienten).
var x=cell.innerHTML tager IKKE for lang tid for IE når tabellen er oprettet på serveren.
Det er fakta. Jeg forstår bare ikke hvorfor og hvordan jeg løser problemet.
Du kan bruge valid DOM (nodeValue). Du behøver ikke bruge innerHTML. Men hvem siger, det skulle være innerHTML, der sinker processen?
Og hvem har bildt dig ind, der ikke er noget dårlig kode? At sortere en tabel med 500 rækker, som er loaded med DOM, bør ikke tage væsentligt over 1,5 sekund på en gennemsnits PC. Tager det længere tid, er der tale om kode, der performer dårligere end nødvendigt - altså er der tale om dårlig kode =)
1. "Men hvem siger, det skulle være innerHTML, der sinker processen?" - Det påstår jeg selvsikkert, fordi hvis jeg istedet skriver: var x="" tager det igen 4 sek istedet for 40 sek.
2. Hvad er DOM (nodeValue) ?
3. Lad os bare sige der er dårlig kode et sted i den forstand at det ikke virker som det skal. Men du mente jo den dårlige kode stammede fra jquery plugin'et og det kan jeg udelede af 1. at det ikke gør.
2) Du bruger selv DOM: newRow.cells[8].childNodes[0].nodeValue = [...] Prøv f.eks: x = cell.firstChild.nodeValue
3) Nej, jeg mener, at jQuery indeholder en del skidt kode - og jeg mindes ikke, jeg nogensinde har rost dig for god kode.
Uanset, om du bruger DOM eller innerHTML, så er der noget i koden, der stinker slemt, hvis en sortering af 500 rækker tager 40 sekunder. Om du så vælger at kalde det dårlig eller elendig kode =)
"Det må give et andet resultat end at bruge" >> Nej, det er præcist det samme. Jeg henter bare data (det, du beskriver med [random string]) fra et js-array. Et array med 500 elementer - bestående af et array med 8 strenge (én til hver celle i en række).
Når jeg opretter rækkerne, traverserer jeg array'et. For hvert element (array i array'et) kloner jeg en række - fylder de otte celler i rækken med data fra array'et. Rækkerne indsættes efterhånden i et dokumentfragmet, som jeg til sidst indsætter i tabellens tbody-element.
Jeg argumenterer ikke spor aggressivt. Til gengæld er det desværre ikke længere politisk korrekt at være ligefrem og sige tingene, som de er.
Det kan godt være, det ville føles lidt mere lækkerligt, hvis jeg ikke kritiserede din kode og fortalte dig, hvor dårlig den er - men når du skriver dårlig kode, er det ikke min opgave at få dig til at føle dig lækker.
Wellness er Ole Henriksens branche. Jeg hedder Clausen, og min branche handler om god kode. Vil du føle dig lækker, henvender du dig til hr. Henriksen. Jeg kan kun lære dig noget om god kode - og det kan man ikke ved at smøre dig ind i utroværdigt flødeskum. Tag det i stedet som en gave, når folk fortæller dig, du har lavet noget møj. Det er den eneste måde, du kan lære at lave noget godt ;o)
"Når jeg opretter rækkerne, traverserer jeg array'et. For hvert element (array i array'et) kloner jeg en række - fylder de otte celler i rækken med data fra array'et. Rækkerne indsættes efterhånden i et dokumentfragmet, som jeg til sidst indsætter i tabellens tbody-element."
Hvis du vil genskabe tidsrøveren og finde den ultimative sandhed er du nødt til at lave tabellen på den nøjagtig samme måde som jeg gør i koden ovenfor. Dokumentfragmentet var en mulig løsning, ikke en beskrivelse af problemet. Endvidere er selve tabellen oprettet fra serveren, med en enkelt række indsat fordi ellers vil asp.net ikke lave thead og tbody. Kan blive lidt af en kradser at genskabe, ja. Må indrømme jeg nødigt vil koge det ned til et bevis fordi jeg har nogle tidsfrister at overholde.
Men når alle celler (500*8) så læses med innerHTML tager det 40 sekunder. Hvis den påstand er forkert, så er 2+2 også lig 5.
Måske har du svaret og årsagen nu, det håber jeg. Måske nægter du at tro på det og så bliver jeg jo nødt til at bevise det.
Jamen, hvorfor skulle du bevise noget? Det skyldes ikke brugen af innerHTML, men måden innerHTML bruges på.
Naturligvis vil asp.net ikke tillade tomme theads eller tbodies - de er jo invalide i forhold til standarden. Jeg er underlagt præcis samme regler og koder derfor også på dette punkt på samme måde. Problemet ligger udelukkende i scriptkodens kvalitet.
Jeg har lavet to forskellige testdokumenter. Det første bruger et dokumentfragment at indsætte i - og det bruger NODE.firstChild.nodeValue til at læse under sorteringen: http://gulfeber.dk/gridtest/
Som du kan se, er der yderst marginal forskel på tiderne i de to dokumenter. Det, der skaber de store forskelle og den dårlige performance i dit dokument handler ikke om valget af DOM metoder, men om resten af din/jQuery's kode.
PS: Du kan sortere ascending eller descending - det skifter ved hvert andet klik i head elementet.
Bemærk, at de tre sidste rækker i Kolonne #1 indeholder æ, ø og å - og at de bliver sorteret korrekt. Noget JS ikke umiddelbart gør, men jeg ved ikke, om jQuery's sorteringsmekanisme tager højde for skandinaviske tegn.
Det eneste jeg gjorde var at ændre cell.firstChild.innerHTML til cell.firstChild.nodeValue i jquery.tablesorter plugin'et. Så kører alt helt smooth, der er ingen ventetid.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.