Ik ben nu een tijdje bezig met een vrij uitgebreide applicatie in JavaScript. Dit is eigenlijk de eerste keer dat ik iets met JavaScript maak en deze omvang heeft. Hierdoor kom ik (eigenlijk voor het eerst) tegen problemen aan met JavaScript en geheugen lekken. Met name eerdere reacties op bepaalde stukken code maakte me nieuwsgierig naar deze problemen.
Na een hoop dingen gevonden te hebben op Google en GoT merkte ik dat er nergens echt een goed overzicht van alle soorten lekken, en vooral (!) de oplossingen voor deze lekken.
In dit topic (uit 2003) wordt hetzelfde onderwerp behandeld, maar ik vind de reacties wat onduidelijk en onvolledig.
De hele openbaring (negatieve dan) heeft me enigszins in de war gebracht, waardoor ik nu niet meer durf om nieuwe code te typen omdat ik bang ben dat alles wat ik schrijf gaat lekken.
Ik wil heel graag de goeie schrijfwijzen weten voor simpele dingen in JS en vraag me nu dus af welke soorten en oplossingen er zijn.
Ik ben ook voorbeelden tegengekomen van het 'oplossen' van geheugenlekken die bij een unload handmatig het geheugen van events vrij maken, maar zoals crisp in een eerdere post noemde is dit volgens mij eerder een workaround dan een oplossing. Tevens is de applicatie die ik nu maak op 1 pagina, dus een unload() komt niet zo snel voor...
Hieronder staan stukken code die ik heb geschreven naar aanleiding van wat ik heb gevonden. De meeste code is in de syntax hoe ik het op zou schrijven, andere stukken zijn in een syntax die ik heb gevonden op internet. (ik ben nog op onderzoek dus ga er niet vanuit dat alles correct is, naar mate er reacties komen zal ik deze post updaten)
VOORBEELDEN:
appendChild() volgorde (het voorkomen van het creëren van tijdelijke DOM nodes)
Events hangen aan DOM nodes
JavaScript closures
DOM object in JavaScript object zorgt voor lek
Gerelateerde URLs:
Na een hoop dingen gevonden te hebben op Google en GoT merkte ik dat er nergens echt een goed overzicht van alle soorten lekken, en vooral (!) de oplossingen voor deze lekken.
In dit topic (uit 2003) wordt hetzelfde onderwerp behandeld, maar ik vind de reacties wat onduidelijk en onvolledig.
De hele openbaring (negatieve dan) heeft me enigszins in de war gebracht, waardoor ik nu niet meer durf om nieuwe code te typen omdat ik bang ben dat alles wat ik schrijf gaat lekken.
Ik wil heel graag de goeie schrijfwijzen weten voor simpele dingen in JS en vraag me nu dus af welke soorten en oplossingen er zijn.
Ik ben ook voorbeelden tegengekomen van het 'oplossen' van geheugenlekken die bij een unload handmatig het geheugen van events vrij maken, maar zoals crisp in een eerdere post noemde is dit volgens mij eerder een workaround dan een oplossing. Tevens is de applicatie die ik nu maak op 1 pagina, dus een unload() komt niet zo snel voor...
Hieronder staan stukken code die ik heb geschreven naar aanleiding van wat ik heb gevonden. De meeste code is in de syntax hoe ik het op zou schrijven, andere stukken zijn in een syntax die ik heb gevonden op internet. (ik ben nog op onderzoek dus ga er niet vanuit dat alles correct is, naar mate er reacties komen zal ik deze post updaten)
VOORBEELDEN:
appendChild() volgorde (het voorkomen van het creëren van tijdelijke DOM nodes)
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
| var div = document.getElementById('test'); var form = document.createElement('form'); var input = document.createElement('input'); // Goeie volgorde, voorkomt tijdelijke DOM tree div.appendChild( form ); form.appendChild( input ); // Appenden op deze volgorde lekt geheugen form.appendChild( input); div.appendChild( form ); |
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| /* * Vraag me af of het nu ook nodig is om alle attributen/properties van de DOM node * pas te definiëren NAdat de node aan zijn parentElement gehangen is met .appendChild() */ // Dus: var p = document.createElement('p'); var label = document.createElement('label'); var input = document.createElement('input'); form.appendChild( p ); p.appendChild( label ); p.appendChild( input ); label.setAttribute('username'); label.htmlFor = ''; // IE only input.type = 'text'; input.name = 'username'; input.id = 'username'; |
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // Of: (kan dit wel gewoon zonder te lekken???) var p = document.createElement('p'); var label = document.createElement('label'); var input = document.createElement('input'); label.setAttribute('username'); label.htmlFor = ''; // IE only input.type = 'text'; input.name = 'username'; input.id = 'username'; form.appendChild( p ); p.appendChild( label ); p.appendChild( input ); |
Events hangen aan DOM nodes
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
| // Anonymous function (kan niet worden verwijderd door de garbage collector, // DUS lekt geheugen?) var div = document.getElementById('test'); div.onclick = function(e) { alert('testje'); } // Function reference in de event handler, lekt geen geheugen? div.onclick = bla; } function bla(e) { // this verwijst hier naar de <div> alert('testje'); } |
JavaScript closures
JavaScript:
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
| function Tree(type) { this.type = type; this.branches = 10; return this; } Tree.prototype.grow = function() { var self = this; // Dit lekt geheugen, hoe kan ik dit voorkomen? var ul = document.createElement('ul'); document.body.appendChild( ul ); for (var i = 0; i < this.branches; i++) { var li = document.createElement('li'); ul.appendChild( li ); li.appendChild( document.createTextNode('branch ' + i) ); li.onclick = function(e) { self.cutBranch( this ); } li = null; // Removing DOM node from memory } ul = null; // Removing DOM node from memory } Tree.prototype.cutBranch = function( element ) { var parent = element.parentNode; if (parent) { parent.removeChild( element ); return true; } return false; } var boompje = new Tree('den'); boompje.grow(); // // Alternatief met function reference ipv anonymous function als event, // en een argument meegeven [...] Tree.prototype._onItemClick(index) { // this verwijst hier naar het <li> element en NIET naar het Tree object ? return function() { alert( 'clicked item with index: ' + index ); } } Tree.prototype.grow2 = function() { var ul = document.createElement('ul'); document.body.appendChild( ul ); for (var i = 0; i < this.branches; i++) { var li = document.createElement('li'); ul.appendChild( li ); li.appendChild( document.createTextNode('branch ' + i) ); li.onclick = _onItemClick(i); li = null; // Removing DOM node from memory } ul = null; // Removing DOM node from memory } |
DOM object in JavaScript object zorgt voor lek
JavaScript:
Als iemand me zou kunnen vertellen welke voorbeelden goed zijn en welke slecht dan ben ik al een heel eind op weg. Thanks!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // function Grid(id) { this.id = grid || 'grid'; // volgende regel zorgt voor lek? this.table = document.getElementById(id) || document.createElement('table'); this.table.id = id; // event function reference meegeven voorkomt lek? this.table.onclick = this.clickHandler; } Grid.prototype.clickHandler = function(e) { // this verwijst naar de <table>, niet erg handig } var gridje = new Grid('grid01'); |
Gerelateerde URLs: