服务器之家:专注于服务器技术及软件下载分享
分类导航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服务器之家 - 编程语言 - JavaScript - vue.js - Vue nextTick的原理解析

Vue nextTick的原理解析

2022-03-09 16:25我在曾经眺望彼岸 vue.js

这篇文章主要介绍了Vue nextTick的原理解析,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下

使用过Vue的小伙伴们都知道,Vue里的nextTick可以获取到更新后的DOM, 今天我就来讲解下nextTick里面究竟做了什么?

开始讲解前,我们需要知道了解一个概念,那就是Event Loop

Event Loop

Event Loop翻译过来就是事件循环, 一个Event Loop会包括一个或多个task队列,持续线程会从队列中取出最早进入队列的任务进行执行,被取出的任务就叫做macroTask(宏任务), 每个macroTask都有一个任务源, 每个macroTask处理完之后就从队列中取出下一个时间最早进入的macroTask再重执行

任务源:

?
1
2
3
4
5
6
7
8
9
10
11
```
    1. script
    2. 事件
    3. Dom交互
    4. I/O
    5. UI Render
    6. setTimeout
    7. setInterval
    8. requestAnimationFrame
    .....
```

也就是说碰到以上几种情况就会产生一个macroTask并且推入到队列中

miscroTask(微任务)

执行完每个macroTask之后,主线程会去检查该macroTask下的microTask是否为空,如果不为空,则按照时间顺序从早到晚取出,如果途中有遇到新的microTask, 那么会继续将该microTask推入到microTask队列里

UI Render(重点)

伴随着miscroTask队列的清空,主线程就会执行UI Render, 也就是渲染界面,但是浏览器它并不会每次在UI Render任务下一定会渲染界面,视情况而言,现在主流浏览器一般都是按照60HZ 也就是16.7ms刷新频率进行渲染(不是精确估量),一个macroTask通常是小于16.7ms, 所以浏览器每次会根据情况进行渲染

总结下一个循环

1. 从macroTask队列里取出最早添加进去的
2. 开始执行task, 途中如果遇到新的macroTask,就会将其添加到macroTask队列的最后面
3. 执行完macroTask之后,event loop会去寻找microTask队列
4. 同样的道理,如果途中遇到新的microTask,将其放入该macroTask下的microTask队列最后面
5. 执行完microTask,会执行UI Render macroTask
6. 浏览器会根据现有情况决定是否更新DOM,通常是按照60HZ的频率去更新
7. 至此,一个event loop结束了

nextTick

我们开始分析nextTick

Vue nextTick的原理解析

根据上图
我们看到nextTick的几种写法:

?
1
2
1. this.$nextTick(cb)
2. this.$nextTick().then(cb)

所有的cb都会被放入到callbacks数组里,等待一次性调用
上图中我们看到了主要是由timerFunc这个函数来进行调用回调, 那么我们下面来着重介绍这个函数,首先看下源码

Vue nextTick的原理解析

我们可以看到timerFunc在不同情况下不同的赋值情况

首先会判断浏览器是否支持promise属性, 如果支持, timerFunc就会被赋值成Promise, 这里有个小小的问题,那就是在ios下,虽然是具备Pormise对象,并且会将它推入到microTask队列里,但是队列却不会更新,这个时候需要添加一个macroTask来强制刷新microTask队列

MutationObserver, 相信很多人并不清楚这个Api, 这是一个能够监听DOM变化的API,并且属于microTask, 优先级低于Promise 在创建一个新的文本节点后,手动更改其文本节点来触发microTask,

这里会有个小小的问题:

该文本节点渲染成功后,一定能代表其他的DOM渲染成功了吗?

这是个备选方案, 主要还是因为它是一个微任务,所以才使用它,并不是因为它监听了DOM

微任务都失败后, 退而求其次,选择setImmediate, 这是一个只有高版本IE和Edge浏览器才可能拥有的API, 其主要是用于计算大量数据的时候使用

最后就是setTimeout

看到这里,你会不会有疑惑?

上面的代码并没有说明nextTick是在监听DOM更新后才执行的? What????当时脑袋就duang了一下

那么接下来说的就是重中之重

DOM Tree的更新是实时的,DOM Tree的更新是实时的,DOM Tree的更新是实时的, 重要的事说3遍, 这意味着你无需去监听DOM 更新, 你对DOM的操作是能够实时得到反馈的,上一行代码操作了DOM,下一行就能获取到

那么有人就会产生疑惑了, nextTick究竟是干嘛的?

nextTick的作用是将收集Watcher从队列中一个个取出,并且更改数据,来一次性渲染DOM, 我们知道操作DOM的代价是昂贵的, 浏览器打开一个网页后会开启一个进程,进程是由线程组成的,

1. GUI渲染线程
2. js引擎线程(主线程)
3. EventLoop轮训处理线程
4. 其他线程,例如网络

跨线程操作代价是昂贵的,所以做到一次性渲染Dom,可以有效的优化性能!!

总结

nextTick并不是用来监听DOM变更,因为DOM变更是能够实时获取到的,它的作用是一次性更改数据,并且渲染DOM

以上就是Vue nextTick的原理解析的详细内容,更多关于Vue nextTick的原理的资料请关注服务器之家其它相关文章!

原文链接:https://juejin.cn/post/6844903914068787213

延伸 · 阅读

精彩推荐
  • vue.js详解vue 表单绑定与组件

    详解vue 表单绑定与组件

    这篇文章主要介绍了vue 表单绑定与组件的相关资料,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...

    Latteitcjz6432022-02-12
  • vue.js梳理一下vue中的生命周期

    梳理一下vue中的生命周期

    看过很多人讲vue的生命周期,但总是被绕的云里雾里,尤其是自学的同学,可能js的基础也不是太牢固,听起来更是吃力,那我就已个人之浅见,以大白话...

    CRMEB技术团队7992021-12-22
  • vue.jsVue2.x-使用防抖以及节流的示例

    Vue2.x-使用防抖以及节流的示例

    这篇文章主要介绍了Vue2.x-使用防抖以及节流的示例,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...

    Kyara6372022-01-25
  • vue.jsVue中引入svg图标的两种方式

    Vue中引入svg图标的两种方式

    这篇文章主要给大家介绍了关于Vue中引入svg图标的两种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    十里不故梦10222021-12-31
  • vue.jsVue项目中实现带参跳转功能

    Vue项目中实现带参跳转功能

    最近做了一个手机端系统,其中遇到了父页面需要携带参数跳转至子页面的问题,现已解决,下面分享一下实现过程,感兴趣的朋友一起看看吧...

    YiluRen丶4302022-03-03
  • vue.jsVue2.x 项目性能优化之代码优化的实现

    Vue2.x 项目性能优化之代码优化的实现

    这篇文章主要介绍了Vue2.x 项目性能优化之代码优化的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    优小U9632022-02-21
  • vue.js用vite搭建vue3应用的实现方法

    用vite搭建vue3应用的实现方法

    这篇文章主要介绍了用vite搭建vue3应用的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下...

    Asiter7912022-01-22
  • vue.jsVue多选列表组件深入详解

    Vue多选列表组件深入详解

    这篇文章主要介绍了Vue多选列表组件深入详解,这个是vue的基本组件,有需要的同学可以研究下...

    yukiwu6752022-01-25