js
js 事件循环
js 是单线程语言,事件循环是为了协调事件、用户交互、脚本、UI 渲染和网络处理等行为,防止主线程阻塞
主线程
一些具有回调函数的事件将进入执行栈中,等待主线程读取,等待主线程读取,遵循先进先出原则。主线程循环:即主线程会不停的从执行栈中读取事件,会执行完所有栈中的同步代码。当遇到一个异步事件后,并不会一直等待异步事件返回结果,而是会将这个事件挂在与执行栈不同的队列中,我们称之为任务队列(Task Queue)。当主线程将执行栈中所有的代码执行完之后,主线程将会去查看任务队列是否有任务。如果有,那么主线程会依次执行那些任务队列中的回调函数。
宏任务与微任务
异步任务分为 宏任务(macrotask) 与 微任务 (microtask)
宏任务(macrotask): script(整体代码)、setTimeout、setInterval、UI 渲染、 I/O、postMessage、 MessageChannel、setImmediate(Node.js 环境)
微任务(microtask): Promise、 MutaionObserver、process.nextTick(Node.js 环境)
Event Loop(事件循环)
执行栈选择最先进入队列的宏任务
然后执行微任务
...循环执行完全部任务(宏任务-微任务-宏任务)
数据类型
值类型(基本类型)
字符串(string)、数值(number)、布尔值(boolean)、undefined、空值(null)、symbol
引用类型
对象(Object)、数组(Array)、函数(Function)
diff 算法
计算出 Virtual DOM 中真正变化的部分,并只针对该部分进行原生 DOM 操作,而非重新渲染整个页面
tree diff
两棵树只对同一层级节点进行比较,只要该节点不存在了,那么该节点与其所有子节点会被完全删除,不在进行进一步比较
只需要遍历一次,便完成对整个 DOM 树的比较
component diff
同类型组件,组件 A 转化为了组件 B,如果 virtual DOM 无变化,可以通过 shouldComponentUpdate()方法优化
不同类型的组件,那么 diff 算法会把要改变的组件判断为 dirty component,从而替换整个组件的所有节点
element diff
key 往前移动的节点不进行任何操作,所以当把最后一个节点移动到头部时,性能损耗最大
插入: 新的组件不在原来的集合中,而是全新的节点,则对集合进行插入操作
删除: 组件已经在集合中,但集合已经更新,此时节点就需要删除
移动: 组件已经存在于集合中,并且集合更新时,组件并没有发生更新,只是位置发生改变(同一层的节点添加唯一 key 进行区分,并且移动,当新集合中位置在旧集合之后时,需要移动)
原型链
事件
事件流
事件捕获阶段
目标阶段
事件冒泡阶段
事件冒泡
由内向外进行事件传播,直到根结点
事件捕获
从根结点开始,由外向内进行事件传播,直到目标元素
事件代理
利用事件冒泡的原理,将事件处理器添加到父元素,等待子元素事件冒泡,通过target属性能区分子元素,从而对不同子元素做不同处理
减少了事件处理器,节省内存
模块化
ES6 module
commonjs
V8垃圾回收机制
Last updated