Toon posts:

[JS] Optimalisatie

Pagina: 1
Acties:

Verwijderd

Topicstarter
Inleiding:

Vanmiddag ben ik een beetje aan het knutselen geweest met javascript, en een scriptje gemaakt wat de inhoud van een selectiebox afhankelijk laat zijn van een andere, namelijk plaatsen van landen.

Manier van aanpak:

ik laat php een aantal javascript arrays produceren als volgt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
case 2: {
            // eerst gaan we even alle plaatsen in arrays pompen... moet niet al te moeilijk zijn.
            ?>
            <script type="text/javascript">
            <?
            $sql = "SELECT id, naam, code FROM v3_landen";
            if (!$result = mysql_query($sql)) {
                echo 'Fout in de query: '. $sql .' '. mysql_error() .'<br />';
            } else {
                if (mysql_num_rows($result) > 0) {
                    while ($rows = mysql_fetch_assoc($result)) {
                        echo $rows['naam'].' = new Array(';
                        $sql2 = "SELECT * FROM v3_plaatsen WHERE code = '". $rows['code'] ."'";
                        if (!$result2 = mysql_query($sql2)) {
                            echo 'Fout in de query: '. $sql2 .' '. mysql_error() .'<br />';
                        } else {
                            if (mysql_num_rows($result2) > 0) {
                                $first = true;
                                while ($rows2 = mysql_fetch_assoc($result2)) {
                                    if ($first) {
                                        $first = false;
                                    } else {
                                        echo ',';
                                    }
                                    echo '"'. strtolower($rows2['naam']) .'"';
                                    
                                }
                            }
                        }
                        echo ');';
                    }
                }
            }
            ?>


Vervolgens maakt javascript er een selectboxje mee:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function WijzigPlaatsen(naam) {
                selectieBox = '<select name="plaats">';
                
                if (naam == 'Nederland') {
                    for (counter = 0; counter < Nederland.length; counter++) {
                        selectieBox += '<option value="' + Nederland[counter] + '">' + Nederland[counter] + '</option>';
                    }
                }   
                if (naam == 'Duitsland') {
                    for (counter = 0; counter < Duitsland.length; counter++) {
                        selectieBox += '<option value="' + Duitsland[counter] + '">' + Duitsland[counter] + '</option>';
                    }
                }   
                if (naam == 'Belgie') {
                    for (counter = 0; counter < Belgie.length; counter++) {
                        selectieBox += '<option value="' + Belgie[counter] + '">' + Belgie[counter] + '</option>';
                    }
                }   
                if (naam == 'Frankrijk') {
                    for (counter = 0; counter < Frankrijk.length; counter++) {
                        selectieBox += '<option value="' + Frankrijk[counter] + '">' + Frankrijk[counter] + '</option>';
                    }
                }   
                if (naam == 'Luxemburg') {
                    for (counter = 0; counter < Luxemburg.length; counter++) {
                        selectieBox += '<option value="' + Luxemburg[counter] + '">' + Luxemburg[counter] + '</option>';
                    }
                }   
                
                
                
                document.getElementById('plaats_span').innerHTML = selectieBox;
            }
            
            
            
            
            
            </script>


Oke alles goed en aardig, het werkt, maar verschrikkelijk traag, als ik een land kies in de dropdown duurt het (afhankelijk van het aantal plaatsen wat voor dat land in de database staat) wel een halve minuut voor ik weer verder kan.
Aangezien wat ik aan het doen ben niet voor mij zelf is, is dit een onacceptabel lange wachttijd.

Heeft iemand dus tips of trucs om dit te versnellen?

Pak ik het zowieso helemaal verkeerd aan?

Alle tips en suggesties zijn welkom

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

IE is heel traag bij het werken met lange strings; daar zijn wel workarounds voor, maar in dit geval zou ik innerHTML sowieso proberen te vermijden en zoiets toepassen:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var plaatsen = new Array();
plaatsen['Nederland'] = new Array('Amsterdam', 'Rotterdam', 'Amersfoort');
plaatsen['Duitsland'] = new Array('Bonn', 'Berlijn');

function WijzigPlaatsen(landSelect)
{
    var land = landSelect.options[landSelect.selectedIndex].value;
    var plaatsSelect = landSelect.form.elements['plaats'];
    plaatsSelect.options.length = 0;
    if (land && plaatsen[land])
    {
        var i = 0, j = plaatsen[land].length, plaats;
        while (i < j)
        {
            plaats = plaatsen[land][i];
            plaatsSelect.options[i] = new Option(plaats, plaats);
            i++;
        }
    }
}

</script>
<form action="#">
    <select name="land" onchange="WijzigPlaatsen(this)" style="width:200px">
        <option>Maak een selectie:</option>
        <option value="Nederland">Nederland</option>
        <option value="Duitsland">Duitsland</option>
    </select>
    <select name="plaats" style="width:200px">
    </select>
</form>

Intentionally left blank


Verwijderd

Topicstarter
Oke,

Ik moet er even mee stoeien (zit pas sinds vanmiddag een beetje naar JS te kijken), maar ik kan er wel wat mee denk ik.


Bedankt alvast iig.

  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 02-01 15:55
In je 1e oplossing is het ook niet echt handig dat je zoveel if statements achter elkaar zet, je zou dat beter op kunnen lossen met een switch of met 'else if' , mocht je het eens nodig hebben!

Verder is de oplossing van crisp zowiezo veel netter en sneller.

If I can't fix it, it ain't broken.


Verwijderd

Topicstarter
Daar heb je gelijk in, het is zeker geen nette oplossing, en ik had het ook zeker niet zo gelaten, maar het ging me nu vooral even om uit te zoeken hoe ik zoiets voor elkaar kon krijgen en hoe ik het kon versnellen :)

