Avatar billede __ak Nybegynder
09. oktober 2008 - 12:58 Der er 22 kommentarer og
1 løsning

Manipulering af DOM med store mængder data

Hejsa alle

Jeg arbejder på en hjemmeside hvor jeg skal tilføje en masse data ind i en tabel via javascript.
Indholder bliver loadet og tilføjet til en tabel med jQuery's .load() funktion.
Problemet er at siden er utrolig lang tid om at loade DOM'en færdigt, så der går lang tid før man kan scrolle på siden og lign.

Så mit spørgsmål går i bund og grund ud på hvad man skal være opmærksom på når man skal manipulere med DOM'en med store mængder data via javascript - og hvordan man kan optimere det mest muligt.

//__ak
Avatar billede roenving Novice
09. oktober 2008 - 13:04 #1
Nu ved jeg ikke hvad jQuery udfører behind the scenes, men jeg har hørt udsagn om, at den bl.a. bruger innerHTML, og det, du skriver, får mig til at tro, at du serverer html ind i det, der skal loades ...

-- den absolut smarteste og hurtigste måde at gøre det på, er at servere data i json eller xml, i dette tilfælde er json så meget mere direkte at bruge, og så arbejde ud fra et (eller flere !-) template(s), som du kan klone og befolke med de data, du har !o]
Avatar billede __ak Nybegynder
09. oktober 2008 - 13:08 #2
Jeg kender kun json af navn, ved ikke hvad det er. Kan du fortælle lidt mere omkring det?
Avatar billede __ak Nybegynder
09. oktober 2008 - 13:11 #3
Men ja HTML koden bliver genereret i PHP før det serveres til jQuery.
Avatar billede __ak Nybegynder
09. oktober 2008 - 13:17 #4
Efter hvad jeg umiddelbart kan finde ud af omkring json så er det en måde at strukturere data som senere kan bruges i javascript - korrekt?
Avatar billede roenving Novice
09. oktober 2008 - 13:21 #5
Det er absolut spild af båndbredde og serverens tid og kræfter, da en opbygning af en json-streng vil kunne klares på en brøkdel af den tid, som serveren bruger på opbygning af html-koden (som jo altså også stort set altid vil være flere gange så stor som de rå data !-)

json (JavaScript Object Notation) er en måde at indlejre data i et objekt, som nemt kan aflæses fra javascript, f.eks.

{
  "1": {"id":1, "fornavn": "Peter", "efternavn": "Hansen"}
  "2": {"id":2, "fornavn": "Hans", "efternavn": "Pedersen"}
}

Hvis du så hælder de data ind i en variabel (f.eks. efter et ajax-kald !-):

var myJsonObject = eval( "(" + myAjax.responseText + ")" );

-- kan du få fat i det lige ud af landevejen:

for( x in myJsonObject ){
  alert(myJsonObject[x].fornavn);
}
Avatar billede __ak Nybegynder
09. oktober 2008 - 13:24 #6
Nu har jeg lige lynstuderet json mens jeg har siddet her og ventet på svar.
Men jeg har ikke helt luret hvorfor objektet skal igennem eval() før det kan tages i brug?

For ud fra mine egne test kan man sagtens tilgå dataen direkte fra objektet?

----------------
<script type="text/javascript">
var data = {
"navn" : "kim",
"efter" : "larsen",
"adresse" : { "vejnavn" : "roskildevej", "husnummer" : 12 },
"alder" : 9,
"telefon" : [1234578, 87654321]
}
alert(data.telefon[0]);
</script>
-----------------
er hvad jeg har prøvet med.
Avatar billede __ak Nybegynder
09. oktober 2008 - 13:25 #7
en anden ting jeg nok lige bør nævne er at det er vigtigere at siden loader hurtigt for brugeren end det er at serveren sparer på sine kræfter.
Avatar billede roenving Novice
09. oktober 2008 - 13:26 #8
Jepz, men hvis du f.eks. modtager det som en tekst fra et ajax-kald vil det ikke være et objekt før du har lavet eval-tingen !-)
Avatar billede roenving Novice
09. oktober 2008 - 13:27 #9
Du skal jo også sende mange gange så meget, så det vil også sløve load ...
Avatar billede __ak Nybegynder
09. oktober 2008 - 13:29 #10
[Du skal jo også sende mange gange så meget, så det vil også sløve load ...]
Jeg er lidt usikker på om den kommentar taler for eller imod?
Avatar billede roenving Novice
09. oktober 2008 - 13:37 #11
Hvis man f.eks. skal sende din datastruktur som færdige tabellinjer vil du have selve html'en som overhead, og den vil ganske ofte komme til at fylde mange gange så meget ...

