IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Ralentissement important au bout de quelques lignes


Sujet :

JavaScript

  1. #1
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut Ralentissement important au bout de quelques lignes
    Salut,

    En faisant des tests (sur un petit éditeur) j'ai remarqué un ralentissement important de l'affichage...

    Par exemple quand j'enfonce la touche entrée et que je la maintiens enfoncée, des lignes s'ajoutent à une certaine vitesse, au début (quelques centaines de lignes) l'affichage se fait bien, on voit les numéros des lignes défiler régulièrement mais au bout d'un certain nombre de lignes l'affichage se fait par à-coups : parfois pendant un temps le défilement ralenti fortement voir s’arrête carrément puis après un laps de temps l'affichage se fait d'un coup...

    C'est assez désagréable...

    Je constate cela sur Chrome et sur FF ---> apparemment le traitement de chaque touche enfoncée est trop long..

    Alors j'ai fait un autre test avec un code réduit juste pour voir ici : http://jsbin.com/pohuguwulu/edit?js,output...

    Sur FF ça à l'air d'aller (je suis allé jusqu'à plus de 5000 lignes) mais sur Chrome j'observe toujours ce ralentissement pourtant le code n'est pas énorme...

    Vous pouvez tester ici http://jsbin.com/pohuguwulu/edit?js,output : maintenez (dans la div éditable à droite) la touche entrée enfoncée pour afficher rapidement des nouvelles lignes...

    Auriez-vous une idée qui expliquerait ce ralentissement ?

    Merci.

  2. #2
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Re-Salut,

    J'ai essayé l’outil "performance" de devTools de Chrome (je découvre cet outil..) et je vois que les "keydown event" sont de plus en plus long en terme de temps...

    J'ai l'impression qu'au bout d'un moment il enregistre les événements et les exécute par paquet...

    Peut-être que cela est dû au taux de répétition de l'événement (quand on maintient la touche enfoncée), celui-ci serait trop élevé ???

    Mais ce qui est bizarre c'est qu'au bout d'un moment (quand il y a beaucoup de lignes 1000-5000) il ralentit systématiquement même si on maintient la touche enfoncée un moment relativement court...



    ---> Peut-on modifier le taux de répétition de l'événement (quand on maintient la touche enfoncée) ?

    ---> Peut-on obliger Chrome à exécuter les éventements un par un et non paquet par paquet ?

    Merci.

  3. #3
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut


    Chaque navigateur optimize le traitement du JS en interne à sa manière.

    Pour un usage "normal" d'une zone "contenteditable" l'intérêt de ce test m'échappe.

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  4. #4
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Merci.

    As-tu aussi constaté ce ralentissement ?

    Citation Envoyé par danielhagnoul Voir le message
    Pour un usage "normal" d'une zone "contenteditable" l'intérêt de ce test m'échappe.
    Ben en fait j'ai fait ce test suite à un problème de ralentissement constaté... Dans un usage normal aussi je pense qu'il est désagréable que les numéros de lignes ou les caractères s'affichent par à-coups...

    Par exemple si tu tapes (rapidement ou en laissant une touche enfoncée) du texte à la ligne 3000 eh bien il s'affiche par à-coups (mot par mot) or en général (dans les éditeurs classiques) il s'affiche d'une manière fluide caractère par caractère... Il n'est pas normal qu'il y est un temps de réponse aussi important...

    Autre exemple quand on veut supprimer plusieurs caractères en maintenant la touche sup enfoncée...

    J'ai testé d'autres éditeurs et il n'y a pas ce problème...

    Je pense que la solution tourne autour de ces deux points :

    ---> Peut-on modifier le taux de répétition de l'événement (quand on maintient la touche enfoncée) ?
    ---> Peut-on obliger Chrome à exécuter les éventements un par un et non paquet par paquet ?

  5. #5
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Voici un autre test : http://jsbin.com/zacehorevu/edit?js,output

    On peut ajouter des lignes de deux manières pour comparaison :

    1- En tapant (dans la div éditable à droite) sur la touche "entrée" (rapidement ou en laissant la touche enfoncée)...
    2- En survolant le bouton "add line" (ajoute des lignes à une certaine vitesse réglable).

    Avec la deuxième il y a beaucoup moins de ralentissement, l'affichage est beaucoup plus fluide...

    On évite la multiplication des éventements et ce serait un moyen de fixer une fréquence de répétition de l'événement keydown lorsque la touche est maintenue enfoncée...

  6. #6
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Voir la solution de @bobince Sep 11 '10 at 16:04 sur https://stackoverflow.com/questions/...-in-javascript

    Mon code de test :

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    <!DOCTYPE html>
    <html lang="fr" dir="ltr">
    <head>
    	<!-- cache-control avec max-age=60 pour le développement uniquement -->
      <meta http-equiv="cache-control" content="public, max-age=60">
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
      <meta name="author" content="Daniel Hagnoul">
      <title>test</title>
      <style>
                    *,
                    *:after,
                    *:before {
                            box-sizing: border-box;
                    }
                    
                    /* CSS du test */
                    
                    main {
          display: grid;
          grid-template-columns: 10rem 1fr;
                            background-color: black;
                            color: wheat;
                    }
                    #num {
                            height: 500px;
                            padding-right: 3px;
                            border: 1px solid white;
                            overflow: auto;
                            text-align: right;
                            color: bisque;
                    }
                    #code {
                            height: 100px;
                            padding-left: 3px;
                            border: 1px solid aqua;
                            overflow: auto;
                            color: white;
                            white-space: nowrap;
                    }
                    
                    /* Fin CSS du test */
     
      </style>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/locale/fr.js"></script>
      <script src="http://danielhagnoul.developpez.com/lib/dvjh/dvjhUtilities-1.3.3.js"></script>
      <script>
        'use strict';
                    
        document.addEventListener( "DOMContentLoaded", ev => {
                            moment.locale( "fr" );
                            klog( `DOM ready   : ${ new kDvjhDate() }` );
                            
          // code du test
                            
     
                            // fin code du test
          
        }, false );
        
        window.addEventListener( "load", ev => { 
                            klog( `Window load : ${ new kDvjhDate() }` );
                            
          // code du test
                            
                            /*
                             * @bobince Sep 11 '10 at 16:04 sur
                             * https://stackoverflow.com/questions/3691461/remove-key-press-delay-in-javascript
                             */
                            
                            // Keyboard input with customisable repeat (set to 0 for no key repeat)
                            //
                            function KeyboardController(keys, repeat) {
                                            // Lookup of key codes to timer ID, or null for no repeat
                                            //
                                            var timers= {};
                            
                                            // When key is pressed and we don't already think it's pressed, call the
                                            // key action callback and set a timer to generate another one after a delay
                                            //
                                            document.onkeydown= function(event) {
                                                            var key= (event || window.event).keyCode;
                                                            if (!(key in keys))
                                                                            return true;
                                                            if (!(key in timers)) {
                                                                            timers[key]= null;
                                                                            keys[key]();
                                                                            if (repeat!==0)
                                                                                            timers[key]= setInterval(keys[key], repeat);
                                                            }
                                                            return false;
                                            };
                            
                                            // Cancel timeout and mark key as released on keyup
                                            //
                                            document.onkeyup= function(event) {
                                                            var key= (event || window.event).keyCode;
                                                            if (key in timers) {
                                                                            if (timers[key]!==null)
                                                                                            clearInterval(timers[key]);
                                                                            delete timers[key];
                                                            }
                                            };
                            
                                            // When window is unfocused we may not get key events. To prevent this
                                            // causing a key to 'get stuck down', cancel all held keys
                                            //
                                            window.onblur= function() {
                                                            for (key in timers)
                                                                            if (timers[key]!==null)
                                                                                            clearInterval(timers[key]);
                                                            timers= {};
                                            };
                            };
     
                            let
                                    divNum = null;
                            
                            const
                                    elemCode = document.querySelector( "#code"),
                                    elemNum = document.querySelector( "#num"),
                                    elemDiv = document.createElement( "div" );
                            
                            // Arrow key movement. Repeat key five times a second
                            //
                            KeyboardController({
                                    13 : function( ){
                                            divNum = elemDiv.cloneNode( false ),
                                            divNum.className = "numline";
                                            divNum.textContent = elemNum.childElementCount + 1;
                                            elemNum.appendChild( divNum );
                                            elemNum.scrollTop += 20;
                                    },
                            }, 200 );
     
                            // fin code du test
     
          kIDUnique();
        }, false );
      </script>
    </head>
    <body>
    	<main>
     
    		<div id="num">
    			<div>1</div>
    		</div>
     
    		<div id="code" contenteditable="true">
    			<div>Hello</div>
    		</div>
     
    	</main>
    </body>
    </html>

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  7. #7
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Merci Daniel,

    Je vais tester ton code qui si j'ai bien compris permet de déclencher plus rapidement les répétitions, cela supprime le délai d'attente qu'il y a normalement... On peut je pense s'en inspirer pour régler la fréquence de répétition.

    Mais j'ai fait un nouveau test sans utiliser la touche enfoncée et il semble que le problème soit que les manipulations du DOM soient lentes...

    Et je constate une grosse différence entre Chrome et FF et plus il y a de lignes plus la différence est importante :

    FF Chrome
    time[1 - 501] : 899.9549999999999 ms.
    time[501 - 1001] : 1369.744999999999 ms.
    time[1001 - 1501] : 1890.875 ms.
    time[1501 - 2001] : 2414.9449999999997 ms.
    time[2001 - 2501] : 3227.0450000000055 ms.
    time[2501 - 3001] : 3940.154999999999 ms.
    time[3001 - 3501] : 4390.130000000005 ms.
    time[3501 - 4001] : 5137.7850000000035 ms.
    time[4001 - 4501] : 5971.77999999997 ms.
    time[4501 - 5001] : 6274.570000000007 ms.
    time[1 - 501] : 942.9950000000001 ms.
    time[501 - 1001] : 2689 ms.
    time[1001 - 1501] : 4495 ms.
    time[1501 - 2001] : 6435.999999999985 ms.
    time[2001 - 2501] : 8851.999999999985 ms.
    time[2501 - 3001] : 10698 ms.
    time[3001 - 3501] : 13499 ms.
    time[3501 - 4001] : 14451 ms.
    time[4001 - 4501] : 17171 ms.
    time[4501 - 5001] : 19938 ms.
    Et encore dans le dernier test que j'ai fait FF va encore plus vite que ça...

    Voici le code : http://jsbin.com/wewodovide/edit?js,output
    ATTENTION : Il faut tester en dehors de jsbin car il limite apparemment... On peut faire File--> Download pour ouvrir le code dans le navigateur de son choix...


    J'aimerais bien savoir ce qui pend du temps, est-ce la manipulations du DOM ?
    Parce que le code JS il devrait être exécuter rapidement par Chrome, j'avais lu que le moteur V8 était rapide justement...

  8. #8
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Salut,

    J'ai encore repéré un des problèmes : l'ajustement de la scrollbar prend énormément de temps !!!

    En l'enlevant, je passe (pour les 500 premières lignes) de 943 ms à 40-50 ms pour Chrome !!! Et pour FF je passe de 900 ms à 78 ms...

    Plus il y a de lignes plus ce temps augmente pour Chrome tandis qu'il reste plus ou moins le même pour FF... Cette fois c'est le appendChild() qui prend du temps à chrome...

    Alors j'ai testé en faisant une string des 500 lignes et en les ajoutant avec un seul appendChild() et innerHTML et là bonne surprise on divise les temps par plus de 10 : on passe de 40-50 ms à 3-4ms et ça reste plus ou moins contant quand le nombre de lignes augmentent... Là chrome va même plus vite que FF...

    Au final avec ces deux modifs ça va 270 fois plus vite avec Chrome pour les 500 premières lignes... Et le gain augmente avec le nombre de lignes !

    Comme quoi pour le JS Chrome est bien rapide mais pour le DOM FF semble plus rapide...

    Bon hélas quand on tape du texte ça reste lent donc il y a encore autre chose qui ne va pas, un truc important à mon avis...

  9. #9
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Le problème c'est la fréquence de l'événement keydown ! Pourquoi utiliser l'événement keydown au lieu de keyup ? Car le second laissera automatiquement du temps libre pour la construction du DOM.

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  10. #10
    Membre expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 873
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 873
    Points : 3 717
    Points
    3 717
    Par défaut
    Salut,

    Merci et désolé pour le retard...

    Citation Envoyé par danielhagnoul Voir le message
    Le problème c'est la fréquence de l'événement keydown !
    Oui c'est vrai que la fréquence est trop élevée, en la diminuant cela fonctionne effectivement mieux (j'ai simulé cela avec un bouton start/stop et un timer)...

    Citation Envoyé par danielhagnoul Voir le message
    Pourquoi utiliser l'événement keydown au lieu de keyup ? Car le second laissera automatiquement du temps libre pour la construction du DOM.
    Parfois c'est nécessaire certaines choses doivent se faire entre le moment où on appuie sur une touche et celui où on l'a relâche... D'ailleurs si on maintient une touche enfoncée l’événement keyup n'a pas lieu...

    Mais en fait je pense que le problème c'est que cela devient lent lorsque la div éditable possède trop d'enfants... J'ai fait un test avec deux div éditables : une contenant le code entier et une autre dans laquelle on peut travailler sur une partie du code eh bien là ça va vite, cela fonctionne normalement... Je pense que certains éditeurs ne travaillent que sur une portion du code à la fois...

    ...

Discussions similaires

  1. Réponses: 3
    Dernier message: 04/07/2008, 14h52
  2. import gros fichier excel (>17000 lignes)
    Par samuelsiffert dans le forum Access
    Réponses: 12
    Dernier message: 05/07/2006, 08h48
  3. [TOMCAT] Tomcat ne répond pas au bout de quelques jours
    Par Bartuk dans le forum Tomcat et TomEE
    Réponses: 7
    Dernier message: 02/03/2006, 17h38
  4. Ralentissement important sous opengl
    Par drcd dans le forum OpenGL
    Réponses: 2
    Dernier message: 26/02/2006, 19h18
  5. [Systeme] Ralentissement important WinXP
    Par titus55 dans le forum Windows XP
    Réponses: 6
    Dernier message: 07/11/2005, 17h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo