Pourquoi le rendu vue est-il asynchrone ?

青灯夜游
Libérer: 2022-12-21 11:59:09
original
2588 Les gens l'ont consulté

Raison : Cela peut améliorer les performances. Si les mises à jour asynchrones ne sont pas utilisées, le composant actuel sera restitué à chaque fois que les données sont mises à jour ; par conséquent, pour des raisons de performances, Vue mettra à jour la vue de manière asynchrone après cette série de mises à jour de données, au lieu de la mettre à jour immédiatement chaque fois qu'il y a une donnée. mettre à jour la vue.

Pourquoi le rendu vue est-il asynchrone ?

L'environnement d'exploitation de ce tutoriel : système windows7, version vue3, ordinateur DELL G3.

1. Le principe et la fonction de nextTick()

nextTick garantit que le DOM que nous exploitons est mis à jour.

(1) Scénario d'application  : Une fois la vue mise à jour, opérez en fonction de la nouvelle vue.

  • Une opération effectuée après les changements de données, et cette opération nécessite l'utilisation d'une structure DOM qui change avec les changements de données , cette opération doit être placée dans nextTick() dans la fonction de rappel.
  • nextTick()的回调函数中。
  • 如果在created()钩子进行DOM操作,created()中dom还没有渲染,一定要放在nextTick()的回调函数中。
  • Vue采用了数据驱动视图的思想,但是在一些情况下,仍然需要操作DOM。有时候,DOM1的数据发生了变化,而DOM2需要从DOM1中获取数据,那这时就会发现DOM2的视图并没有更新,这时就需要用到了nextTick了。

(2)原理:

  • nextTick 的核心是利用了如 Promise 、MutationObserver、setImmediate、setTimeout的原生 JS 方法来模拟对应的微/宏任务的实现;
  • 本质是为了利用 JS的这些异步回调任务队列实现 Vue 框架中自己的异步回调队列;
  • 本质是对JS执行原理事件循环的一种应用

nextTick 是典型的将底层JS执行原理应用到具体案例中的示例,引入异步更新队列机制的原因∶

如果不采用异步更新,那么每次更新数据都会对当前组件进行重新渲染。所以为了性能考虑,Vue 会在本轮数据更新后,再去异步更新视图。而不是每当有数据更新,就立即更新视图。

  • 为了在数据更新操作之后操作DOM,我们可以在数据变化之后立即使用nextTick(callback)
  • nextTick()将回调延迟到下一个事件循环开始时执行, 这样回调函数会在DOM更新完成后被调用,就可以拿到最新的DOM元素了。 

当你设置 vm.someData = 'new value',DOM 并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新才会进行必要的DOM更新。

(3) vue的降级策略

Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替,进行降级处理。降级处理的目的都是将flushCallbacksSi vous effectuez des opérations DOM dans le hook créé(),

le dom n'a pas été rendu dans créé(),

doit être placé dans la fonction de rappel de nextTick() . Vue adopte l'idée de vue basée sur les données, mais dans certains cas, le DOM doit encore être manipulé. Parfois, les données de DOM1 changent et DOM2 doit obtenir des données de DOM1, vous constaterez alors que la vue de DOM2 n'a pas été mise à jour, vous devez alors utiliser nextTick. (2) Principe :

nextTick Le noyau est d'utiliser des méthodes JS natives telles que Promise, MutationObserver, setImmediate et setTimeout pour simuler le micro/ macro Implémentation de tâches ;

L'essence est de

utiliser ces files d'attente de tâches de rappel asynchrones de JS pour implémenter sa propre file d'attente de rappel asynchrone dans le framework Vue

L'essence ; est d'exécuter JS Une application de la boucle d'événements de principe nextTick est un exemple typique d'application du principe d'exécution JS sous-jacent à un cas spécifique, La raison de l'introduction du mécanisme de file d'attente de mise à jour asynchrone ∶