-- og hvis data sendes med i dokumentet, vil man kunne starte indsætningen af data, når dokumentet ellers er loadet færdigt, og så vise en meddelelse om dette på den ene eller anden måde, og så fjerne den som det sidste man gør i et script, der indsætter !-)
Avatar billede __ak Nybegynder
09. oktober 2008 - 13:41 #12
Men er det realistisk at det vil være hurtigere end den nuværende metode.

Nuværende metode:
Får en lang streng med en masse HTML kode som indsættes i en tabel

Kommende metode:
Får alt data som en json objekt fra PHP og derefter oprettes og indsættes hver række i tabellen seperat via javascript.

Der kan ofte være tale om at det er 200 rækker i 9 kolonner der skal loades ind.
Avatar billede __ak Nybegynder
09. oktober 2008 - 13:42 #13
Nu fik jeg skrevet mit sidste spørgsmål mens du skrev dit sidste svar, så jeg kan næsten regne ud at svaret er "ja" ;o)

Jeg vil lige prøve at køre nogle forsøg og så vender jeg tilbage:-)

tusind tak for hjælpen indtil videre.
Avatar billede roenving Novice
09. oktober 2008 - 13:48 #14
Du laver en skjult tabel, med et template, hvor de ni kolonner er i en række ...

-- for hvert sæt af data kloner du rækken, befolker den med data, appender den til den tabel, de skal vises i, og sætter så eventuelle events på ...
Avatar billede __ak Nybegynder
09. oktober 2008 - 13:52 #15
Mht. at klone en tabel er jeg ikke helt sikker på jeg forstår hvad du mener.
Kan du forklare det hurtigt, eller give et link til det - vil jeg være taknemlig :-)
Avatar billede roenving Novice
09. oktober 2008 - 14:23 #16
F.eks.

<table id="template" style="display:none;">
  <tr>
    <td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>
  </tr>
</table>

<table id="herVisesTingene">
  <tbody></tbody>
</table>

-- og i scriptet:

...
var tpl = document.getElementById("template").getElementsBTagName("tr");
var target = document.getElementByID("herVisesTingene").getElementsByTagName("tbody");
var newNode, tds;
...

-- og i en løkke for hver række:

newNode = tpl.cloneNode(true);
tds = newNode.getElementsByTagName("td");
for(i=0;9>i;i++){  //kun som eksempel, du skal med garanti lave det lidt anderledes
  tds[i].appendChild(document.createTextNode(data[i]));
}
target.appendChild(newNode);

-- og derefter kan du så evt. sætte events på !-)
Avatar billede roenving Novice
09. oktober 2008 - 14:24 #17
Ups ...

...
var tpl = document.getElementById("template").getElementsBTagName("tr")[0];
var target = document.getElementByID("herVisesTingene").getElementsByTagName("tbody")[0];
var newNode, tds;
...
Avatar billede olebole Juniormester
09. oktober 2008 - 16:37 #18
<ole>

Du skal også tænke på, at serveren er mange gange så lang tid om at udskrive HTML, som den er om at udskrive samme data i en JSON-streng, hvis vi f.eks. taler PHP  ;o)

Der ligger et par småeksempler i tråden her:
    http://www.eksperten.dk/spm/817625

/mvh
</bole>
Avatar billede __ak Nybegynder
21. oktober 2008 - 11:25 #19
Jeg tror jeg går efter JSON løsningen, tak for svarene begge to - lægger i et svar?
Avatar billede olebole Juniormester
21. oktober 2008 - 18:17 #20
Det lyder fornuftigt. Jeg springer over i denne omgang, men du skal have tak for tilbudet  ;o)
Avatar billede roenving Novice
22. oktober 2008 - 15:47 #21
Velbekomme '-)
Avatar billede __ak Nybegynder
23. oktober 2008 - 13:49 #22
Tak for hjælpen :-)
Avatar billede roenving Novice
23. oktober 2008 - 16:05 #23
-- og tak for point ;~}
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester