Ce billet fait partie de la série « Dirty Hacky ». Le but de cette série est un objet critique sur les astuces de web-développement, et n'a pas pour vocation d'être une recette définitive, mais d'attirer l'audience par la polémique technique.
BANG! BANG! BANG!
- Je parse en HTML .357 S&W
- Commentaires conditionnels
- Magouilles dans les CSS
- Des confettis troués en CSS
- Liens serrés dans la police
- Des Bleus et des Boss
- Exécutions très rapides
- Le script des bas-fonds
- Préfixes frelatés
Javascript, du moutard à l'adolescent à problèmes
C'est avec Netscape Navigator 2, circa 1995, qu'arriva la balise <script></>
, la première implémentation d'un web dynamique côté clients. À cette époque, où les designs d'hommes allaient se faire en tables, le Javascript nouveau-né s'appelait encore LiveScript
. Cette idée marchant bien, la balise fut indiquée comme usage futur
lors de la tentative de standardisation du HTML numéro 3.2. Puis dans la standardisation “ferme” HTML 4, la balise <script></>
était prévue pour que tout langage puisse être installé. Il me semble que les exemples donnés étaient Tcl/Tk et Visual Basic. Ahem… C'est dire combien on en était déjà très optimiste quant à l'éventuelle unification multi-plateforme du web…
Dans les faits, seul Javascript fut implémenté. Ouf…
On ne va pas revenir sur les tristes différences entre JScript (l'implémentation incomplète de Microsoft) et la norme ECMA, les incohérences propres à javascript et les retards et défauts présents dans l'interpréteur V8 de Google face à celui de Firefox.
Avant d'aller plus loin, cet excellent article explique comment il fonctionne en interne, quels sont les étapes d'interprétation du Javascript dans un navigateur, et les astuces d'optimisations, notamment de V8, pour en accélérer l'exécution.
Les limites dans l'optimisation actuelle
Nous allons de plus en plus vers de réelles applications web. On est désormais capable, uniquement en utilisant des technologies JS/HTML5/CSS/SVG/WebGL, de faire de la transmission vidéo temps-réel, une suite office quasi complète, des services de messageries instantanées et même des meuporg, euh pardon des mmorpg.
Le projet FirefoxOS montre qu'il est possible de concevoir un client graphique e-mail complet (POP3, SMTP,…) en servant uniquement des pages HTML statiques et du javascript uniquement client.
Seulement pour sauter le pas vers l'embarqué, et rendre caduc le principe de l'application fournie via un store propriétaire, il faut aller vers plus de performance, donc à rendu comparable, moins de consommation batterie.
Falsification de preuves
Bien évidemment, les navigateurs se font la course, une saine concurrence. Pour illustrer ce gain, j'aurais pu ici intégrer un graph des performances gagnées à travers les années.
En réalité, ces métriques sont systématiquement pris en défaut par la suite, voire du code est spécialement préparé pour péter des scores faramineux sur certains tests. Depuis 15 ans, cette lamentable escroquerie existe dans le domaine des cartes graphiques 3D ou les calculs en Téraflops car la mesure de kikis performances est devenu un argument commercial.
Depuis 5 ans, on commence à voir quelque(s) navigateur(s) magouiller. Par exemple, si les sélecteurs d'éléments DOM est un goulet de perfs (ce qui ne concerne pas le javascript pur mais son interface), très rapidement des tests se mettent en place. Assez vite, certain navigateur tentera d'y briller mieux que les autres, avec des soupçons d'“arrangements” confinant au dopage, voire à la triche. Les performances semblent donc superbes, mais dans les faits… pfiiiuuuiiit…
Ça en devient encore plus piquant quand une étude financée par Microsoft en conclut que les tests de benchmark javascript sont très éloignés des cas habituels d'utilisations de navigateur. Étant le seul moteur Javascript en closed-source, donc non auditable, faisant des scores théoriquement faramineux mais assez tristes en usage normal, c'est assez… salé.
NaCl : Et Google dégaine le sel du binaire natif
Merci de ne pas applaudir cette transition…
En 2010, Google propose une technologie, dite native client. Elle consiste non plus à envoyer un code source à interpréter mais directement un binaire à exécuter, le langage processeur pur. Le code d'origine étant écrit en C ou C++, on est donc théoriquement au plus près de la performance processeur, et on peut accéder à toute l'API du navigateur hôte et, normalement ce code ne peut sortir vers l'OS hôte. Évidemment on est alors à des vitesses d'exécutions absolument démentielles face à un langage interprété.
Le concept est intéressant, mais il pose plusieurs questions :
Ne revient-on pas finalement au principe de l'infâm la balise <object></>
, celle que justement tente de faire disparaître le concept HTML5 ?
Que fait-on quand le processeur hôte n'est pas celui pour lequel est compilé ce code ? Justement, là aussi, on parle de fragmentation. S'il n'existe pratiquement plus que deux plateformes processeurs dominantes (x64 d'Intel pour le desktop et les franchisés Arm pour l'embarqué), que fait-on en cas de revival PowerPC ou si des multicores CUDA de NVidia deviennent les nouveaux CPU ? On en revient au gros problème des plateformes différentes et incompatibles, ce qui est contraire au concept même du web où un seul et unique code doit pouvoir “tourner” n'importe où.
Comment auditer le code ? La question est éludée par une certaine frange de développeurs imberbes, puisque le code est censé s'exécuter dans un environnement virtualisé. Ouuuiiii maaaaais les évasions de machines virtuelles sont des failles parfaitement pratiquées depuis 2006. Et qui a déjà passé du temps à désassembler du code binaire malicieux sait combien les méthodes actuelles d'obfuscations sont absconses. Bon, il est vrai que du javascript malicieux, ça existe aussi, mais ça peut se repérer plus vite, et on peut aisément invalider des API dans un contexte de page web (c'est comme ça qu'est gérée la sécurité de Firefox OS).
Bref, en prenant un certain recul, on y voit un concept qui est bancal, à mon sens.
Origine | GOOD |
Élégance | BAD AND RETRO |
Modernité | TRENDING |
Postérité | MIDDLE |
asm.js : Mozilla compile un javascript simplifié
En 2012, Mozilla “répond” à Google en proposant asm.js. L'idée est que sur les très gros projets clients web, si des équipes souhaitent travailler en C/C++, ils compileront en asm.js plutôt qu'en binaire.
La technologie asm.js consiste à auditer la manière dont le code javascript va être exécuté. On y trouve quelques nouveautés comme le typage de valeurs et d'objets dans une notation dégradables. Mais l'essentiel est une restriction, un subset du langage javascript, d'en écarter les constructions les moins évidentes à optimiser. Il suffit d'indiquer en début de source ou de bloc d'instructions une directive. Comme suit :
"use asm" ;
Cette directive, à rapprocher de "use strict";
, est vue comme une insignifiante chaîne sans assignation par les navigateurs un poil daté. Et si le code ne correspond pas à ce subset tel qu'il est décrit, le navigateur remonte dans un mode d'exécution interprété. Cela ne prête donc pas à un risque d'incompatibilité, mais demande juste une meilleure maîtrise de l'écriture par le développeur de la webapp.
Là où le concept est extrêmement élégant, c'est qu'il contient son propre fallback. Le code source est exécuté par pratiquement tous les navigateurs sans aucun souci. Il repose non pas sur des ajouts de Javascript, mais au contraire, sur un jeu d'instruction réduit. Une partie de ces règles de constructions sont parfaitement identifiées depuis 5 ans, l'autre partie vient par les développeurs de moteurs javascript sur les fonctions très difficilement optimisables en opcodes.
Origine | GOOD |
Élégance | EXCELLENT |
Modernité | TRENDING |
Postérité | LONG |
T'as beau courir, l'Inspecteur te rattrapera
Bien évidemment, asm.js ne sera peut-être jamais aussi rapide que NaCl. Mais je trouve que le pari de cette dernière moins probant, et je pense qu'on arrivera au moment où le navigateur s'optimisera en fonction des jeux d'instructions CPU/GPU/APU.
Allez, je vais être franc, c'est pas uniquement un parti pris qui m'a animé, mais réellement un besoin de comparer les deux technos pour d'éventuels projets lourds. Et j'ai beau retourner dans tous les sens, je vois moins le futur de NaCl que d'asm.js. J'ai essayé d'avoir le plus de recul possible afin de ménager mes chances de me faire recruter par Google. Si Owen Wilson y arrive…
C'est dire ;)
To be continued
Dans le prochain épisode, nous débusquerons le javascript des bas-fonds.
Si vous pensez pouvoir me battre à la course, assurez-vous d'aller assez vite pour éviter les balles de mes commentaires ↓