Une partie importante du cycle de développement de Microsoft consiste à ajuster les performances des produits. L'optimisation des performances est également l'un des domaines clés auxquels les développeurs doivent prêter attention. Après des années de développement, l'industrie a beaucoup appris sur la manière d'optimiser les performances des programmes Win32.
L'un des problèmes auxquels les développeurs sont confrontés aujourd'hui est qu'ils ne comprennent pas vraiment ce qui fait que les pages DTHML et HTML s'exécutent rapidement ou lentement. Bien sûr, il existe des solutions simples, comme ne pas utiliser d'images de 2 Mo. Nous avons utilisé d'autres techniques intéressantes pour améliorer les performances des pages DHTML. Nous espérons qu'elles pourront vous aider à améliorer les performances de vos propres pages.
Ici, j'utilise un exemple de programme pour créer une table. Les méthodes document.createElement() et element.insertBefore() permettent de créer un tableau de 1000 lignes (Row). Chaque ligne comporte une colonne (Cellule). Le contenu contenu dans la Cellule est appelé « Texte ». À quel point ce code pourrait-il être mauvais ? Quelle est la marge d’ajustement d’un si petit programme ? Veuillez consulter l'introduction.
Au début, j'ai écrit un programme que je pensais rapide. J'ai essayé d'éviter certains problèmes de bas niveau, comme ne pas définir explicitement les variables ou utiliser VBScript et JavaScript en même temps sur une seule page. Le programme est le suivant :
<html>
<corps>
<script>
var tbl, tbody, tr, td, texte, je, max ;
max = 1000;
tbl = document.createElement("TABLE");
tbl.border = "1" ;
tbody = document.createElement("TBODY");
tbl.insertBefore(tbody, null);
document.body.insertBefore(tbl, null);
pour (i=0; i<max; i++) {
tr = document.createElement("TR");
td = document.createElement("TD");
texte = document.createTextNode("Texte");
td.insertBefore(texte, null);
tr.insertBefore(td, null);
tbody.insertBefore(tr, null);
}
</script>
</corps>
</html>
Exécutez ce programme sur une machine PII233/64 Mo de mémoire/NT4.0/IE5.0. La page est chargée à partir de cette machine. Le temps écoulé entre le début du chargement de la page et celui où la page s'apaise complètement (tous les événements ont été exécutés et l'affichage à l'écran est terminé) est de 2 328 millisecondes, ce qui est également la base de référence de ce test (je l'appelle Test1).
Dans cette page, une opération très chronophage consiste à référencer fréquemment des objets globaux, tels que "document", "body", "window", etc. Faire référence à toutes ces variables globales similaires coûte beaucoup plus cher que référencer une variable locale.
J'ai donc fait une première tentative d'amélioration : mettre en cache (Cache) document.body dans la variable locale "theBody" :
ajout du code suivant :
var theBody = document.body;
Modifiez ensuite cette ligne :
document.body.insertBefore(tbl, null);
Remplacez-le par :
theBody.insertBefore(tbl, null);
Regardez le deuxième échantillon.
Cette modification n'a pas beaucoup affecté le temps global, elle n'a raccourci que 3 ms. Mais il a été démontré que s’il y a aussi un objet document.body dans la boucle et que sa référence est modifiée, les bénéfices seront considérables.
Par la suite, j'ai mis en cache l'objet document - lors de notre test, l'objet document a été référencé 3 002 fois au total. Le code modifié est le suivant :
<html>
<corps>
<script>
var tbl, tbody, tr, td, texte, je, max ;
maximum = 1 000 ;
var theDoc = document;
var theBody = theDoc.body;
tbl = theDoc.createElement("TABLE");
tbl.border = "1" ;
tbody = theDoc.createElement("TBODY");
tbl.insertBefore(tbody, null);
theBody.insertBefore(tbl, null);
pour (i=0; i<max; i++) {
tr = theDoc.createElement("TR");
td = theDoc.createElement("TD");
text = theDoc.createTextNode("Texte");
td.insertBefore(texte, null);
tr.insertBefore(td, null);
tbody.insertBefore(tr, null);
}
</script>
</corps>
</html>
Visualisez le troisième exemple.
Ce temps d'exécution n'est que de 2 100 ms, ce qui permet d'économiser environ 10 % du temps. L'utilisation de variables locales au lieu de référencer directement l'objet document a permis d'économiser en moyenne 0,4 milliseconde à chaque fois.
Une manière courante d'optimiser les performances consiste à définir l'attribut « defer » dans la balise <SCRIPT> lorsque le script n'a pas besoin d'être exécuté immédiatement. (Le script immédiat n'est pas contenu dans un bloc fonctionnel, il sera donc exécuté pendant le processus de chargement.) Après avoir défini l'attribut "defer", IE n'a pas besoin d'attendre que le script se charge et s'exécute. De cette façon, la page se chargera plus rapidement. De manière générale, cela signifie également qu'il est préférable de placer les scripts immédiats dans des blocs fonctionnels et de gérer la fonction dans le gestionnaire onload du document ou de l'objet corps. Cette propriété est utile lorsque certains scripts doivent être exécutés en fonction des actions de l'utilisateur, comme cliquer sur un bouton ou déplacer la souris vers une certaine zone. Mais lorsque certains scripts doivent être exécutés pendant ou après le chargement de la page, les avantages de l'utilisation de l'attribut defer ne sont pas grands.
Voici la version modifiée du code utilisant l'attribut defer :
<html>
<body onload="init()">
<script différé>
fonction init() {
var tbl, tbody, tr, td, texte, je, max ;
maximum = 1 000 ;
var theDoc = document;
var theBody = theDoc.body;
tbl = theDoc.createElement("TABLE");
tbl.border = "1" ;
tbody = theDoc.createElement("TBODY");
tbl.insertBefore(tbody, null);
theBody.insertBefore(tbl, null);
pour (i=0; i<max; i++) {
tr = theDoc.createElement("TR");
td = theDoc.createElement("TD");
text = theDoc.createTextNode("Texte");
td.insertBefore(texte, null);
tr.insertBefore(td, null);
tbody.insertBefore(tr, null);
}
}
</script>
</corps>
</html>
Visualisez le quatrième échantillon.
La durée de ce test est de 2043 ms. Il s’agit d’une augmentation de 12 % par rapport au test de base et de 2,5 % de plus que le test précédent.
Une méthode d'amélioration dont nous parlons ci-dessous est très utile, bien sûr, mais un peu plus gênante. Lorsque vous devez créer un élément puis l'insérer dans une structure arborescente, il est plus efficace de l'insérer directement dans le tronc, plutôt que de l'insérer d'abord dans un grand sous-arbre, puis d'insérer le grand sous-arbre dans le tronc. Par exemple, si vous créez un tableau avec une colonne dans chaque ligne et du texte dans la colonne, vous pouvez faire ceci :
1. Créer <TR>
2. Créer <TD>
3. Créer un nœud TextNode
4. Insérer TextNode dans <TD >
5 . Insérez <TD> dans <TR>
6. Insérez <TR> dans TBODY
Lorsqu'elle est plus lente que la méthode suivante :
1. Créer <TR>
2. Créer <TD>
3. Créer TextNode
4. Insérer <TR > Insérer dans TBODY
5. Insérer <TD> dans <TR>
6. Insérer TextNode dans <TD>
Les quatre tests ci-dessus utilisent tous la première méthode. Nous avons utilisé cette dernière méthode pour le cinquième test. Le code est le suivant :
<html>
<body onload="init()">
<script différé>
fonction init() {
var tbl, tbody, tr, td, texte, je, max ;
maximum = 1 000 ;
var theDoc = document;
var theBody = theDoc.body;
tbl = theDoc.createElement("TABLE");
tbl.border = "1" ;
tbody = theDoc.createElement("TBODY");
tbl.insertBefore(tbody, null);
theBody.insertBefore(tbl, null);
pour (i=0; i<max; i++) {
tr = theDoc.createElement("TR");
td = theDoc.createElement("TD");
text = theDoc.createTextNode("Texte");
tbody.insertBefore(tr, null);
tr.insertBefore(td, null);
td.insertBefore(texte, null);
}
}
</script>
</corps>
</html>
Visualisez le cinquième échantillon.
Test5 ne prend que 1649 ms. Il s'agit d'une amélioration de 25 % par rapport au dernier test et de près de 30 % plus rapide que la ligne de base.
Les modifications ultérieures ont été apportées à l'aide de feuilles de style prédéfinies. La largeur de colonne d'un tableau qui utilise une feuille de style prédéfinie ou est définie via la balise <COL>. Lorsqu'il n'y a pas de balise <COL>, la largeur de chaque colonne est uniformément répartie. Puisqu'il n'est pas nécessaire de recalculer la taille de chaque colonne, etc., l'utilisation d'une feuille de style améliore réellement les performances, en particulier lorsque le nombre de colonnes dans le tableau est important.
Le code pour ajouter une feuille de style (CSS) est très simple, comme suit :
tbl.style.tableLayout = "fixed";
Afficher le sixième exemple
Étant donné que le tableau de notre test ne comportait qu'une seule colonne, cette modification n'a amélioré les performances de la page que de 1,6 %. S'il y a plus de colonnes, l'augmentation des performances sera encore plus importante.
Les deux derniers tests ont modifié la manière dont le texte est inséré dans le tableau. Dans les tests précédents, nous avons d'abord créé un TextNode puis l'avons inséré dans le TD. Dans Test7, à la place, nous spécifions le texte inclus via innerText. Le code modifié est :
td.innerText = "Text";
Regardez le septième échantillon.
Étonnamment, la différence apportée par cette modification a été énorme : une amélioration des performances de 9 % par rapport à la dernière fois et une amélioration totale des performances de 36 % par rapport à l'original. Le temps s'étend des premières 2323 ms aux dernières 1473 ms.
Maintenant, presque tout le monde sait que l'utilisation d'element.innerHTML est très lente. Pour voir à quel point c'est lent, j'ai fait un dernier test : insérer du texte en utilisant innerHTML au lieu de innerText. Cela réduit considérablement les performances. Le temps a atteint 3 375 ms, soit 80 % plus lent que le dernier test et 45 % plus lent que le test de base. Évidemment, innerHTML prend beaucoup de temps.
Le réglage des performances des pages HTML est similaire au réglage des performances des applications Win32 ; vous devez savoir ce qui est lent et ce qui est rapide. J'espère que ces méthodes pourront vous aider à améliorer les performances des pages.