Dans le monde de la compilation, il en existe 2 approches différentes : compilation statique et compilation dynamique. Si les langages et l'approche ne sont pas identiques, il s'agit de compilation, donc de compiler du code et d'exécution le code.
Typiquement, C++, C ou encore le Basic utilisent une compilation statique pour générer le code machine et l'exécutable. En compilation dynamique, le code sera transformé en bytecode. Il s'agit d'une représentation intermédiaire qui pourra être exécuté par un interpréteur ou JIT (compilateur Just In Time). L'exécution JIT nécessaire un runtime d'exécution, typiquement une JVM, CLR. Cette approche dynamique se retrouve en JavaScript, Python, Java, C#. Nous trouvons cette approche dans les langages interprétés.
Max Shahdoost (sur Medium) résume bien les 2 approches :
Approche JIT :
En JavaScript, le principe est le modèle dynamique car JS est un langage interprété nécessitant un moteur d'exécution (typiquement inclus dans le navigateur) et éventuellement un JIT pour améliorer les performances. Tous les moteurs JS récents intègrent un JIT qui évite de tout (re)compiler à chaque fois.
Max Shahdoost résume ainsi l'architecture d'exécution moderne dans le monde JS :
Modèle type d'un compilateur statique (exemple en C++) :
Une autre tendance, en complément ou pour remplacer le JIT, est la compilation dite AOT (Ahead of Time). IBM présente ainsi l'approche AOT : "La compilation AOT (ahead-Of-Time) permet de compiler les classes Java en code natif pour les exécutions ultérieures du même programme. Le compilateur AOT fonctionne avec l'infrastructure de partage des données des classes.Le compilateur AOT génère le code natif dynamiquement lorsqu'une application s'exécute et met en cache le code AOT généré dans le cache des données partagées. Les machines virtuelles Java suivantes qui exécutent la méthode peuvent charger et utiliser le code AOT depuis le cache des données partagées sans subir les pertes de performances associées au code natif compilé par JIT."
Si nous prenons l'exemple d'Angular, il intègre un AOT. Le projet le définit ainsi : "Le compilateur AoT d'Angular convertit les codes HTML et TypeScript en code JavaScript (plus) efficace pendant la phase de build avant le chargement (du code) sur le navigateur et son exécution. La compilation de votre application durant le phase de build permet un rendu plus rapide dans le navigateur".
En Angular, voici l'approche JIT vs AOT :
On constate que le flux de compilation n'est pas identique. Un des arguments de l'AOT est que la compilation du code est déjà faite comme on builde (réellement) son application. Et il n'y a pas de runtime d'exécution qui prend la main pour le run.