[JS] 500 KB aan menu opbouwen`

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • UltimateB
  • Registratie: April 2003
  • Niet online
Ik moet dynamisch een menu opbouwen van een Google Maps appllicatie. Dit menu wijzigd zich elke keer als de kaart wordt versleept. Nu ben ik op zoek naar een manier om dit efficient te doen. Normaliter gebruik ik een eval op een Ajax request die de data op haalt. Deze data is JSON met daarin een object met HTML. Niet echt efficient dus.

Nu zijn er verschillende manieren om dit sneller te maken in mijn ogen. Of het menu wordt opgebouwd met native dom op basis van de gegevens die beschikbaar zijn. Of misschien moet ik alleen een eval los laten op het relevante gedeelte van de data, al kan ik mij herinneren dat IE altijd een eval doet op data die via innerHTML wordt ingevoegd.

Een demo van een beta versie vind je hier; http://demo.geostart.nl/.

Heeft iemand ervaring met dergelijke dom manipulaties, of tips wat ik zou kunnen doen?

"True skill is when luck becomes a habit"
SWIS


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 09:33

crisp

Devver

Pixelated

Als je enkel een stuk HTML opstuurt, waarom wrap je dat dan nog in JSON? Dan kan je net zo goed gewoon de platte HTML opsturen en element.innerHTML = requestObject.responseText doen toch? Scheelt je het omzetten van de JSON naar een javascript object (wat afhankelijk van je JSON implementatie bij grote responses behoorlijk kostbaar kan zijn).

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

offtopic:
Dat popupje "Er worden X locaties niet getoond" na elke bewerking (zoomen, verplaatsen) is schijtirritant, ik hoop dat dat voor debugging is? En ja, ik zie dat je hem uit kan schakelen.

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • UltimateB
  • Registratie: April 2003
  • Niet online
crisp schreef op vrijdag 26 juni 2009 @ 09:50:
Als je enkel een stuk HTML opstuurt, waarom wrap je dat dan nog in JSON? Dan kan je net zo goed gewoon de platte HTML opsturen en element.innerHTML = requestObject.responseText doen toch? Scheelt je het omzetten van de JSON naar een javascript object (wat afhankelijk van je JSON implementatie bij grote responses behoorlijk kostbaar kan zijn).
Probleem is dat de data bestaat uit zowel echt JS data als uit HTML. Een mogelijkheid zou zijn om de HTML po basis van de data op te bouwen inplaats van met smarty server side. Dit zou in ieder geval een hele sloot aan data schelen bij de requests. Maar dan zal ik via dom, of view, via een een string het menu clientside moeten opbouwen.

Dit zou wel lastig zijn, maar stel ik bouw een menu op met een element of 100, hoe zou dat presteren.
CodeCaster schreef op vrijdag 26 juni 2009 @ 09:53:
offtopic:
Dat popupje "Er worden X locaties niet getoond" na elke bewerking (zoomen, verplaatsen) is schijtirritant, ik hoop dat dat voor debugging is? En ja, ik zie dat je hem uit kan schakelen.
We live to annoy. Nee, dit is een testversie ja. Mag de huidige versie niet laten zien namelijk.

"True skill is when luck becomes a habit"
SWIS


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 09:33

crisp

Devver

Pixelated

UltimateB schreef op vrijdag 26 juni 2009 @ 10:09:
[...]


Probleem is dat de data bestaat uit zowel echt JS data als uit HTML. Een mogelijkheid zou zijn om de HTML po basis van de data op te bouwen inplaats van met smarty server side. Dit zou in ieder geval een hele sloot aan data schelen bij de requests. Maar dan zal ik via dom, of view, via een een string het menu clientside moeten opbouwen.
Ik zag het bij het uitpluizen van je Ajax requests ja :P

In ieder geval kan ik je alvast voorspellen dat het menu met DOM methods opbouwen zeker trager zal zijn dan mbv innerHTML.

Als de grootte van de respons een bottleneck is (gelukkig gebruik je al HTTP compressie, dus dat scheelt al behoorlijk) probeer dan de HTML zo minimalistisch mogelijk te houden: whitespace strippen, optionele end-tags (</li> bijvoorbeeld) weglaten, boolean atributes gewoon als boolean schrijven (gewoon 'selected' ipv 'selected="selected"'), zoveel mogelijk quotes weglaten voor attribute-values en voor zover mogelijk zo min mogelijk classes gebruiken en dat oplossen dmv specifiekere selectors in CSS.

Ik zag overigens ook dat je gewoon puur eval gebruikt voor je JSON; probeer in ieder geval te testen op de aanwezigheid van de native JSON.parse() method, da's weer een stuk sneller. IE8 heeft er al support voor en Firefox 3.5 krijgt het ook :)

Verder is het een kwestie van profilen: kijken waar precies veel tijd in gaat zitten en je dan daar op focussen qua verbeteringen.

[ Voor 6% gewijzigd door crisp op 26-06-2009 10:24 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • UltimateB
  • Registratie: April 2003
  • Niet online
crisp schreef op vrijdag 26 juni 2009 @ 10:16:
[...]

Ik zag het bij het uitpluizen van je Ajax requests ja :P

In ieder geval kan ik je alvast voorspellen dat het menu met DOM methods opbouwen zeker trager zal zijn dan mbv innerHTML.

Als de grootte van de respons een bottleneck is probeer dan de HTML zo minimalistisch mogelijk te houden: whitespace strippen, optionele end-tags (</li> bijvoorbeeld) weglaten, boolean atributes gewoon als boolean schrijven (gewoon 'selected' ipv 'selected="selected"'), zoveel mogelijk quotes weglaten voor attribute-values en voor zover mogelijk zo min mogelijk classes gebruiken en dat oplossen dmv specifiekere selectors in CSS.

Ik zag overigens ook dat je gewoon puur eval gebruikt voor je JSON; probeer in ieder geval te testen op de aanwezigheid van de native JSON.parse() method, da's weer een stuk sneller. IE8 heeft er al support voor en Firefox 3.5 krijg het ook :)
Ik heb met een profiler gekeken en het grootste gedeelte van de tijd is hij bezig met eval. Een beetje afhankelijk van de hoeveelheid die geupdate wordt. Ik zou inderdaad even moeten controleren op native JSON implementatie.

Ik wou dat er een CDATA tag was voor JSON zodat hij niet geparsed wordt daar. :)

Ik heb recentelijk in ieder geval de HTML al gesplitst om na de eerste load alleen nog de veranderde hoodfgroepen te updaten met innerHTML. Dat scheelt al wat in veel gevallen. Ik zal inderdaad even kijken of ik een "packed" versie van de HTML kan maken. Kijken wat dat helpt.

Probleem is ook wel een beetje dat meerdere mensen het moeten onderhouden. Dit kan een probleem worden als ik de template ga proberen zo klein mogelijk te houden. Misschien maar even op zoek naar een script die dat kan.

"True skill is when luck becomes a habit"
SWIS


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 09:33

crisp

Devver

Pixelated

Ik wou dat er een CDATA tag was voor JSON zodat hij niet geparsed wordt daar.
Er wordt daar niets geparsed hoor; het is gewoon een string en blijft dat ook als de data van JSON is omgezet naar een javascript object. Het is alleen wat groot waardoor eval() meer tijd nodig heeft :P

Over het algemeen is IE behoorlijk rap in het evallen van grote chunks, maar Firefox weer een stuk minder. JSON.parse() gebruiken voor Firefox 3.5 straks zal dan ook wel behoorlijk schelen denk ik.

En kijk eens naar event delegation in plaats van al die inline eventhandlers ;)

[ Voor 17% gewijzigd door crisp op 26-06-2009 11:07 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • UltimateB
  • Registratie: April 2003
  • Niet online
Volgens mij zou een event die aan een dom element zit door middel van event delegation niet persistent zijn als ik innerHTML doe. Ten minste dat heb ik altijd gedacht. Daar zou dit niet een hoop geheugen lekken tenzij ik us na elke update alle listeners clear?

Kan het mis hebben tho.

Verder heb ik even een "beejte" geschoond, de HTML is nu uncompressed nog "maar" 241kb. Ook even een korte versie gemaakt van de objecten die worden aangeroepen, dus g. in plaats van oGeoStart.

Buiten het menu ben ik het wel met je eens aan de ene kant. Aan de andere kant maakt dat het iets minder goed leesbaar. Ik zet het iig in de devtrack, misschien voor op een laten moment ;)

"True skill is when luck becomes a habit"
SWIS


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 09:33

crisp

Devver

Pixelated

UltimateB schreef op vrijdag 26 juni 2009 @ 11:19:
Volgens mij zou een event die aan een dom element zit door middel van event delegation niet persistent zijn als ik innerHTML doe. Ten minste dat heb ik altijd gedacht. Daar zou dit niet een hoop geheugen lekken tenzij ik us na elke update alle listeners clear?
Niet als je de events op de container zet ;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • UltimateB
  • Registratie: April 2003
  • Niet online
Ok daar had is niet even snel schuin overheen moeten lezen, dacht dat dat puur de scheiding was, niet het tja, delegeren lol :) Klinkt inderdaad erg goed. Dat zou echt heel veel kunnen schelen.

[ Voor 20% gewijzigd door UltimateB op 26-06-2009 12:17 . Reden: +regeltje ]

"True skill is when luck becomes a habit"
SWIS


Acties:
  • 0 Henk 'm!

Verwijderd

Kun je de request niet splitsen in twee request? Hoef je de HTML niet door eval te halen. Overhead van die ene extra request hoeft niet groot te zijn.

Bedoel je met DOM manipulatie dat je zelf met appendChild e.d. aan de slag gaat? Kijk eens naar kant & klare treeviews zoals deze van Yahoo. Stylen is voor je menu misschien een uitdaging maar het aanpassen zelf is erg eenvoudig.

Iedere keer de lijst ophalen bij het verslepen van de kaart werkt niet lekker. Wanneer ik op een icoon aan de rand van de kaart klik verschuift de kaart om de popup te tonen wat dus zorgt voor het opnieuw ophalen van de lijst.

Acties:
  • 0 Henk 'm!

  • UltimateB
  • Registratie: April 2003
  • Niet online
Verwijderd schreef op vrijdag 26 juni 2009 @ 18:03:
Kun je de request niet splitsen in twee request? Hoef je de HTML niet door eval te halen. Overhead van die ene extra request hoeft niet groot te zijn.

Bedoel je met DOM manipulatie dat je zelf met appendChild e.d. aan de slag gaat? Kijk eens naar kant & klare treeviews zoals deze van Yahoo. Stylen is voor je menu misschien een uitdaging maar het aanpassen zelf is erg eenvoudig.

Iedere keer de lijst ophalen bij het verslepen van de kaart werkt niet lekker. Wanneer ik op een icoon aan de rand van de kaart klik verschuift de kaart om de popup te tonen wat dus zorgt voor het opnieuw ophalen van de lijst.
Het zou in principe met 2 requests kunnen, maar de set data is erg samen hangend. Ik probeer eigenlijk nooit libraries te gebruiken in combinatie met een dergelijk groot stuk javascript, is al zo veel ;)

Usability technisch heeft deze beta nogal wat gebreken. Hiervan zijn we ons bewust. Er komen een tweetal oplossingen, clustering (zoals je ziet op bijvoorbeeld nukaart.nl) en een tileserver voor het tonen van grote aantallen iconen tegelijk. Deze oplossingen zouden betekenen dat er geen nood is voor extra communicatie met de gebruiker of het feit dat er meer locaties zichtbaar worden als je meer inzoomed.

Ik zou bij het vermijden van een dergelijke overbodige eval van de html eerder denken aan een container binnen de request waardoor ik dus een substring actie zou kunnen doen. Meerdere requests gaat echt gezeur geven denk ik, wat nou als de ene er langer over doet dan de ander dan komt de data qua locaties niet meer overeen met de data van het menu. Dat wordt lastig afvangen imo.

"True skill is when luck becomes a habit"
SWIS


Acties:
  • 0 Henk 'm!

Verwijderd

UltimateB schreef op vrijdag 26 juni 2009 @ 21:42:
[...]Ik zou bij het vermijden van een dergelijke overbodige eval van de html eerder denken aan een container binnen de request waardoor ik dus een substring actie zou kunnen doen.
Misschien kun je je response zelf nog encoden: voorloop decimale lengte van het eerste blok, scheidingsteken, blok één en dan blok twee. Je kunt de responsetext vrij eenvoudig scheiden in HTML en JSON.
Meerdere requests gaat echt gezeur geven denk ik, wat nou als de ene er langer over doet dan de ander dan komt de data qua locaties niet meer overeen met de data van het menu. Dat wordt lastig afvangen imo.
Valt wel mee; je kunt de twee request achter elkaar hangen. Bij de eerste request maakt je server script dan de data en zet de content voor de tweede request klaar. Parallel kan ook maar dan ga je of de data twee keer samenstellen (lijkt me in jouw geval niet wenselijk) of moet je 'moeilijke' dingen op de server gaan doen (lijkt me wat overkill) Het tijdverschil tussen beide request is minimaal en je kunt eventueel de data ook pas verwerken wanneer de tweede request afgerond is.
Pagina: 1