En lisant le forum et en répondant aux questions, je me suis dit qu'une petite mise au point semblait nécessaire.
Souvent, dans nos développements, nous avons un serveur dynamique PHP, ASP, JAVA, C#, Ruby, etc.
Il est très facile et tentant de générer les divers éléments dont on a besoin directement avec le langage de ce serveur.
C'est simple, ça apporte des facilités mais ce n'est pas toujours aussi efficace qu'on le pense.
Lorsqu'on crée le code HTML de la page, on place au fur et à mesure le code JavaScript dont on a besoin en incluant directement dans celui-ci, tout comme pour le HTML, les valeurs des variables du langage hôte.
Code php : | Sélectionner tout |
1 2 3 4 5 6 7 | <?PHP $Message = '"Hello World!"'; print '<script type="text/javascript">'; print ' function confirm(message) { ..... }'; print '</script>'; print "<a href='#' onClick = 'return confirm(".$Message.");'>Test</a>"; ?> |
Parmi les avantages, le regroupement de tout le code concernant un point précis. Ici la confirmation du message.
Dans le langage hôte, nous avons la définition de la valeur,
la génération du code JavaScript qui l'utilise
et le code HTML qui permettra de l'invoquer.
Autre avantage, on peut très facilement ne produire que le code JavaScript nécessaire à ce besoin. Si la fonction JavaScript à utiliser dépend d'une propriété dans le langage hôte, un simple if permet de produire la bonne fonction.
Bref, je ne vais pas énumérer les avantages et encore moins les inconvénients.
Mon propos est juste de montrer pourquoi cette idée est une fausse bonne idée.
Pour cela revenons, au fonctionnement du Web, c'est-à-dire HTTP.
- Le client invoque une URL.
- Le serveur déroule son code et produit dynamiquement une source HTML.
- Le client reçoit cette source.
- Il ne peut pas le mettre en cache car il est dynamique et contient des données variables.
- Il le parse et crée le DOM correspondant.
- Il donne à l'interpréteur JavaScript la source JavaScript qu'il contient.
- L'interpréteur JavaScript compile le code (partiellement) et le relie au DOM.
- L'interpréteur ne peut mettre le code compilé en cache car il est embarqué dans une source qui n'est pas cachée.
- L'interpréteur ne peut mettre le code compilé en cache car il est embarqué dans une source qui n'est pas cachée.
- La page est disponible pour l'utilisateur.
- L'utilisateur active le code JavaScript par une action (un click dans l'exemple).
- L'interpréteur JavaScript compile si besoin le code non compilé et l'exécute.
- Si l'action est encore invoquée, elle est juste exécutée.
- Si l'action est encore invoquée, elle est juste exécutée.
Si le client au cours de son activité revient sur la même page, on repart du début.
Le code est régénéré, retransféré, réinterprété par le moteur HTML, recompilé pour le JavaScript et ce à chaque fois qu'on invoque l’URL.
Peut-on gagner en efficacité ? La réponse est oui évidemment, en utilisant le protocole et la capacité du navigateur.
La première chose à faire est de mettre le code JavaScript dans des fichiers séparés
Code javascript : | Sélectionner tout |
function confirm(message) { ..... }
Reste l'utilisation des variables du langage hôte dans JavaScript.
J'ai donné une solution ici, avec celle-ci il n'est plus du tout nécessaire de placer les valeurs des variables du langage hôte dans JavaScript.
En quoi une telle solution peut-elle améliorer l'efficacité ?
Reprenons le déroulement des opérations.
- Le client invoque une URL
- Le serveur déroule son code et produit dynamiquement une source HTML.
- Le client reçoit cette source.
- Il ne peut pas la mettre en cache car elle est dynamique et contient des données variables.
- Il la parse et crée le DOM correspondant.
- Il charge les fichiers JavaScript liés.
- Il met la source JavaScript dans le cache.
- L'interpréteur JavaScript compile le code (partiellement) et le relie au DOM.
- L'interpréteur met en cache le code compilé.
- L'interpréteur met en cache le code compilé.
- La page est disponible pour l'utilisateur.
- L'utilisateur active le code JavaScript par une action (un clic dans l'exemple).
- L'interpréteur JavaScript compile si besoin le code non compilé et l'exécute.
-
- Si l'action est encore invoquée elle est juste exécutée.
- Si l'action est encore invoquée elle est juste exécutée.
Si la page est rappelée, le fichier JavaScript n'est pas rechargé et il n'est pas recompilé.
Du coup diront certains, on se retrouve avec un gros JavaScript qui contient tout les cas alors qu'en générant le JavaScript à la volée, je peux générer la fonction dont j'ai besoin
Code php : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?PHP $Message = '"Hello World!"'; print '<script type="text/javascript">'; print ' function confirm(message) {'; if ($property == 'some value' { print " //ici le code JavaScript dans un cas"; } else { print " //ici le code JavaScript dans l'autre cas"; } print ' }'; print '</script>'; print "<a href='#' onClick = 'return confirm(".$Message.");'>Test</a>"; ?> |
C'est en fait un faux problème. Il suffit de faire plusieurs fichiers JavaScript et d'inclure le bon.
Code php : | Sélectionner tout |
1 2 3 4 5 6 | <?PHP $Message = '"Hello World!"'; print '<script type="text/javascript" src="' . $property . '.js">'; print '</script>'; print "<a href='#' onClick = 'return confirm" . $property . "(".$Message.");'>Test</a>"; ?> |
On a ainsi le code précis de la fonction que l'on veut dans le JavaScript tout en bénéficiant du cache du compilateur JavaScript et du cache du navigateur.
Cet aspect des choses peut avoir de gros effets.
Sur de tout petits JavaScript, ça ne se voit quasiment pas.
Mais ce n'est pas le cas lorsqu'ils se multiplient ou si le code devient plus gros.
Ajoutez les caches réseaux dans l'affaire et la différence peut devenir énorme.
Vous avez sûrement remarqué que certaines applications sur le net sont très lentes à démarrer la première fois et bien plus rapides par la suite.
Imaginez une telle application dont le serveur est à l'autre bout du monde. Tout le code statique, CSS statique, images statiques est mis en cache dans des caches réseau tout au long du parcours (le proxy de l'entreprise fait aussi cela).
Du coup, lorsqu'un autre client vient chercher une de ces ressource et que le réseau la trouve en cache dans l'acheminement de la requête, c'est cette version en cache qui est livrée. Ce n'est donc plus simplement juste entre le client et le serveur qu'on optimise ainsi les transferts mais sur toute la ligne.
Avec JavaScript, il y a en plus le cache du code compilé qui apporte un réel confort à l'utilisateur. L'application devient beaucoup plus fluide et réactive.
A+JYT