队列是一个 先进先出(FIFO) 的数据结构
js
中没有队列,但我们可以用 数组或链表 实现队列的所有功能
队列的常用操作:
enqueue(element)
:向队列尾部添加一个(多个)新的项dequeue()
:移除队列的第一项,并返回被移除的元素front/peek()
:返回队列中的第一个元素isEmpty()
:判断队列是否为空size()
:返回队列的元素个数队列的结构示意图:
栈是一种 后进先出(LIFO) 的数据结构
在 js
中没有栈,但我们可以用 数组或链表 实现栈的所有功能
栈的常用操作:
push(入栈)
pop(出栈)
peek(返回栈顶元素)
isEmpty(判断是否为空栈)
size(返回栈里元素个数)
栈的结构示意图
实现栈结构有两种比较常见的方式:
链表也是一种数据结构,js 中没有自带链表结构,后续会写关于链表的文章,本章先使用数组来实现。
webpack
作为前端目前使用最广泛的打包工具,在面试中也是经常会被问到的。
比较常见的面试题包括:
webpack
性能优化?webpack
来回答)webpack
的性能优化比较多,我们可以对其进行分类:
exclude
、cache-loader
等)大多数情况下,我们会更加侧重于 第一种,因为这对线上的产品影响更大。
虽然在大多数情况下,webpack
都帮我们做好了该有的性能优化:
mode
为 production
或者 development
时,默认 webpack
的配置信息;本章,就让我们来学习一下 webpack
性能优化的更多细节
我们之前完成过一个 patchChildren
的方法,该方法的主要作用是为了 更新子节点,即:为子节点打补丁。
子节点的类型多种多样,如果两个 ELEMENT
的子节点都是 TEXT_CHILDREN
的话,那么直接通过 setText
附新值即可。
但是如果 新旧 ELEMENT
的子节点都为 ARRAY_CHILDREN
的话,那么想要完成一个 高效 的更新就会比较复杂了。这个时候,我们就需要,比较两组子节点,以达到一个高效的更新功能。这种 比较的算法 就是 diff
算法。
vue
中对 diff
算法的描述在 packages/runtime-core/src/renderer.ts
的 patchKeyedChildren(1759行)
方法中:
观察该方法,可以发现该方法内部被分成了 5
块( 5 种场景):
sync from start
:自前向后的对比sync from end
:自后向前的对比common sequence + mount
:新节点多于旧节点,需要挂载common sequence + unmount
:旧节点多于新节点,需要卸载unknown sequence
:乱序这 5
块就是 diff
的核心逻辑。我们本章就是围绕这五种场景进行分析和实现,现在,就让我们开始循序渐进的解开 diff
算法的神秘面纱吧~~~
在实现了 ELEMENT
、COMMENT
、TEXT
节点的挂载后,我们最后再来实现一下组件的挂载与更新
开始实现组件之前,我们需要明确 vue
中一些关于组件的基本概念:
组件本身是一个对象(仅考虑对象的情况,忽略函数式组件)。它必须包含一个 render
函数,该函数决定了它的渲染内容。
如果我们想要定义数据,那么需要通过 data
选项进行注册。data
选项应该是一个 函数,并且 renturn
一个对象,对象中包含了所有的响应性数据。
除此之外,我们还可以定义例如 生命周期、计算属性、watch
等对应内容。