🎜🎜🎜🎜Si 🎜Si les mises à jour asynchrones ne sont pas utilisées🎜, alors 🎜le composant actuel sera restitué à chaque fois que les données sont mises à jour. 🎜Donc🎜Pour des raisons de performances, Vue mettra à jour la vue de manière asynchrone après cette série de mises à jour des données. 🎜Au lieu de mettre à jour la vue immédiatement chaque fois que les données sont mises à jour. 🎜🎜🎜🎜🎜🎜Afin de faire fonctionner le DOM après l'opération de mise à jour des données, nous pouvons utiliser nextTick(callback) immédiatement après les modifications des données 🎜🎜🎜🎜🎜nextTick() ; pour retarder le rappel Il sera exécuté lorsque 🎜commence la prochaine boucle d'événement De cette façon, la fonction de rappel sera appelée une fois la mise à jour du DOM terminée et le dernier élément du DOM. peut être obtenu. 🎜🎜🎜🎜Lorsque vous définissez vm.someData = 'new value', le DOM ne sera pas mis à jour immédiatement, mais sera mis à jour lorsque la file d'attente asynchrone sera effacée, c'est-à-dire lorsque la prochaine boucle d'événement démarre. 🎜Les mises à jour DOM nécessaires seront effectuées. 🎜🎜🎜🎜🎜(3) La stratégie de rétrogradation de Vue 🎜🎜🎜🎜🎜Vue essaie en interne d'utiliser 🎜Promise.then natif, MutationObserver 🎜 et 🎜setImmediate🎜 pour 🎜file d'attente asynchrone🎜 Si l'environnement d'exécution ne le prend pas en charge, il le fera. être utilisé. 🎜setTimeout(fn, 0) 🎜remplacé pour le traitement de la rétrogradation. Le but du traitement de rétrogradation est de placer la fonction flushCallbacks dans la file d'attente des microtâches ou des macrotâches et d'attendre son exécution dans la prochaine boucle d'événements🎜🎜🎜🎜Il est possible d'actualiser la file d'attente dans🎜cette boucle d'événements Ce qui est rafraîchi 🎜 dans une microtâche peut également être rafraîchi 🎜 dans la prochaine boucle d'événement 🎜. Cela 🎜 dépend de l'environnement d'exécution actuel du code 🎜. Si l'environnement d'exécution actuel prend en charge les promesses, alors nextTick utilisera en fait Promise pour s'exécuter en interne, puis l'actualisation de la file d'attente sera exécutée dans la microtâche de cette boucle d'événements. 🎜🎜🎜🎜🎜La raison pour laquelle on donne la priorité aux microtâches : 🎜la ​​mise à jour de la file d'attente🎜dans les 🎜microtâches nécessitera un rendu d'interface utilisateur de moins🎜 que la mise à jour 🎜dans les macrotâches. 🎜🎜🎜🎜🎜2. Pourquoi Vue utilise-t-il le rendu asynchrone ? 🎜🎜🎜🎜🎜vue est une mise à jour au niveau du composant🎜 Lorsque les données du composant changent, le composant sera mis à jour🎜. Exemple : this.a = 1, this.b=2 (même observateur)🎜🎜

(1) Raison : Si n'utilise pas de mise à jour asynchrone , alors le composant actuel sera restitué à chaque fois que les données sont mises à jour. DoncPour des raisons de performances, Vue mettra à jour la vue de manière asynchrone après cette série de mises à jour des données. Au lieu de mettre à jour la vue immédiatement chaque fois que les données sont mises à jour.

(2) Processus :

  • Vue effectue des mises à jour dom de manière asynchrone Une fois les modifications de données observées, Vue ouvrira une file d'attente, puis la placera dans la même boucle d'événements que les observateurs qui observent les modifications de données. poussé dans cette file d’attente.

  • Si cet observateur est déclenché plusieurs fois, il ne sera placé dans la file d'attente qu'une seule fois. Ce comportement de mise en mémoire tampon peut supprimer efficacement les données en double et éviter les calculs et opérations DOM inutiles.

  • Et dans la boucle d'événement suivante, Vue effacera la file d'attente et effectuera les mises à jour DOM nécessaires.

3) Analyse du code source :

  • Lorsque les données changent, informez l'observateur d'effectuer des opérations de mise à jour via notify ; subs[i].update La vue n'est pas mise à jour);

  • Mettez l'observateur dans la file d'attente. Le queueWatcher effectuera la déduplication en fonction de l'identifiant de l'observateur (plusieurs attributs dépendent d'un observateur si l'observateur ne l'est pas). dans la file d'attente, l'observateur sera ajouté à la file d'attente (la vue n'est pas mise à jour)

  • Exécutez de manière asynchrone la méthode flushSchedulerQueue via nextTick pour actualiser la file d'attente de l'observateur (mettre à jour la vue) ;

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!