Indiquez que la fonction JS du processeur est en cours (les filtres GIF ne sont pas animés)

Montrer alors cacher les icônes animées / les gifs de spinner sont un bon moyen de montrer à un utilisateur que son action a fonctionné et que quelque chose se passe alors qu'ils attendent que leur action soit complétée – par exemple, si l'action nécessite le chargement de certaines données à partir d'un serveur (s) ) Via AJAX.

Mon problème est que, si la cause du ralentissement est une fonction fonctionnelle du processeur , le gif se fige.

Dans la plupart des navigateurs, le GIF cesse d'animer pendant que la fonction de faim de processeur s'exécute . Pour un utilisateur, cela semble que quelque chose s'est écrasé ou a mal fonctionné, quand il fonctionne réellement.

Exemple JSBIN

Remarque: le bouton «This is slow» allie le processeur pendant un certain temps – environ 10 secondes pour moi, variera selon les spécifications du PC. Vous pouvez modifier la mesure dans laquelle cela se fait avec l'attribut "data-reps" dans le HTML.

Entrez la description de l'image ici

  • Attente: en cliquant, l'animation s'exécute. Lorsque le processus est terminé, le texte change (nous cacherions normalement l'indicateur, mais l'exemple est plus clair si on le laisse tourner).
  • Résultat réel: l'animation commence à fonctionner, puis gèle jusqu'à la fin du processus. Cela donne l'impression que quelque chose est cassé (jusqu'à ce qu'il se termine de façon inattendue).

Existe-t-il un moyen d'indiquer qu'un processus est en cours d'exécution qui ne gèle pas si JS maintient le processeur occupé? S'il n'y a aucun moyen d'avoir quelque chose d'animé, je vais recourir à l'affichage puis à cacher un message texte statique indiquant Loading... ou quelque chose de similaire, mais quelque chose d'animé semble beaucoup plus actif.


Si quelqu'un se demande pourquoi j'utilise un code qui nécessite un processeur plutôt que d'éviter le problème en optimisant: il s'agit d'un rendu nécessairement complexe. Le code est assez efficace, mais ce qu'il fait est complexe, il sera toujours exigeant pour le processeur. Cela ne prend que quelques secondes, mais c'est assez long pour frustrer un utilisateur, et il y a plein de recherches depuis longtemps pour montrer que les indicateurs sont bons pour UX .


Un deuxième problème connexe avec les filateurs gif pour les fonctions lourdes du processeur est que le spinner ne s'affiche pas jusqu'à ce que tout le code dans un ensemble synchrone ait fonctionné – ce qui signifie qu'il ne montrera normalement pas le spinner jusqu'à ce qu'il soit temps de cacher le spinner.

  • Exemple de JSBIN .
  • Une correction facile que j'ai trouvée ici (utilisée dans l'autre exemple ci-dessus) consiste à envelopper tout après avoir affiché l'indicateur dans setTimeout( function(){ ... },50); Avec un intervalle très court, pour le rendre asynchrone. Cela fonctionne (voir le premier exemple ci-dessus), mais ce n'est pas très propre. Je suis sûr qu'il y a une meilleure approche.

Je suis sûr qu'il doit y avoir une approche standard pour les indicateurs pour le chargement intensif du processeur dont je ne connais pas – ou peut-être normal d'utiliser simplement Loading... text with setTimeout ? Mes recherches n'ont révélé rien. J'ai lu 6 ou 7 questions sur des problèmes de sonorité similaires, mais ils se révèlent tous indépendants.


Modifier Quelques excellentes suggestions dans les commentaires, voici quelques précisions sur mon problème exact:

  • Le processus complexe implique le traitement de grands fichiers de données JSON (comme dans les opérations de manipulation de données JS en mémoire après le chargement des fichiers) et le rendu des visualisations SVG (via Raphael.js), y compris une carte mondiale approfondie et détaillée, basée sur les résultats de la Traitement de données à partir du JSON. Donc, certains d'entre eux nécessitent une manipulation DOM, d'autres ne le font pas.
  • J'ai malheureusement besoin de supporter IE8 MAIS si nécessaire, je peux donner aux utilisateurs IE8 / IE9 un ressaut minimal comme Loading... texte et donner à tous les autres quelque chose de moderne.

Les navigateurs modernes exécutent maintenant des animations CSS indépendamment du thread UI si l'animation est implémentée à l'aide d'une transformation, plutôt que par modification de propriétés. Un article sur ceci peut être trouvé à http://www.phpied.com/css-animations-off-the-ui-thread/ .

Par exemple, certains des filateurs CSS à http://projects.lukehaas.me/css-loaders/ sont implémentés avec des transformations et ne gèlent pas lorsque le thread UI est occupé (p. Ex., Le dernier filant sur cette page).

J'ai déjà eu des problèmes similaires dans le passé. En fin de compte, ils ont été corrigés en optimisant ou en faisant du travail dans des mandrins plus petits répondant aux actions des utilisateurs. Dans votre cas, différents niveaux de zoom déclencheraient différents algorithmes de rendu. Vous ne transformeriez que ce que l'utilisateur peut voir (plus peut-être une marge tampon).

Je crois que la seule solution de rechange simple pour vous qui serait cross-browser est d'utiliser setTimeout pour donner au thread ui une chance de s'exécuter. Détachez votre travail dans des ensembles d'opérations et raccordez-les en utilisant plusieurs appels setTimeout. Cela ralentira le temps de traitement total, mais l'utilisateur recevra au minimum des commentaires. De toute évidence, cette suggestion exige que votre traitement puisse être facilement séparé. Si tel est le cas, vous pouvez également envisager d'ajouter une barre de progression pour UX amélioré.