Edit;

Overigens ben ik wel bekend met switch-statements etc. ik programmeer al een tijdje in PHP en C++

[ Voor 21% gewijzigd door Verwijderd op 06-06-2005 20:03 ]


  • Annie
  • Registratie: Juni 1999
  • Laatst online: 25-11-2021

Annie

amateur megalomaan

Als het om heel veel opties gaat, is werken met new Option overigens ook niet de snelste methode. Dan is innerHTML bij mijn weten nog steeds sneller. Om de lange string met options op te bouwen kan je dan weer een array aanmaken met alle waarden en deze join-en.

Disclaimer: tot zover de theorie ;) ik heb het niet getest. Dit is puur gebaseerd op wat de grijze massa zich denkt te kunnen herinneren ooit gelezen te hebben. So sue me, if i'm wrong :P

Today's subliminal thought is:


Verwijderd

Annie schreef op maandag 06 juni 2005 @ 20:49:
Als het om heel veel opties gaat, is werken met new Option overigens ook niet de snelste methode. Dan is innerHTML bij mijn weten nog steeds sneller. Om de lange string met options op te bouwen kan je dan weer een array aanmaken met alle waarden en deze join-en.

Disclaimer: tot zover de theorie ;) ik heb het niet getest. Dit is puur gebaseerd op wat de grijze massa zich denkt te kunnen herinneren ooit gelezen te hebben. So sue me, if i'm wrong :P
Nee je bent niet verkeerd, zowiezo is die join functie afaik de beste methode qua optimalisatie voor iig IE, en is innerHTML (en document.write() maar die geeft problemen in IE ivm het maximaal aantal connecties en is dus niet runtime handig) nog steeds sneller op elke browser dan de native en DOM functies. Nadeel is echter wel, en daarom gebruik ik innerHTML steeds minder, is dat je geen referentie krijgt naar je elementen en die alsnog moet opzoeken als je ze nodig hebt.

[ Voor 3% gewijzigd door Verwijderd op 06-06-2005 21:09 ]


  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

even 3 alternatieven gebenched (AMD XP2000+ Win2K) met 2000 options voor 'Nederland':
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<script type="text/javascript">

function WijzigPlaatsen(landSelect)
{
    var st = new Date().getTime();

//  WijzigPlaatsen1(landSelect);
//  WijzigPlaatsen2(landSelect);
    WijzigPlaatsen3(landSelect);

    var et = new Date().getTime();
    alert (et-st);
}

function WijzigPlaatsen1(landSelect)
{
    var land = landSelect.options[landSelect.selectedIndex].value;
    var plaatsSelect = landSelect.form.elements['plaats'];
    plaatsSelect.options.length = 0;
    if (land && plaatsen[land])
    {
        var i = 0, j = plaatsen[land].length, plaats;
        while (i < j)
        {
            plaats = plaatsen[land][i];
            plaatsSelect.options[i] = new Option(plaats, plaats);
            i++;
        }
    }
}

function WijzigPlaatsen2(landSelect)
{
    var land = landSelect.options[landSelect.selectedIndex].value;
    var plaatsSelect = '<select name="plaats" style="width:200px">';
    if (land && plaatsen[land])
    {
        var i = 0, j = plaatsen[land].length, plaats;
        while (i < j)
        {
            plaats = plaatsen[land][i];
            plaatsSelect += '<option values="' + plaats + '">' + plaats;
            i++;
        }
    }

    document.getElementById('plaatsContainer').innerHTML = plaatsSelect + '<\/select>';
}

function WijzigPlaatsen3(landSelect)
{
    var land = landSelect.options[landSelect.selectedIndex].value;
    var plaatsSelect = new Array();
    if (land && plaatsen[land])
    {
        var i = 0, j = plaatsen[land].length, plaats;
        while (i < j)
        {
            plaats = plaatsen[land][i];
            plaatsSelect[i] = '<option values="' + plaats + '">' + plaats;
            i++;
        }
    }

    document.getElementById('plaatsContainer').innerHTML = '<select name="plaats" style="width:200px">' + plaatsSelect.join('') + '<\/select>';
}

</script>
<form action="#">
    <select name="land" onchange="WijzigPlaatsen(this)" style="width:200px">
        <option>Maak een selectie:</option>
        <option value="Nederland">Nederland</option>
        <option value="Duitsland">Duitsland</option>
    </select>
    <span id="plaatsContainer"><select name="plaats" style="width:200px"></select></span>
</form>


resultaten:

WijzigPlaatsen1
IE 6: +/- 4200 ms
Ff 1.04: +/- 290 ms
Opera 8: +/- 350 ms

WijzigPlaatsen2
IE 6: +/- 770 ms
Ff 1.04: +/- 120 ms
Opera 8: +/- 30ms

WijzigPlaatsen3
IE 6: +/- 70 ms
Ff 1.04: +/- 120 ms
Opera 8: +/- 60 ms

via new Option werken is in IE zelfs extreem traag :/
Je ziet hier ook duidelijk dat IE moeite heeft met het verwerken van grote strings (WijzigPlaatsen2) terwijl dat voor Firefox niet uitmaakt en in Opera zelfs 2x sneller is dan de truuk met de array en de join() (WijzigPlaatsen3).
Conclusie: IE zuigt ( :P ) en het beste compromis is toch om met innerHTML en de array - join() truuk te werken :)

Intentionally left blank


Verwijderd

Wederom mooie benches Crisp _/-\o_ Cijfertjes tonen nu eenmaal meer aan als beweringen, al waren ze wel goed :P

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Verwijderd schreef op maandag 06 juni 2005 @ 23:21:
Wederom mooie benches Crisp _/-\o_ Cijfertjes tonen nu eenmaal meer aan als beweringen, al waren ze wel goed :P
Ik had zelf eerlijk gezegd niet verwacht dat IE met de new Option-methode nog trager zou zijn dan de toch al trage string-handling van IE, en dan heb ik de DOM 2 methode (createElement) nog niet eens geprobeerd. 300 ms voor 2000 options vind ik zelf nog wel acceptabel (of 2000 options in een select nog wel usable is is een ander vraagstuk), maar in dit geval heb je eigenlijk geen andere keus dan toch innerHTML te gebruiken, en dat dat vervolgens ook nog eens sneller is in andere browsers (disclaimer: ik heb er maar 3 getest) is mooi meegenomen ;)

Intentionally left blank


Verwijderd

Ik zou zelf de voorkeur geven aan de new option in je eerste voorbeeld. Tenzij je compleet afhankelijk bent van low level optimalisaties is sneller is nu eenmaal vaak niet beter als netter, en vind de OO aanpak betere onderhoudbaar dan de string output :)

Verwijderd

Topicstarter
Inderdaad heel tof die bench _/-\o_

Lijkt me duidelijk dat ik versie 3 zal gebruiken :)
Pagina: 1