Voir le flux RSS

danielhagnoul

[Actualité] JavaScript est-il malade de la compatibilité ascendante ?

Noter ce billet
par , 16/08/2018 à 22h16 (651 Affichages)
JavaScript incorpore sans cesse des nouveautés et des améliorations en assurant une compatibilité ascendante, mais il oublie quelque chose.

L'aspect positif : cela lui permet de faire tourner d'anciens codes.

L'aspect négatif : certains utilisateurs, même de nouveaux utilisateurs du langage, se complaisent à utiliser des vieilleries alors que le langage dispose d'instructions plus performantes, parfois depuis longtemps.

Certes, on fait un peu de ménage de temps en temps (voir fonctionnalités dépréciées), mais est-ce suffisant ?

En dehors des personnes obligées de travailler pour des horreurs dignes du musée, je pense aux anciens navigateurs et principalement à la série des IE, pourquoi utiliser des instructions dépassées ?

Quelques exemples :
  • "var" au lieu de "const" et "let" ;
  • "getElementBy..." au lieu des versatiles et performants "querySelector" et querySelectorAll" ;
  • "on..." au lieu du performant et versatile "addEventListener" ;
  • écrire du code ES2015 et en faire une horreur avec Babel alors que tous les navigateurs d'aujourd'hui sont parfaitement compatibles y compris pour les modules ES2015+.


Je pense que si l'on continue sur la voie actuelle on va créer des "clans" de programmeurs JS (et je n'ai pas parlé des nodistes) qui ne se comprendront plus entre eux, du genre discussions entre utilisateurs de Python branche 2 et de Python branche 3, mais en pire ! Il y a au moins un autre langage qui souffre du même mal : Java.

Je propose deux solutions :
  1. Donner un numéro de version à JS, avec un grand ménage sur les instructions qui existaient avant ES2015.
  2. Réviser le contenu de l'instruction "use strict" dans le sens ci-dessus et promouvoir largement son usage.


La deuxième solution, acte volontaire de l'utilisateur, aurait l'avantage de ne pas trop compliquer le fonctionnement du navigateur.

Qu'en pensez-vous ?

Envoyer le billet « JavaScript est-il malade de la compatibilité ascendante ? » dans le blog Viadeo Envoyer le billet « JavaScript est-il malade de la compatibilité ascendante ? » dans le blog Twitter Envoyer le billet « JavaScript est-il malade de la compatibilité ascendante ? » dans le blog Google Envoyer le billet « JavaScript est-il malade de la compatibilité ascendante ? » dans le blog Facebook Envoyer le billet « JavaScript est-il malade de la compatibilité ascendante ? » dans le blog Digg Envoyer le billet « JavaScript est-il malade de la compatibilité ascendante ? » dans le blog Delicious Envoyer le billet « JavaScript est-il malade de la compatibilité ascendante ? » dans le blog MySpace Envoyer le billet « JavaScript est-il malade de la compatibilité ascendante ? » dans le blog Yahoo

Mis à jour 17/08/2018 à 01h12 par Michael Guilloux

Catégories
Javascript , Développement Web , ES2015

Commentaires

  1. Avatar de Hyome
    • |
    • permalink
    "getElementBy..." au lieu des versatiles et performants "querySelector" et querySelectorAll" ;
    querySelectorAll vs getElementsByTagName
    https://jsperf.com/queryselectorall-...mentsbytagname
    getElementsByTagName: 962 582 895 op/sec
    querySelectorAll: 38 070 op/sec --> 25 284 fois plus lent !

    querySelector vs getElementById
    https://jsperf.com/getelementbyid-vs-queryselector
    getElementById: 837 269 329 op/sec
    querySelector: 3 095 559 op/sec --> 270 fois plus lent !

    Donc querySelector(All) c'est bien pour des selecteur CSS élaborés, mais dire qu'il est performant comparé à getElementBy... est faux.
  2. Avatar de scandinave
    • |
    • permalink
    Pour ce qui est des "vieillerie", il a encore beaucoup de windows 7 + IE en fonctionement crois moi.

    Sinon le mythe de, je limite a mort le langage pour éviter que les dêveloppeur fasse de la merde est vieux comme le monde mais n'a jamais résolu quoi que ce soit.

    C'est au développeur de se former et de se tenir à jour. Ce n'est pas au langage de corriger des lacunes.

    Pour la version, ca existe, tu l'a cité, ça s'appelle ES 2015, 2016 etc.

    Enfin tu cite java. C'est justement sa rétrocompatibilité qui fait ça grande force. Tu es sûr que le code continuera a tourner quoi qu'il arrive. Regarde comment les gens on hurler du passage de angularjs a Angular 2.
    Heureusement qu'il y avait la force de frappe de Google derrière, sinon cela aurait été un échec.

    Bref, pour moi rien n'ai à changé et tout fonctionne. Je ne me sens aucunement limité. Je pense que les mecs qui font Emacscript savent ce qu'il font.
  3. Avatar de sirthie
    • |
    • permalink
    JavaScript est-il malade de la compatibilité ascendante ?
    Ça serait pas plutôt la compatibilité descendante ?

    https://fr.wikipedia.org/wiki/Compat...et_descendante
  4. Avatar de danielhagnoul
    • |
    • permalink
    @Hyome : oui c'est plus lent pour des utilisations basiques dans les tests qui bouclent X milliers de fois la même opération. Mais sur une page web, la différence est à peine perceptible.

    Avantage : il y a les sélecteurs CSS élaborés et la recherche d'éléments dans un autre élément du DOM.

    Les méthodes "getElementBy..." sont celles de l'objet document alors que les méthodes "querySelector" existent sur chaque élément du DOM : Element.querySelector().

    ----

    @scandinave : ES2015 et suivant sont les numéros de version d'ECMAScript pas de JS.

    C'est au développeur de se former et de se tenir à jour. Ce n'est pas au langage de corriger des lacunes.
    L'histoire de Python et de Java montre que sans un mécanisme externe (pour JS, navigateur ne prenant plus en compte les instructions obsolètes) seule une petite partie des utilisateurs suivent et appliquent les nouveautés. La sortie de ES2015 c'était il y a 3 ans déjà.
  5. Avatar de goldbergg
    • |
    • permalink
    "var" au lieu de "const" et "let" ;
    Je ne vois pas ou est le problème a utiliser "var" partout ? Sa impact les perf?
    Et sinon, même sous ie "const" est supporté depuis longtemps.

    "getElementBy..." au lieu des versatiles et performants "querySelector" et querySelectorAll" ;
    "querySelector" est ce qu'il y a de moins performant (en dehors de Jquery qui est encore pire), il y a enormement de test sur jsperf qui le prouvent.
    Les "getElementBy" ne sont surtout pas a écartée si on veut un code optimale...


    écrire du code ES2015 et en faire une horreur avec Babel alors que tous les navigateurs d'aujourd'hui sont parfaitement compatibles y compris pour les modules ES2015+.
    Pour ce point je suis d'accord, je ne comprend pas pourquoi certains s'acharne a absolument utiliser Babel qui génére du code tous moisi...


    certains utilisateurs, même de nouveaux utilisateurs du langage, se complaisent à utiliser des vieilleries alors que le langage dispose d'instructions plus performantes, parfois depuis longtemps.
    Moué, ou pas...
    Les sucre syntaxique tel que "class" n'ont rien de plus performent et n'ont rien d'une évolution (au contraire).
    Comme dit plus haut, ton exemple avec les sélecteur rajoute au contraire de la lenteur (et je ne parle pas des mauvais usage a vouloir faire une sélection via des sélecteur CSS hyper chiadé, la ou souvent on pourrait faire bien plus simple).
    Bref, je ne vois vraiment pas ou est le problème a utiliser des api qui date (mais qui on fait leurs preuves) plutôt que des nouvelles qui ne sont pas forcement top et qui risque d'être déprécié (malheureusement c'est arrivé plus d'une fois...)
  6. Avatar de danielhagnoul
    • |
    • permalink
    @sirthie : j'ai pris exemple sur le titre du livre sur Java, mais en effet mon choix est discutable.
  7. Avatar de grunk
    • |
    • permalink
    "var" au lieu de "const" et "let" ;
    const et let n'ont pas vocation à remplacer var. var n'est pas devenue une vieillerie avec l'apparition de const et let

    const= constante
    let = variable à portée limitée au bloc , ce qui est parfois très bien mais peux aussi être génant auquel cas var prend du sens.
    const et let sont donc des ajouts très intéressant au langages, mais ne remplaceront pas var

    écrire du code ES2015 et en faire une horreur avec Babel alors que tous les navigateurs d'aujourd'hui sont parfaitement compatibles y compris pour les modules ES2015+.
    J'ai eu le cas récemment avec IE10 et 11 qui sont supposé être compatible ES2015 et qui ne supporte pas TypedArray.prototype.slice(). Peut être que dans ce cas précis j'aurais évité un beau bug


    Pour ce qui est de la compatibilité , comment on fait avec tous les sites écrit en js non moderne ? Du jour au lendemain on condamne des millions de sites ? Plein de petits sites sont en ligne , utiles mais non maintenu pour X raisons.

    Quand on commencera à avoir des utilisateurs qui utilisent que des navigateurs evergreen on pourra envisager de casser la rétrocompatibilité , mais je pense qu'on à encore quelques années de souffrance devant nous , en particulier dans le monde pro.

    Perso je vois pas le mal à gardé d'anciennes fonctionnalités à partir du moment ou elle ne mettent pas en péril le langage. Après libre à chacun d'être formé et d'utiliser les dernières nouveautés ou non. C'est comme en C++ tu peux faire un programme en C++98 comme en C++17. Idem en JAVA. La seul contrainte que ça apporte c'est éventuellement de freiner l'adoption des nouvelles versions (on change pas quelque chose qui marche).
    Mis à jour 17/08/2018 à 11h59 par grunk
  8. Avatar de melka one
    • |
    • permalink
    on..." au lieu du performant et versatile "addEventListener
    addEventListener a été créé après les evenements on.... pour palier au problème de cumule d'evenement le plus connu étant onload qui cumulé supprime l' evenement onload précédent et sa permet simplifie la mise en place de plusieurs scripts. removeEventListener donne la possibilité de supprimer l'execution d'une fonction sans retirer l'evenement complètement
  9. Avatar de lmontout
    • |
    • permalink
    C'est au niveau de ton éditeur de code de te suggérer des évolutions de codes pertinents.
    J'aime bien les outils (langage, edi, progiciel etc....) qui me garantissent de bien fonctionner à chaque montée de version sans passer des mois à lire les "breaking changes" et à imaginer les patch.
  10. Avatar de Grulim
    • |
    • permalink
    2 choses me choquent :
    1) Babel qui produirait du code moisi : Babel transpile le code de façon conforme au proposition du TC39 (cf https://github.com/babel/proposals).
    2) Je produis pas mal de code JS, je dois bien dire que je ne vois plus l'utilité de var (et très peu let).
  11. Avatar de SylvainPV
    • |
    • permalink
    Il existe une solution pour distinguer les environnements "modernes" des dépassés, et utiliser directement du JS moderne tout en préservant la compatibilité grâce à Babel et aux polyfills: <script type="module"> et <script nomodule>. C'est ce que propose le framework Vue.js avec son option Modern Build: https://cli.vuejs.org/guide/browser-...ml#modern-mode
  12. Avatar de Namica
    • |
    • permalink
    Je propose deux solutions :
    1. Donner un numéro de version à JS, avec un grand ménage sur les instructions qui existaient avant ES2015.
    2. Réviser le contenu de l'instruction "use strict" dans le sens ci-dessus et promouvoir largement son usage.
    Belle idée, mais quel système de version ? Celui de I.E., de Firefox, de Chrome, autre... ? Et ça ne résout pas le problème des sites anciens.
  13. Avatar de danielhagnoul
    • |
    • permalink
    @grunk :
    const et let sont donc des ajouts très intéressant au langages, mais ne remplaceront pas var
    Je vous assure que var est la cause de bien des problèmes (par exemple : la portée globale, la déclaration de paramètre après usage dans une fonction, la perte de la valeur d'un paramètre dans une boucle). La portée bloc est un plus indéniable, car elle impose plus de rigueur et permet de concevoir des arrangements de code impossible autrement.

    J'ai eu le cas récemment avec IE10 et 11 qui sont supposé être compatible ES2015
    Non compatible ! Obsolète ! Abandonné par Microsoft : https://www.microsoft.com/fr-fr/wind...-of-ie-support

    Pour ce qui est de la compatibilité , comment on fait avec tous les sites écrit en js non moderne ? Du jour au lendemain on condamne des millions de sites ? Plein de petits sites sont en ligne , utiles mais non maintenu pour X raisons.
    Avec la première solution : il suffirait d'indiquer au navigateur d'utiliser la version JS adéquate.
    Avec la seconde solution : il suffit de ne pas utiliser l'instruction "use strict".

    La seul contrainte que ça apporte c'est éventuellement de freiner l'adoption des nouvelles versions (on change pas quelque chose qui marche).
    Cette réflexion illustre mon propos, c'est un signe indéniable de la maladie de JS.
  14. Avatar de danielhagnoul
    • |
    • permalink
    @SylvainPV :
    Il existe une solution pour distinguer les environnements "modernes" des dépassés, et utiliser directement du JS moderne tout en préservant la compatibilité grâce à Babel et aux polyfills: <script type="module"> et <script nomodule>.
    C'est pratique pour les utilisateurs qui utilisent ES2015+ et qui veulent fournir aux navigateurs obsolètes une solution de repli.

    Je connais et j'ai déjà utilisé. C'est justement à ces occasions que Babel produit ce que j'appelle des "horreurs".

    Si vous êtes soucieux de performance, comparer donc un code, non simpliste, en ES2015+ et sa traduction ES5 par Babel.
  15. Avatar de SylvainPV
    • |
    • permalink
    Le loose mode de Babel permet de bien simplifier le code ES5 produit, même s'il n'est pas 100% spec compliant et donc introduit un risque de régression. Après, les "horreurs" ne m'ont jamais trop dérangé puisque j'utilise Babel uniquement pour le build de production aux côtés de Uglify, donc j'ai un code imbitable dans tous les cas à la fin. Mais je n'ai jamais constaté de régression entre ES6 et ES5 transpilé. Le code est peut-être illisible, mais il fonctionne impec. Certes au prix de ~30/40% de taille de bundle et de coût à l'éxécution.

    Je pense que la technique du script module est un bon compromis qui devrait donner un résultat acceptable pendant quelques années, le temps qu'IE meurt pour de bon (allez on y croit). Les nouveaux navigateurs grand public ont tous des mises à jour auto, ça devrait réduire considérablement le travail de Babel avec le preset-env.

    Pour ce qui est de supprimer des parties du langage dans les versions de JS, je ne pense pas que ce soit une bonne idée. Il faut comprendre pourquoi ces parties sont obsolètes, avant de juger qu'elles doivent être éliminées. Par exemple, l'instruction `with` est coûteuse et confusante, et donc déconseillée à l'usage. Mais elle est utilisée en minification pour réduire la taille du code, dans des cas où le coût à la compilation est négligeable par rapport au gain en taille. Donc l'instruction reste utile, même s'il ne faut plus l'utiliser en développement. De la même façon, certaines instructions sont moins pratiques à l'usage mais plus performantes, comme les `getElementsBy`. Elles ont donc tout à fait leur place dans le code de bilbiothèques/frameworks, mais moins dans du code utilisateur.

    Au final, le "nettoyage" du langage est plus un travail à faire du côté de la formation, des linters et des précompilateurs, que du langage lui-même. Maintenir plusieurs subsets du langage au sein d'un compilateur JIT est aussi compliqué, voire davantage, que de maintenir le code des instructions dépréciées. Mais ça ne devrait surprendre personne, c'est une habitude en informatique de construire par-dessus les ruines du passé (cf modèle OSI).
  16. Avatar de Nothus
    • |
    • permalink
    Entièrement d'accord avec tous les points indiqués par l'article.

    J'y ajoute mon grain de sel :

    (1) j'utilise addEventListener, et c'est une plaie pour une raison : il dédouble les fonctions (et c'est si c'est ma volonté d'avoir des doublons?), sans pouvoir lister ce qui existe déjà (on ne choisit pas). Pour le coup, un tableau de fonctions à appeler en callback m'aurait semblé plus indiqué pour une utilisation dans un contexte où souvent les scripts se chevauchent, permettant de retirer plus aisément les fonctions ajoutées (retirer une fonction anonyme c'est juste galère... ou alors je m'y prends mal ?!)

    (2) JS "confond" synchrone et asynchrone. Python a cette avantage que tu déclares une boucle d'événements, que tu peux contrôler, et qui finalement rend très transparent le contexte du code lorsqu'il est développé. JS c'est directement intégré à l'architecture du logiciel si j'ai tout bien suivi (?). Au quotidien, entre callback/setTimeout ou Promise, code synchrone et asynchone, c'est juste le foutoir. Avis très personnel qui n'engage évidemment que moi...

    (2') IndexedDB est un exemple parlant : la doc du MDN prévoit un abandon du synchrone, alors qu'on a mis en place les Workers pour éviter la complexité de l'asynchrone. Résultat on a le doublon Worker et des API plus ou moins asynchrones, non-normés. Je ne comprends pas la logique.

    Le problème de JS me semble être avant la "limite" de ce qu'il entend être, en ajustant ainsi ses qualités et ses défauts à un cadre plus rigide, particulièrement dans un contexte client Web.