Ik ben bezig een simpel scriptje te schrijven dat alle anchors op een pagina naloopt en controleert of ze toevallig naar een externe site wijzen. Indien dit het geval is, wordt de anchor gemarkeerd in de vorm van een icoontje naast de tekst en opent de pagina in een nieuw venster (met fallback naar het huidige venster als een popupblocker roet in het eten gooit).
Allereerst, het script zoals het er nu bijstaat:
Nu is dit een relatief eenvoudig script, maar wel één dat zich leent voor allerlei optimalisatie technieken en truuks. Aangezien ik hier toch eens serieus naar wilde kijken, heb ik dus geprobeerd dit script zo efficiënt mogelijk te maken.
Wat heb ik gedaan?
1) Zoveel mogelijk buiten de loop gehouden. Reguliere expressies niet als literal argument aan de match methodes meegeven, event handler volledig buiten de functie plaatsen om eventuele closure problemen te voorkomen, etc.
2) Het aantal DOM calls tot een minimum beperken. Verder zoveel mogelijk cachen.
3) De loop reversen. Ik heb ook een "Duff's device" geprobeerd, maar haalde hier geen meetbare snelheidswinst mee.
Nu de vraag, wat kan er beter? Wellicht dat het toevoegen van het icoon sneller kan. Ik had het aanvankelijk met CSS opgelost, maar dat bleek fout te gaan in IE (kan niet lekker overweg met backgrounds op een inline element dat meerdere tekstregels bevat).
Nu hoef ik niet direct specifieke tips voor dit script, ik ben vooral geïnteresseerd in wat algemene richtlijnen om m'n JavaScripts zo efficiënt mogelijk hun werk te laten doen.
Overigens nog één laatste, ietwat nasty idee waar ik mee speel: het aanroepen van de externalLinks functie op de volgende manier:
Als ik me niet vergis wordt code die aangeroepen wordt door setTimeout in een andere thread uitgevoerd. Op deze manier zou ik kunnen voorkomen dat de pagina "bevriest" terwijl er door de +/- 200 anchors geloopt wordt. Als ik het test merk ik wel dat de pagina niet meer bevriest (alleen merkbaar overigens bij 1000+ anchors). Klopt het dat de functie in een andere thread wordt uitgevoerd? En kleven er nog nadelen aan dit idee?
Allereerst, het script zoals het er nu bijstaat:
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
| function newWindow() { return !window.open(this.href, "_blank"); } function externalLinks() { // Regular expressions, match should be negative var hrefRegEx = new RegExp("^mailto:|(http|https)://" + window.location.hostname, "gi"), classRegEx = new RegExp("nopopup", "gi"); // Anchors var anchors = document.getElementsByTagName("a"), i = anchors.length; // Icon var icon = document.createElement("img"); icon.src = "external.gif"; icon.alt = "Opent in een nieuw venster"; // Check if the anchor points to an external URI function check(anchor) { if (anchor.href && !anchor.href.match(hrefRegEx) && !anchor.className.match(classRegEx)) { anchor.onclick = newWindow; anchor.title = (!anchor.title ? "Opent in een nieuw venster" : anchor.title + " (Opent in een nieuw venster)"); // If the anchor contains an image, don't add the icon if (!anchor.getElementsByTagName("img").length) { anchor.appendChild(icon.cloneNode(false)); } } } // Loop-tee-loop while(i--) { check(anchors[i]); } } |
Nu is dit een relatief eenvoudig script, maar wel één dat zich leent voor allerlei optimalisatie technieken en truuks. Aangezien ik hier toch eens serieus naar wilde kijken, heb ik dus geprobeerd dit script zo efficiënt mogelijk te maken.
Wat heb ik gedaan?
1) Zoveel mogelijk buiten de loop gehouden. Reguliere expressies niet als literal argument aan de match methodes meegeven, event handler volledig buiten de functie plaatsen om eventuele closure problemen te voorkomen, etc.
2) Het aantal DOM calls tot een minimum beperken. Verder zoveel mogelijk cachen.
3) De loop reversen. Ik heb ook een "Duff's device" geprobeerd, maar haalde hier geen meetbare snelheidswinst mee.
Nu de vraag, wat kan er beter? Wellicht dat het toevoegen van het icoon sneller kan. Ik had het aanvankelijk met CSS opgelost, maar dat bleek fout te gaan in IE (kan niet lekker overweg met backgrounds op een inline element dat meerdere tekstregels bevat).
Nu hoef ik niet direct specifieke tips voor dit script, ik ben vooral geïnteresseerd in wat algemene richtlijnen om m'n JavaScripts zo efficiënt mogelijk hun werk te laten doen.
Overigens nog één laatste, ietwat nasty idee waar ik mee speel: het aanroepen van de externalLinks functie op de volgende manier:
JavaScript:
1
| setTimeout(externalLinks, 0); |
Als ik me niet vergis wordt code die aangeroepen wordt door setTimeout in een andere thread uitgevoerd. Op deze manier zou ik kunnen voorkomen dat de pagina "bevriest" terwijl er door de +/- 200 anchors geloopt wordt. Als ik het test merk ik wel dat de pagina niet meer bevriest (alleen merkbaar overigens bij 1000+ anchors). Klopt het dat de functie in een andere thread wordt uitgevoerd? En kleven er nog nadelen aan dit idee?