Est-il possible d’accéder au facteur de mise à l’échelle actuel d’un élément% -width en Javascript sans provoquer de refusion?

J’essaie de corriger du javascript peu performant dans une interface utilisateur lente, et j’ai réduit la cause principale à un .width() jQuery .width() utilisé pour afficher la taille réelle en pixels d’un élément width: 100% dans un responsive mise en page, dans un processus qui doit souvent se produire en réponse aux actions de l’utilisateur.

J’ai ajouté des mesures basées sur l’horodatage et elles montrent que cela représente à lui seul environ 33% du temps de latence, ce qui rend la différence entre une sensation d’interface utilisateur nette et une impression de lenteur de l’interface utilisateur. En supprimant cette ligne, l’interface utilisateur est rapide – mais elle place les choses au mauvais endroit …

Il semble bien établi que .width() est relativement lent dans jQuery> 1.8 principalement pour deux raisons:

Le but de l’appel width() de mon code est de voir si, et dans quelle mesure, une conception réactive a été réduite. Il doit examiner l’élément wrapper d’un widget, qui a la width: 100%; (mais peut se trouver dans une colonne ou un autre conteneur, en fonction du site / de la page qui l’héberge), et doit voir quel% de la largeur maximale de ce wrapper est réellement affiché.

Un autre code basé sur un système de coordonnées différent me donne l’emplacement, en pixels, d’une étiquette, puis je dois utiliser un facteur de mise à l’échelle (essentiellement = $wrapper.width() / maxWidth; ) pour réduire l’emplacement afin que Par exemple, si la page est affichée dans une fenêtre / un périphérique étroit et que le wrapper correspond à 50% de sa taille maximale, les décalages supérieur et gauche des libellés correspondent à 50% de leurs valeurs par défaut.

Existe-t-il un moyen quelconque d’accéder à ces données pour savoir combien un élément% -width a été réduit sans provoquer de refusion et les autres choses qui .width() appels .width() ?

Choses que j’ai essayées ou exclues:

  • .outerWidth() est exactement aussi lent que .width()
  • .get(0).clientWidth (l’option purement Javascript / non-Jquery) est aussi presque aussi lent que .width() (vraisemblablement, c’est donc le refoulement qui est à l’origine du problème)
  • J’ai remarqué que sur la plupart des navigateurs, si je fais l’un de ces .get(0).clientWidth suivi de l’un des .outerHeight() dans l’autre dimension (par exemple .get(0).clientWidth suivi de .outerHeight() ), les appels après le premier sont très rapides (~ 20 fois). plus rapide). Vraisemblablement, étant donné que la redissortingbution vient d’être effectuée et que les propriétés des éléments viennent d’être consultées, elles sont en quelque sorte mises en cache. Mais l’effet ne tient pas pour les appels répétés à la fonction, mais dans un appel de fonction.
  • .css("width") sert évidemment à rien car cela me donnerait 100% dans tous les cas
  • J’ai envisagé d’obtenir la largeur de la fenêtre , mais les choses se compliquent en fonction de la disposition des colonnes de la page qui héberge cet élément. Par exemple, si mon wrapper est dans une disposition à deux colonnes et que la fenêtre est un peu plus large que le point d’arrêt qui réduit les deux colonnes, la fenêtre sera plus large que la taille maximale de l’élément wrapper, mais ce dernier ne sera pas 100% de sa largeur maximale.

[ Mise à jour ] Je pensais avoir trouvé un moyen de contourner mon besoin de résoudre le problème et de positionner mes étiquettes sans accéder à la mise à l’échelle de l’élément: comme j’avais déjà la variable maxWidth en pixels et les décalages en pixels, j’en avais assez data pour calculer un pourcentage de décalage pour mes étiquettes avec leftOffset_px / maxWidth_px et topOffset_px / maxHeight_px , puis + '%' et l’appliquer comme décalage top et left CSS de chaque étiquette. C’est ridiculement plus rapide – maintenant moins de 1 milliseconde, donc vite ma fonction basée sur l’horodatage ne peut pas le mesurer!

Malheureusement, j’ai aussi une autre fonction qui vérifie que les étiquettes, qui ont une largeur fixe, ne débordent pas le conteneur sensible, et pour cela, je dois prendre en compte la largeur de pixel actuelle du conteneur ou son facteur d’échelle. .

Vous ne savez pas trop à quel point cela pourrait être une amélioration, mais vous pouvez essayer d’append un élément positionné de manière absolue, ne contenant aucun enfant, à la racine de votre widget, dans le seul but de lire sa largeur. Je pense que les éléments en position absolue ne font que rediffuser ses enfants

 .root { position: relative; } .ruler { position: absolute; width: 100%; } 

_

 

 var updatedWidth = $('.ruler').width() 

(Bien que je sois d’accord avec les commentaires disant que vous devriez essayer de résoudre avec CSS)