Journal Réflexion sur ASM.js ou quand le javascript deviens enfin performant :

Posté par . Licence CC by-sa
42
20
mar.
2013

Sommaire

Comme suggéré, je transforme mon message du forum en journal.

Tout d'abord, pour info et pour être honnête, ce qu'il faut savoir sur moi, c'est que je ne suis pas le plus grand fan de la prochaine version de javascript, bien que la plupart des améliorations soient une réelle avancée, d'où mon affection pour typescript de microsoft ( je sais, je sais…). Cependant, d'autres fonctionnalités me paraissent un peu compliquées pour les plus-values qu'elles apportent, surtout quand on sait que js est devenu le bytecode du web : pour moi les guards en sont un parfait exemple. Le javascript deviendrait-il le nouveau C++ ?

introduction

Pour le meilleur ou pour le pire, javascript est devenu incontournable. Néanmoins, malgré les efforts constants des navigateurs pour améliorer le moteur, il reste extrêmement lent dans certaines situations, et ce, à cause de certaines limitations intrinsèques au langage (comme le boxing, le garbages collector…). Jusqu’à présent, mozilla refusait un peu la réalité. Lorsque dart est sortie, le seul argument qui me paraissait honnête était le coût de maintenance non négligeable à ajouter à l'existant. Pour native client, l'argument était plus évident : les binaires ou bytecodes n'étaient pas l'idéal pour le web qui est supposé être ouvert tout en introduisant une nouvelle technologie à maintenir. Ainsi, la réponse au problème de la part de mozilla a enfin était annoncé sous le nom d' asm.js: un sous-ensemble de javascript qui permet enfin d'avoir des performances proches de native client (et aussi une protection mémoire similaire du code compilé à la volé dans certain cas…). Cet exploit est réalisé grâce à quelques astuces syntaxiques qui permettent de donner des indices de typages des variables,des restrictions dans les fonctionnalités les plus coûteuses ainsi que l'utilisation d'un buffer (typeArray) comme heap dans le programme pour éviter tout problème de garbage collector…

avis

J'avoue être très agréablement surpris par cette solution : ce n'est que du javascript, ainsi le fallback est évident à mettre en place car il sera exécuté par tout les navigateurs sans aucune modification. Pour toute personne intéressé par le sujet, je vous propose d'aller voir le blog suivant

Cependant, pour un développeur qui aime le bas niveau et le web, tout n'est pas parfait.Tout d'abord, il n'existe que deux types classiques le int et le double. D'après moi, cette restriction provient du moteur même de firefox (spidermonkey/ionmonkey) qui est lui-même limité à ces types. Il existe d'autres raisons plus obscures qui n'ont de sens que si vous pensez à l'implémentation (les type boolish/intish…). De mon point de vue, ce défaut mineur sera probablement corrigé lorsque les implémentations seront plus matures et que les interactions entre la partie codée en asm.js et javascript seront définies plus strictement. En effet, asm.js permet d’interagir directement avec votre moteur javascript sans passer par des tableaux de bytes, provoquant un besoin de définir les interactions entre le code du js optimisé et le js interne (appelé ffi pour les plus curieux).

Personnellement, j'aurai vu uniquement des ArrayBuffer comme entrée et sortie, ce qui aurait eu l'avantage de simplifier le tout mais surtout de permettre une plus grande souplesse dans les types à l'intérieur du programme optimisé et d'être déjà paré pour les structure binaires d'harmony.

D'après moi, il faut bien se l'avouer et en avoir conscience, si asm.js est implémenté dans les navigateurs, la prochaine étape pour avoir des performances sera bel et bien le parallélisme. Et c'est bien ça le problème, bien que nous possédions déjà le parallélisme de tâches grâce aux webworkers, il nous manque encore le parallélisme de données ou quelque chose d'encore plus évolué (genre SPMD ). Certains me dirons que ce dernier sera géré en partie par rivertrail. A ceci, je répondrai seulement que l'API est relativement restrictive et que je préférerai une approche plus proche d'OpenCL/Cuda : j'aurais adoré voir asm.js exécuté sur GPU ou CPU au choix, avec un « hint » pour le compilateur, surtout que passer le sous-ensemble MIR/LIR d'ASM.js en code C pour GPU est relativement simple. J'aurais aussi aimé que les typedArray qui sont utilisés comme arguments soient la mémoire globale (CPU ou GPU) avec de simples mutex et que le compilateur soit capable de gérer les heaps comme des caches bas niveaux (un peu comme la mémoire privé d'OpenCL ou les registers en C)….

Concrètement, c'est faisable?

Techniquement, cela n'est pas très difficile à réaliser[1] mais avec l'évolution envisagée qui est de dire qu'asm.js doit faire de plus en plus de choses et ne pas rester si limité comme sous-ensemble du javascript, je crains que ce ne soit qu'un vœu pieu (avec par exemple les pointeurs de fonctions qui ne sont pas possibles sur tout les GPU sans créer une sorte de vtable à la main). C'est un point que je comprends d'autant moins que le but du projet était bien d'avoir un sous-ensemble du javascript le plus optimisé possible tout en gardant l'aspect sécurisé de ce dernier, bien entendu.
Tiens, tant qu' à rêver, pourquoi ne pas avoir, un jour, un code javascript capable de faire de l’auto-vectorisation si rapide que l’exécutable serait plus rapide que celui compilé par GCC grâce au parallélisme et cela, sans même que le développeur n'ait rien à faire ( comme avec sumatra )

[1] On parle ici de prendre le code assembleur généré par le moteur javascript, d'avoir quelques hooks sur les fonctions essentielles (math/ threadid…) et de lancer cela à partir d'un threadPool. Après il faut aimer bidouiller dans le moteur js, mais ce n'est pas si difficile (regarder pour comprendre comment ajouter des API et ceci pour voir comment utiliser le code natif -> cela n'est pas plus compliqué que ce que l'on trouve ailleurs. En plus, cela permettrait de mutualiser avec ce qui pourrait être fait pour WebCL, non? Bon mais c'est un peu fastidieux à faire et pas le plus sexy à faire avant de dormir).
Allez dés que je trouve le temps (probablement pas avant quelques semaines), je fais un prototype.

Un avis sur le sujet? Quelqu'un qui serait intéressé?

  • # Gni? on est déjà en 2023?

    Posté par (page perso) . Évalué à 3.

    Un avis sur le sujet? Quelqu'un qui serait intéressé?

    Ben comme tu sembles vouloir accélérer internet, je suis preneur, mon Pentium 4 n'y a pas suffi.

    ⚓ À g'Auch TOUTE! http://afdgauch.online.fr

  • # Bidouille

    Posté par (page perso) . Évalué à 6.

    Toutes ces solutions ressemblent quand même à de la grosse bidouille. On obtiendra peut être un gain en performance, mais:

    • jamais autant qu'avec un vrai langage.
    • au prix d'un code source dans la page peu lisible.

    Depuis des années, on a bidouillé une plateforme faite pour servir des documents en sandbox d'applications.

    Il est peut être temps de trancher dans le vif et de pouvoir enfin écrire quelque-chose comme:

    <script type="text/rust" >
    
    

    http://devnewton.bci.im

    • [^] # Re: Bidouille

      Posté par . Évalué à 1.

      jamais autant qu'avec un vrai langage.

      C'est vrai ça, il y a les vrai langages de programmation, pour les Hommes, les vrais, et les faux langages de programmation, pour les lopettes.

      Je ne comprends vraiment pas cette vindicte générale contre les langages interprétés comme javascript, python, etc… C'est trop accessible ? Pas assez 1337 ?

    • [^] # Re: Bidouille

      Posté par . Évalué à 3.

      Il y a de plus en plus de compilateurs vrai langage -> javascript, par exemple js_of_ocaml (pour ocaml) ou fay (pour Haskell). Je ne sais pas s'il est facile pour eux d'avoir asm.js plutôt que js comme cible. Pour ce qui est de rust, ça m'étonnerait que mozilla ne développe pas un truc du même type si le langage prend (et s'ils décident que ça vaut le coup d'y allouer plus de ressources).

      Du coup, la GPLv3 prend son importante, puisque le javascript n'est plus le code source.

      • [^] # Re: Bidouille

        Posté par . Évalué à 2.

        Du coup, la GPLv3 prend son importante, puisque le javascript n'est plus le code source.

        Oui, c’était déjà problématique dans le cas de GWT (Google Web Toolkit) et/ou GXT.
        Il me semble que RMS en avait parlé d'ailleurs.

    • [^] # Re: Bidouille

      Posté par . Évalué à 9.

      Merci pour les retours.

      jamais autant qu'avec un vrai langage.

      Je ne suis pas sûr de comprendre la remarque. On a un code dont la représentation me permet de créer un IR vraiment proche de ce que tu aurais avec du code C bas niveau généré par clang . Du coups, je ne vois pas en quoi le langage est un problème ici…
      Les cas que je vois sont par rapport au C/C++, lorsqu'on utilise des fonctionnalités bas niveaux (comme SSE…). Sauf qu'avec ces optimisations, tu n'es plus portable, c'est à dire plus dans le navigateur.

      au prix d'un code source dans la page peu lisible

      Tu peux aussi voir asm.js comme un tout nouveau langage dédié à l’efficacité, une sorte de bytecode du web. Partant de ce constat, je le trouve vraiment très très lisible comme représentation intermédiaire (comparé à llvm IR, le bytecode java…).

      Il est peut être temps de trancher dans le vif et de pouvoir enfin écrire quelque-chose comme:

      Ici, on parle d'avoir des performances. Avec Rust ( ou même dart/java/C++ ), si tu veux des performance, tu vas définir un sous ensemble à utiliser.Pourquoi ne pas simplement le faire directement dans le langage déjà utilisé ?

      Depuis des années, on a bidouillé une plateforme faite pour servir des documents en sandbox d'applications.

      Depuis des années, on améliore un produit plutôt que d'écrire des pseudo révolutions toutes les 5 minutes. C'est plutôt un bonne chose de mon point de vue. Finalement, je ne suis pas d'accord que ce soit un problème, mais je n'ai pas d'argument vraiment pertinent donc, je vais considérer que je me trompe.

      Maintenant, je ne suis pas chez mozilla, mais personnellement, je ne vois Rust comme une solution viable et intégrable rapidement pour répondre aux problème de performance, je préfèrerai avoir directement du C sandboxé.

  • # emscripten

    Posté par (page perso) . Évalué à 10.

    Puisqu'on en est à parler d'asm.js, une petite note pour emscripten qui permet de compiler du bytecode LLVM (qui peut être généra avec du C/C++) en javascript et qui utilise asm.js.

    Kate a été porté en javascript avec, c'est relativement impressionnant quand on pense que ça implique de porter Qt et plusieurs bibliothèques kde: http://kate-editor.org/2013/03/16/kate-vim-mode-papercuts-bonus-emscripten-qt-stuff/ et http://vps2.etotheipiplusone.com:30176/redmine/emscripten-qt-examples/kate-testing/kate.html .

    Il y a une liste de projets portés ici: https://github.com/kripken/emscripten/wiki . On peut noter des jeux comme Supertux, Sauerbraten (3D), des interprètes comme Python ou Ruby, des kits logiciels comme Qt, ou encore des bibliothèques/utilitaires comme SQLite, zlib, gnuplot, etc.

    D'après le site, les performances sont 4 à 5 fois plus lentes que du code natifs (jusqu'à 10 fois plus lent dans les plus mauvais cas), mais on devrait rapidement tourner autour des 2 fois plus lent.

  • # soit dit en passant

    Posté par . Évalué à 5.

    Pour le meilleur ou pour le pire

    Pour le pire. L'entreprise d'accélération de JS lancée par Apple à partir de 2005 est une abomination.

    Naviguer sur une page revient maintenant, grâce à des gens de bonne volonté comme toi, qui prennent prétexte de l'extension de ce fléau pour l'aggraver, à faire de ses processeurs autant de noeuds potentiels d'un supercalculateur dont personne ne peut rien savoir.
    N'importe quel amateur peut mettre en place un réseau distribué de Web Workers transparents (cf. http://blog.0x82.com/2010/11/22/map-crowd-reduce/), qui asservit peut-être toutes les ressources de ta machine, pour ce que tu en sais, au programme nucléaire iranien ou pire encore, à l'élaboration du prochain Stephenie Meyer.

    Donc, plutôt que de poursuivre tes investigations dans ce sens, je t'encourage à te tourner vers des tâches collectivement utiles et éthiquement recevables, comme la lutte contre cet état de fait - ou à défaut, vers la culture des tomates (la noire de russie est succulente).

    • [^] # Re: soit dit en passant

      Posté par . Évalué à 2.

      Noire de Crimée, plutôt, non?

      • [^] # Re: soit dit en passant

        Posté par . Évalué à 1.

        Ca ne l'empêche pas d'être succulente :)

      • [^] # Re: soit dit en passant

        Posté par . Évalué à 1.

        la Crimée est très jolie, mais c'est pas la plus goûteuse des noires…
        je recommande plutôt la Charbonneuse de Russie (j'en ai 25 pieds au semoir)
        :-|°°

    • [^] # Re: soit dit en passant

      Posté par . Évalué à 2.

      Au moins avec JavaScript, on peut facilement lire le code source et tracer les connexions réseau. De plus les navigateurs permettent de suivre de plus en plus facilement les ressources utilisées par chaque site ouvert.

      A mon avis, ce qui va plutôt se passer, c'est un transfert d'une partie des calculs des serveurs aux clients afin d'économiser sur les serveurs. Tout en gardant la supervision sur les serveurs afin de contrôler les données et d'enregistrer les activités des utilisateurs.

      Cela n'empêchera pas les utilisations malveillantes et le vol de temps de CPU, mais je pense que ça restera marginal. Dans le cas contraire, il faudra que les éditeurs de navigateurs ajoutent plus de contrôle. Mais je le répète, je pense pas qu'un tel réseau puisse se mettre en place à grande échelle ou sur des grands sites sans être repéré.

      Ton lien est intéressant, il montre un exemple où l'utilisateur choisit de participer aux calculs. Mais je me demande s'il existe des cas où une utilisation malveillante sans avertir l'utilisateur a été détectée, et quels sont les résultats.

      Je travaille justement sur l'implémentation en JavaScript d'une architecture logicielle qui est par définition optimisée pour l'exécution en parallèle de plusieurs processus (entity.JS). Malheureusement les web workers ne sont vraiment adaptés qu'à des tâches travaillant sur des données disjointes ou dont le coût du transfert de données vers les web workers et retour, est inférieur aux coûts en calculs. Des améliorations dans ce domaine seraient donc très bénéfiques.

      • [^] # Re: soit dit en passant

        Posté par . Évalué à 2.

        La transparence des sources ? je pense que ça te fait une belle jambe quand la plupart du JS est camouflé, compressé, utilise un framework lourd qui change complètement la sémantique, ou n'est plus qu'un bytecode illisible issu d'un des innombrables compilateurs depuis le langage X..

        Quant à la différence entre "utilisation malveillante" et "transfert d'une partie des calculs des serveurs aux clients", ce n'est qu'une question de point de vue - c'est à dire que c'est exactement la même chose.

        Aujourd'hui même, il est impossible de laisser 50 onglets ouverts sur des sites parfaitement banals sans mettre un octo coeur à genoux, tout cela parce que les acteurs de l'industrie ont transformé à dessein le JS en outil d'annexion des ressources de calcul individuelles. Ça n'a donc rien d'une vue de l'esprit ou d'une projection dans l'avenir.

        Améliorer la vitesse d'exécution de JS, ou sa parallélisation, sous quelque angle que ce soit, ne fait qu'empirer une situation déjà désastreuse en rendant la déportation des calculs sur le client toujours plus rentable.

      • [^] # Re: soit dit en passant

        Posté par (page perso) . Évalué à 4.

        Au moins avec JavaScript, on peut facilement lire le code source

        J'ai bien rit.
        Sérieux, tu as déjà essayé de jeter un oeil au code JS des sites?

        A mon avis, ce qui va plutôt se passer, c'est un transfert d'une partie des calculs des serveurs aux clients afin d'économiser sur les serveurs.

        Yep, super, après on sait pourquoi il faut une machine de guerre pour afficher une page surtout vu les perfs de JS… Bon, certes l'avantage est que les machines de guerres sont de moins en moins chère, mais bon ça reste du gaspillage quand même.

        • [^] # Re: soit dit en passant

          Posté par . Évalué à 3.

          C'est vrai que quand on utilise NoScript, et les bloqueurs de pub, on se rend moins compte de la lourdeur des pages web. J'ai pas un ordi spécialement puissant et pourtant j'ai souvent plusieurs dizaines d'onglets ouverts dans plusieurs fenêtres sans problème.

          Ok, vous avez tout à fait raison pour la minification du JavaScript. Il y a des déminificateurs, et des beautifiers de code, mais si on veut, on peut facilement rendre un code complètement illisible. Ca n'empêche pas de pouvoir suivre les connections réseau par exemple.

          A mon avis, ce qui va plutôt se passer, c'est un transfert d'une partie des calculs des serveurs aux clients afin d'économiser sur les serveurs.

          Ce n'était qu'une prédiction personnelle, pas un jugement sur ce qui serait mieux ou pas. Mais bon dans le contexte, c'est pas forcément compréhensible :)

          Dans l'absolu, je ne suis pas contre le transfert de calculs vers les clients. Déjà, vu que ça se fait dans une sandbox, les risques sont limités, ce qui n'a jamais été le cas avec Flash par exemple. Ensuite, avec des technologies comme WebRTC, ça permettrait de faire des applications décentralisées (faudra quand même du temps pour y arriver), chose que j'ai toujours soutenu.

          Il y a aussi des applications intéressantes comme gmail, ou ownCloud que je vais tester très bientôt, et qui ne pourraient pas fonctionner sans JavaScript car ce serait trop lent et mal intégré.

          Après, dire qu'il faut pas rendre JS plus rapide car JS ça bouffe du CPU, c'est pas très cohérent. Par contre, en avoir marre du JS utilisé n'importe où, n'importe comment, c'est beaucoup plus pertinent à mon avis. Moi aussi quand je lis un article, je déteste avoir des trucs qui bougent partout, et du code qui s'exécute par derrière et que je soupçonne de ne pas vraiment aller dans le sens de mes intérêts. Et malheureusement la seule solution qui marche à peu près à l'heure actuelle est NoScript. C'est dommage que tout le monde ne fasse pas comme moi des pages qui puissent s'afficher correctement avec ou sans le JavaScript :(

          La situation du JavaScript ne me satisfait pas complètement: elle m'oblige à tout le temps faire des compromis…

          • [^] # Re: soit dit en passant

            Posté par . Évalué à 1.

            Ok, vous avez tout à fait raison pour la minification du JavaScript. Il y a des déminificateurs, et des beautifiers de code, mais si on veut, on peut facilement rendre un code complètement illisible. Ca n'empêche pas de pouvoir suivre les connections réseau par exemple.

            En ayant les droits et sur un OS correct, on fait ça pour n'importe quel langage, compilé ou non. Et pour tout le reste, il y a la virtualisation.

            • [^] # Re: soit dit en passant

              Posté par . Évalué à -1. Dernière modification le 20/03/13 à 17:22.

              Et pour ceux qui n'auraient pas un OS correct, on fait ça avec n'importe quel Arduino ou Rasp Pi. Pour tout le reste, il y a jslinux.

              Bon là, ça vire carrément au HS. J'arrête.

            • [^] # Re: soit dit en passant

              Posté par . Évalué à 0. Dernière modification le 20/03/13 à 18:35.

              Oui, mais ça ne te dit pas quel script sur quelle page en est responsable.

              (Désolé pour le post précédent.)

          • [^] # Re: soit dit en passant

            Posté par . Évalué à -1.

            C'est vrai que quand on utilise NoScript

            mais oui, mais précisément, voilà ! Il est devenu complètement impossible de se passer de moyens de désactiver sélectivement le javascript dès qu'on a une navigation de quelques dizaines d'onglets : c'est quelque chose qui était complètement impensable il n'y a pas même 5 ans. Et ça c'est pour une raison toute simple : le javascript s'exécute beaucoup plus rapidement et incite donc les dévelopeurs à en abuser. C'est toujours la vieille histoire software becomes slower faster than hardware becomes faster.

            Après, dire qu'il faut pas rendre JS plus rapide car JS ça bouffe du CPU, c'est pas très cohérent
            Mais si, c'est cohérent : au départ, la lenteur de JS était intentionnelle, c'était un outil limité, destiné à rendre quelques services programmatiques, mais en évitant de rendre les ressources du client intéressantes pour le serveur.

            Maintenant, qu'on veuille rendre JS plus efficace, qu'on le JIT, qu'on l'optimise pour qu'il bouffe moins de cycles pour une même tâche, c'est très bien, mais il devrait être limité en vitesse d'exécution par défaut (avec un mécanisme de réglage facile pour les applis exigeantes, voire une api standard pour demander ce genre de permission) et faire des petits usleep(3) des familles pour ne pas rendre ton système rentable à exploiter.

            Tout le monde serait gagnant et tu n'aurais pas à faire tout ça manuellement avec ton plugin NoScript qui te casse 98% des sites par défaut - ce qui est quand même un hack incroyable !

            • [^] # Re: soit dit en passant

              Posté par . Évalué à 3.

              Maintenant, qu'on veuille rendre JS plus efficace, qu'on le JIT, qu'on l'optimise pour qu'il bouffe moins de cycles pour une même tâche, c'est très bien, mais il devrait être limité en vitesse d'exécution par défaut (avec un mécanisme de réglage facile pour les applis exigeantes, voire une api standard pour demander ce genre de permission) et faire des petits usleep(3) des familles pour ne pas rendre ton système rentable à exploiter.

              C'est quoi ton délire de système exploités ? Qui exploite ta machine et pourquoi ? Tu peux nous donner des exemples concrets puisque ca fait plusieurs fois que tu assénes ca comme une vérité ?

              • [^] # Re: soit dit en passant

                Posté par . Évalué à 1.

                Qui exploite ta machine et pourquoi ?

                Je comprends presque pas ta question.. ;-(

                Les pages Web utilisent les ressources de ta machine comme bon leur semble et tu n'as aucun moyen de savoir à l'avance comment.
                Le seul moyen que tu aies d'éviter ça, c'est de désactiver le javascript avec quelque chose comme NoScript, et le web n'est presque plus fonctionnel comme cela tellement les pages reposent abusivement sur cet environnement d'exécution.

                Tu veux un exemple concret, on va prendre encore les Web Workers parce que c'est frappant :
                - ouvre cet URL en 4 ou 5 exemplaires dans des onglets d'un navigateur récent :
                http://extremelysatisfactorytotalitarianism.com/projects/experiments/2010/03/boxdemo/
                - coche la case marqué "11" dans chaque onglet.

                eh bien voilà, l'UI de ton navigateur a l'air de répondre normalement, mais en fait tous tes CPU sont maxés, exploités sans que tu aies été consulté, pour faire des calculs arbitraires.
                Bien sûr dans ce cas, c'est juste pour une démo, et la page te met gentiment au courant de ce qu'elle fait..

            • [^] # Re: soit dit en passant

              Posté par (page perso) . Évalué à 8. Dernière modification le 20/03/13 à 20:02.

              Mais si, c'est cohérent : au départ, la lenteur de JS était intentionnelle

              Que la rapidité ne soit pas le premier critère de conception, je veux bien la croire, mais essayer de nous faire avaler que JavaScript a été pensé pour être lent, faut pas déconner.

              mais il devrait être limité en vitesse d'exécution par défaut

              Et qui y gagnerait au fait ? C'est n'importe quoi !

              Je ne suis pourtant pas un adorateur de JavaScript, loin de là.

              • [^] # Re: soit dit en passant

                Posté par . Évalué à -6.

                que JavaScript a été pensé pour être lent, faut pas déconner

                c'est pourtant exactement le cas. Pour les besoins computationnels sérieux, il y avait Java sous forme d'applet - bardé de sécurités.
                On parle d'une époque ou la moindre ressource CPU était précieuse, je vois pas ce qui te surprend.

                Et qui y gagnerait au fait ?

                si ton navigateur te laissait allouer un certain pourcentage de CPU maximum dévolu au JS, contrôlé par usleep, avec des exceptions paramétrables,
                tu y gagnerais que ton système ne ramerait plus pour 3 pauvres onglets, on y gagnerait tous que les devs Webs cesseraient progressivement de mettre 1 Mo de scripts sur la moindre page, et les fournisseurs de contenu y gagneraient qu'on cesserait peut-être tous d'utiliser NoScript pour survivre.

                • [^] # Re: soit dit en passant

                  Posté par (page perso) . Évalué à 6.

                  que JavaScript a été pensé pour être lent, faut pas déconner

                  c'est pourtant exactement le cas.

                  Quelle est la difficulté à comprendre la différence entre ces deux phrases?
                  - être rapide n'était pas la priorité
                  - le but était de ne pas être rapide

                  Car bon, ça n'a absolument rien à voir : JS est lent, mais n'a pas été pensé pour être lent, c'était juste pas la priorité.

                  Je suis le premier à taper sur JS, mais la, dire que l'objectif était la lenteur, c'est du gros n'importe quoi.

                  • [^] # Re: soit dit en passant

                    Posté par . Évalué à -4.

                    Non, j'ai parfaitement compris ta phrase, mais tu mets trop de poids dans la mienne : il était important que JS soit lent pour pouvoir exister au départ, pour pouvoir être adopté comme langage embarqué, et il n'y avait absolument aucun projet de l'accélérer un jour.

                    On parle ici d'une décision historique, c'est-à-dire d'un contexte, de besoins précis, d'une idée qu'on se faisait de la chose naissante qu'était le web - du respect de l'équilibre client/serveur et de leurs ressources respectives.

                    Bien sûr que Brendan Eich ne s'est pas regardé dans la glace le matin en se demandant comment rendre ses constructions syntaxiques les plus lentes possibles. Il n'en avait pas besoin parce que de toute manière, implémenter un langage lent était ce qu'il y avait de plus rapide à faire - il ne faut pas oublier que tout ça se passe sur un coin de table, à toute allure, chez Netscape. Mais cette lenteur arrangeait tout le monde, parce qu'elle rassurait sur la non-exploitabilité du langage. Cela devait rester un jouet aux yeux des "programmeurs sérieux".

                    Il aurait été complètement impensable d'interfacer un langage puissant avec le DOM, sans aucun garde-fou, alors que c'était la chose la plus simple à faire - ils auraient parfaitement pu passer un arrangement pour interfacer Java plus directement puisqu'ils étaient cul et chemise avec Sun, mais tout le monde les aurait pris pour des fous.

                    Tout comme on laisse une petite cuiller à des prisonniers, mais pas un marteau piqueur, parce qu'on se dit qu'il leur faudra quand même un bout de temps pour creuser un tunnel, JS était intentionnellement lent.

                    Je te traduits un bout d'interview de Eich pour infoworld (comme ça, je réponds aussi indirectement à la demande de citation de source, plus bas) :

                    "
                    InfoWorld: Dans quel but avez-vous développé JavaScript ?

                    Eich: L'idée était de faire quelque chose que les développeurs Web, des gens qui n'avaient pas forcément beaucoup d'expérience de la programmation, pourraient utiliser pour ajouter un tout petit peu d'animation, ou un tout petit peu d'interactivité, à leurs formulaires et à leurs pages Web.

                    Bon, on est en 1995, le Web en est à ses premiers balbutiements. HTML en était à 3.2, je crois, ou quelque chose d'approchant. Les gens n'avaient pas beaucoup de programmabilité à disposition. Java arrivait au même moment mais ça demandait d'apprendre un langage de programmation sophistiqué, puis de faire tourner un compilateur et de mettre votre code dans un paquet qui devenait une applet qui faisait alors partie de la page, mais qui était dans un petit silo. Il était entouré de murs en quelque sorte.

                    Et puis c'était dur—c'était pour les programmeurs professionnels. On pensait que c'était pour faire les visites virtuelles d'agences immobilières ou des trucs puissants comme ça. Alors que JavaScript, c'était juste 3 lignes que vous pouviez écrire, que vous pouviez copier sur quelqu'un, et que vous pouviez apprendre sur le tas. Vous n'aviez pas à apprendre tout le langage pour l'utiliser - ça pouvait se faire au coup par coup.

                    Cette idée était apprement défendue par Marc Andreessen et moi-même. Bill Joy, de chez Sun, était son plus ardent défenseur, ce qui était utile parce que c'est comme ça qu'on a trouvé le nom. Et on le promouvait comme le petit frère de Java, un langage complémentaire, un peu ce que Visual Basic était au C++ dans la gamme des langages de Microsoft à l'époque. Et ça a pris. Et on l'a sorti à temps.
                    "

                    Bon j'ai bien mouillé la chemise là :-)
                    Je pensais que tout ça était encore bien connu, mais je m'aperçois que l'idée moderne du web déforme beaucoup celle qu'on se fait de ses origines.

                    • [^] # Re: soit dit en passant

                      Posté par (page perso) . Évalué à 5.

                      Tout comme on laisse une petite cuiller à des prisonniers, mais pas un marteau piqueur, parce qu'on se dit qu'il leur faudra quand même un bout de temps pour creuser un tunnel, JS était intentionnellement lent.

                      Je dirais plus simplement que la cuiller n'est pas un bon outil pour creuser des trous, de même que JS n'est pas un bon outil pour faire du gros développement web. Mais je ne dirai pas que la cuiller est intentionnellement pas pratique pour creuser des trous (puisque c'est faux).

                      Que JS ne soit pas un bon outil pour créer de grosses application web, je suis entièrement d'accord (il n'a pas été fait pour ça et inventer des constructions horribles pour pallier ses limitations n'arrange rien), et c'est en gros ce que dit Eich dans la citation que tu donnes. Mais les mots ont un sens, et l'exagération du propos crée plus de confusion dans le débat qu'autre chose.

                      Je pensais que tout ça était encore bien connu, mais je m'aperçois que l'idée moderne du web déforme beaucoup celle qu'on se fait de ses origines.

                      Non pas du tout. Je pense que c'est ton propos qui déformait ces idées d'origine en l'exagérant. Mais je comprends ce que tu veux dire. Dans le fond, nous somme quasiment d'accord, à part que je ne pense pas utile de limiter artificiellement JS, mais qu'il serait bien plus intéressant de pousser une bonne alternative.

                      • [^] # Re: soit dit en passant

                        Posté par . Évalué à -2.

                        Non pas du tout. Je pense que c'est ton propos qui déformait ces idées d'origine en l'exagérant. Mais je comprends ce que tu veux dire. Dans le fond, nous somme quasiment d'accord, à part que je ne pense pas utile de limiter artificiellement JS, mais qu'il serait bien plus intéressant de pousser une bonne alternative.

                        +1

                • [^] # Re: soit dit en passant

                  Posté par (page perso) . Évalué à 4.

                  c'est pourtant exactement le cas.

                  J'aimerais bien une source, car pour moi c'est plus du délire qu'autre chose.

                  On parle d'une époque ou la moindre ressource CPU était précieuse, je vois pas ce qui te surprend.

                  Comme c'était précieux, on allait sûrement pas faire exprès de bouffer de la ressource…

                  tu y gagnerais que ton système ne ramerait plus pour 3 pauvres onglets,

                  Je sais bien qu'il y a de mauvais développeurs web, mais il ne mettent pas non plus du JavaScript pour le simple plaisir de faire ramer ton navigateur. Donc si tu veux juste brider les possibilités, tu vas les faire chier, et peut-être nous faire chier en faisant des pages moins réactives avec les limitations que tu veux mettre.

                  • [^] # Re: soit dit en passant

                    Posté par . Évalué à 1.

                    Je t'ai traduit un extrait d'interview dans le commentaire au-dessus, mais je peux juste te resituer un contexte, c'est ça l'histoire, une question de perspectives, personne ne détient la vérité ultime et il faut souvent savoir lire entre les lignes.

                    Comme c'était précieux, on allait sûrement pas faire exprès de bouffer de la ressource…

                    non, l'idée était de ne pas te laisser la possibilité de bouffer de la ressource, parce que ce serait tellement peu pratique que le faire serait absurde. J'ai fait une analogie avec la petite cuiller qu'on laisse aux prisonniers : ils peuvent parfaitement s'en servir pour manger, mais s'ils veulent s'évader, ça va les faire chier, c'est fait exprès !

                    Donc si tu veux juste brider les possibilités, tu vas les faire chier, et peut-être nous faire chier en faisant des pages moins réactives avec les limitations que tu veux mettre.

                    Elles ne seraient pas moins réactives. L'idée (JavaScript == vitesse du web) est une construction marketing des années 2006 par Google qui voulait ses applications lourdes : il faut savoir que tout n'est pas accélérable dans la pile de standards constituée par les navigateurs. Depuis bien longtemps, aux environs de 2006 d'ailleurs, ce n'est pas JavaScript qui est le facteur limitant, mais l'arborescence DOM, qui n'est pas parallélisable, et qu'il faut bien parcourir, et l'arbre de rendu du document avec son arbre de styles CSS associé. Tout cela est au maximum de vitesse depuis des années, et ne peut évoluer que si de nouveaux standards émergent.

                    99% de tout ce qui se fait sur le web en dehors des applis lourdes (pour lesquelles l'utisateur pourrait faire des exceptions à la manière de NoScript) peut se faire avec 1% de la vitesse JS, sans différence de vitesse effective puisque tout ce qui est vraiment interactif visuellement est bridé par le DOM. Cela éviterait les spoliations de CPU qui sont le fait de programmeurs incompétents ou de l'accumulation de strates de frameworks.
                    Cela rétabirait 'équilibre entre les différents standards, et entre client et serveurs : on éviterait de faire en JS ce qu'on peut parfaitement construire côté serveur mais qu'il est simplement devenu plus rentable de faire sur le client, ou ce qu'on peut carrément implémenter statiquement en CSS 3.

                    En gros, il me semble qu'il est urgent de recentrer le Web sur le statique, et de refaire de l'applicatif une exception.
                    Mais ça n'est que mon avis (j'avoue, je suis biaisé, j'ai bossé 8 ans sur le moteur de rendu de Konqueror - j'exècre ce que Google a fait du Web)

    • [^] # Re: soit dit en passant

      Posté par (page perso) . Évalué à 5.

      L'entreprise d'accélération de JS lancée par Apple à partir de 2005

      L'entreprise d'accélération de JS existait déjà du simple fait de IE6 et Firefox. Même si les navigateurs basés sur webkit on bien fait évoluer les choses.

      une abomination
      l'extension de ce fléau

      Tu peux développer. Nan mais je veux dire pour de vrai, sortir de ton troll et développer un peu ?

  • # Comme je n'ai pas envi de refaire le monde

    Posté par . Évalué à 0.

    Je signe tout de suite.
    Je ferais même rajouter une clause pour distribuer certaines librairies javascript avec les navigateurs afin que plus jamais elle n'ai besoin de transférer sur le réseau et solutionner un petit plus encore ses problèmes de chargement.

    Ceci dit, tu as eu un plus de retours, mais c'est p'tet pas ceux là que tu souhaitais voir pour te motiver, ou autre = )

    Encore merci pour le temps que tu as pris à partager ces projets !

    a+

  • # workers ...

    Posté par . Évalué à 7.

    Est-ce que quelqu'un peut expliquer un peu ce que sont les workers ? Je suis allé voir le lien cité en référence mais j'ai un peu de mal à comprendre certaines choses. Je suis loin d'être un spécialiste JAvascript, par contre le sujet m'intéresse car je pourrais en avoir besoin d'ici peu, et ce que j'en ai lu et compris me plait. …

    D'abord ce que j'en ai compris :
    - les workers permettent de faire du parallélisme en Javascript. *
    - les workers utilisent les threads de l'OS pour s'exécuter.
    - javascript devient donc un langage multithread (donc potentiellement casse-gueule si on ne fait pas attention).
    D'ou mes question :
    - est-ce que les variables peuvent être partagées entre workers, ou entre le worker et l'appelant, ou le worker et l'appelant ne communiquent entre eux que par passage de messages ? Il semble que non ( je cite : "Google Chrome 17 and Firefox 18 contain an additional way to pass certain kind of objects (Transferable Objects) to/from a worker with high performance. ")

    Pour les experts du domaine qui trainent ici, pourriez-vous SVP faire un retour de l'utilisation de ces petites bêtes (qui me plaisent pour ce que je veux faire) ? Limites, erreurs à éviter, etc … ?

    Merci d'avance.

    • [^] # Re: workers ...

      Posté par . Évalué à 2. Dernière modification le 20/03/13 à 18:22.

      Les web workers permettent de faire du parallélisme en JavaScript sans danger grâce à une forte séparation entre les contextes d'exécution.

      Tu ne peux pas accéder aux données d'un autre contexte, il n'y a donc pas de risque d'interférer. La seule façon de transférer des données était de les passer sous forme de chaînes de texte ou d'objet JSON qui seront clonés. Il existe maintenant la possibilité de passer un ArrayBuffer (tableau de nombres) qui ne sera pas cloné, mais transférés d'un contexte à un autre, comme s'il disparaissait du premier contexte. C'est plus rapide, car cela peut se faire sans copie de mémoire, mais ça ne fonctionne pas sur tous les navigateurs et ça demande plus de travail qu'un simple JSON.

      Tu as accès à la plupart des fonctions de base de JavaScript pour faire tes calculs (Array, Object, Math, setInterval(), …). Tu as aussi accès aux fonctionnalités réseau et peut donc envoyer/recevoir des données au serveur. Par contre tu n'as pas accès au DOM. Il te faudra envoyer des messages au thread GUI (le thread principal de la page web qui a créé les web workers) qui se chargera de manipuler le DOM.

      Les web workers sont donc souvent utilisés pour faire des longs calculs sans bloquer le thread GUI et pour traiter les entrées/sorties avec le serveur.

      Je te conseille la documentation de Mozilla Developer Network (MDN) qui offre souvent les meilleures informations:
      https://developer.mozilla.org/en-US/docs/DOM/Worker
      https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers

      Quant aux erreurs à éviter et aux limites, je n'en ai pas en tête, si ce n'est bien vérifier la compatibilités des différentes fonctionnalités avec les navigateurs (ça se trouve en bas des pages sur MDN).

    • [^] # Re: workers ...

      Posté par . Évalué à 5.

      Un worker est un thread indépendant.
      Quand tu l'initialize tu lui passe l'URL d'un fichier Javascript et il se charge de le télécharger et l'executer. Il n'est pas possible de l'initializer avec une fonction.

      Ensuite le seul moyen de communiquer avec lui c'est de lui envoyer des messages. Ces messages seront copiés, donc non il n'y a pas moyen de partager des variables entre workers.

      Autrement dit il n'y a aucune mémoire partagé entre les différents thread (le principal et le/les Worker). Donc tu ne peut pas tomber dans les pièges classiques des applications multithreads. De plus il faut comprendre que ça implique que les workers ne peuvent pas directement modifier le DOM.

      Àmha, la seule application pratique des workers c'est de passer des taches CPU intensives en arrière plan. Bref c'est franchement pas pour tout le monde.

      • [^] # Re: workers ...

        Posté par (page perso) . Évalué à 2.

        Un worker est un thread indépendant.
        Quand tu l'initialize tu lui passe l'URL d'un fichier Javascript et il se charge de le télécharger et l'executer. Il n'est pas possible de l'initializer avec une fonction.
        De plus il faut comprendre que ça implique que les workers ne peuvent pas directement modifier le DOM.

        Si je comprends bien, un worker est un moyen technique permettant à une page web de lancer un script en tâche de fond dans la vm de mon navigateur, avec la garantie que le travail effectué ne pourra pas impacter le rendu de la page que je demande, ce qui signifie autrement qu'un worker ne peut être un moyen efficace pour répondre à ma requête (à moins de contournement) ? C'est une question de néophyte… mais vu comme ça, à quoi peut servir un worker autrement que pour utiliser mon CPU pour autre chose que la page que je regarde ? Peut-on avoir des exemples concrets avec lesquels un worker sert à autre chose qu'étendre un système de calcul distribué ?

        ce commentaire est sous licence cc by 4 et précédentes

        • [^] # Re: workers ...

          Posté par . Évalué à 2.

          Une partie de la réponse a été donnée : passer les attentes IO en arière plan. Mais si les workers n'ont pas acès au DOM, c'est un peu limité.

          A vue de nez, une des utilités que je vois, c'est les jeux : calcul d'une partie d'image ou de coordonnées pendant que le navigateur traite l'affichage du calcul précédent.

          • [^] # Re: workers ...

            Posté par . Évalué à 4.

            Une partie de la réponse a été donnée : passer les attentes IO en arière plan.

            Beh non, les IO sont déjà pas en problème puisque toutes les opérations IO permisses par le navigateur sont "evented".

            Par contre ce qu'il faut comprendre c'est que lorsque du Javascript est en cours d'execution dans une page le navigateur doit attendre qu'il finisse pour pouvoir repeindre la page et accepter de nouvelles entrées utilisateur.

            Du coup si en réaction à une entrée utilisateur tu lance une opération de calcul qui prend une seconde, tu fige la page 1 seconde(ou le navigateur entier dans le cas de Firefox à moins que ça n'ai été réglé depuis).

            Démonstration: http://jsfiddle.net/nDf7r/9/

            une des utilités que je vois, c'est les jeux : calcul d'une partie d'image ou de coordonnées pendant que le navigateur traite l'affichage du calcul précédent.

            Effectivement c'est tout à fait le genre d'opération longue mais synchrone qu'on ne peut pas se permettre de faire dans le thread principal.

            En résumé les WebWorkers permettent d'exporter des fonction synchrone dans un ou plusieurs autre threads et de les utiliser de manière asynchrone.

            • [^] # Re: workers ...

              Posté par . Évalué à 2.

              Beh non, les IO sont déjà pas en problème puisque toutes les opérations IO permisses par le navigateur sont "evented

              L'IO en elle même non, par contre parser la réponse et la traiter ca peut prendre un certain temps si tu as un peu de volume et ca c'est synchrone.

              • [^] # Re: workers ...

                Posté par . Évalué à 2.

                Effectivement 3Mo de JSON => 80 à 160ms sous chrome.

            • [^] # Re: workers ...

              Posté par (page perso) . Évalué à 3.

              ou le navigateur entier dans le cas de Firefox à moins que ça n'ai été réglé depuis

              ça fait en fait un bon moment que cela a été réglé… dans Gecko. Mais pas appliqué à Firefox Desktop. Cette fonctionnalité était le projet Electrolysis, pour ceux qui s'en souviennent.

              Dans une application XUL (comme Firefox), dans Gecko, on a à disposition une balise pour afficher une page web.

               <browser src="http://site.com">
              
              

              c'est en gros une iframe plus évoluée au niveau propriété/methodes. Depuis Firefox 4/Gecko 2 , il suffit de faire

               <browser remote="true" src="...">
              
              

              pour avoir la page web qui s’exécute dans un processus séparé et il y a aussi

               <iframe mozbrowser remote> 
              
              

              pour les webapp.

              Donc dans Gecko, on a la possibilité depuis longtemps d'afficher une page dans un process séparé, que ce soit en XUL ou en C++. Et c'est largement utilisé dans Firefox Mobile (sur Android) et dans Firefox OS.

              Pourquoi ce n'est pas appliqué à Firefox Desktop :

              • Sur le desktop, ça ne semble pas apporter énormément : augmentation de la mémoire utilisée etc.. Surtout avec les travaux de "parallélisation" dans le moteur de layout par exemple qui ont eu lieu et qui ont permis d'améliorer les choses indirectement (ex: OMTC même si ce truc n'est pas encore actif je crois dans la version desktop).
              • lancer une page web dans un process séparé, implique une nouvelle manière pour les extensions XUL pour accéder au contenu de la page web (passages de messages plutôt que de manipuler directement le contenu). Même si des extensions utilisent déjà la nouvelle API, le passage définitif au multiprocess pour les pages web va casser bon nombre d'extensions.
              • Et cela ne cassera pas seulement les extensions, mais aussi Firefox : il faut réécrire énormément de choses dans l'interface de Firefox. C'est un long travail qu'ils ont à peine commencer. Et comme ils ont d'autres priorités en ce moment comme Firefox OS etc…
              • [^] # Re: workers ...

                Posté par . Évalué à 4.

                Attention je dit pas que chaque onglet devrait être dans un processus séparé comme dans Chrome. Juste l'interface. Je me fiche si un de mes onglets n'est pas réactif car il est en train de charger une page lourde. Mais si je ne peux pas continuer à naviguer sur els autres onglets pendant ce temps là c'est franchement pénible.

        • [^] # Re: workers ...

          Posté par . Évalué à 4.

          Peut-on avoir des exemples concrets avec lesquels un worker sert à autre chose qu'étendre un système de calcul distribué ?

          Le web ce sont des pages statiques, des pages dynamiques et des applications webs. Donc réagir aux actions de l'utilisateur, faire du CPU bound sans bloquer l'UI, consulter et agréger des ressources externes, implémenter des greffons, structurer et segmenter son code ?

          Sérieusement vous croyez vraiment qu'on passe son temps à utiliser votre petit CPU ? Il y a beaucoup de choses qui font plus de sens à faire client side que serveur side. Quand on avait pas le choix pour des raisons techniques, matérielles ou de base de code on trouvait une solution avec des échanges coté serveur. Maintenant il faut trouver la balance.

          Il faut autant cesser de voir le web comme simplement des pages à papa qu'il faut arrêter d'utiliser des usines à gaz pour des pages vraiment à papa.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.