【Vue原理系列】(一)简要总结Vue3运行时+编译时原理

文章目录

  • 前言
  • 一、命令式和声明式
  • 二、二者的性能比较
  • 三、运行时和编译时
  • 总结

前言

要讨论vue3的运行时和编译时框架设计,我们可以先来看看 什么叫命令式什么叫声明式?
首先我们先确定 Vue3是运行时+编译时的框架,其次我们再来看看为什么是?单纯的运行时或者编译时又有什么优缺点呢?

一、命令式和声明式

命令式框架最突出的就是关注编码过程,例如Jquery就是一个命令式框架哟。

- 获取id为content的div
- 设置文本内容为 hello vue
- 绑定点击事件
- 点击弹出 nice to meet you!
// 将其翻译为代码
$('#content').text('hello vue').on('click',()=>{alert('nick to meet you')})
// 原生写法
const div = doucument.querySelector('#content')
div.innerText = 'hello vue'
div.addEventListener('click',()=>{alert('nice to meet you')})

所以,命令式就是看中过程,有种隐隐的过程与代码的逻辑一一对应的感觉。

声明式更关注结果,内部过程则是予以封装了。
例如上面的代码可以用声明式的方式:

<div @click="() => alert('nick to meet you')">hello vue</div>

看起来很简洁吧,这是Vue封装后的。但Vue的内部实现一定是命令式的,只是暴露给开发者的是声明式的。

二、二者的性能比较

结论:声明式性能<=命令式性能
1.命令式代码更新性能消耗 = 修改消耗
2.声明式代码更新性能消耗 = 找出差异的消耗+ 修改差异的消耗
于是,Vue要做的就是,最小化找出差异的消耗,这里vue使用了虚拟DOM
虚拟DOM理论上不比原生JS性能高,但这是理论上,因为大多数情况下,写出绝对优化了命令式代码是消耗精力的。

然后,我们需要明确一点:JS对象操作的效率远高于DOM操作

那么,在创建页面时
虚拟DOM需要 创建虚拟JS对象(VNode)+新建DOM元素的Dom操作
命令式需要:渲染HTML字符串(js)+ 新建DOM元素的Dom操作
到目前为止,虚拟DOM可能性能上是小于等于命令式的

但轮到修改页面时:命令式需要进行全量的更新:重新获取HTML字符串 + 销毁DOM + 创建所有新DOM
虚拟DOM:创建js对象 + 找出差异(js层面) + 更新差异DOM
两者的性能差异随着页面变大也会越来越大。

三、运行时和编译时

我们先来看看

纯运行时模型:一个Render函数 + 符合树形结构的数据对象

// 数据对象
const obj = { 
	tag:'div',
	children:[
	  {tag:'span',children:'hello vue'}
	]
}
// render 函数
function Render(obj, root) {
    const el = document.createElement(obj.tag)
    if (typeof obj.children === 'string') {
        const text = doucument.createTextNode(boj.children)
        el.appendChild(text)
    } else if (obj.children) {
        //递归render,使用el作为root
        obj.children.forEach(child => Render(child, el))
    }
    root.appendChild(el)
}
// 用户直接调用
Render(obj,doucument.body)

运行时 + 编译时模型:一个Render函数 + 一个Compiler函数 + html

const html = `
hello vue
`
const obj = Compiler(html) Render(obj,doucument.body)

编译时模型: 一个Compiler函数 + html

const html = `
hello vue
`
const div = document.createElement('div') const span = document.createElement('span') span.innerText = 'hello vue' div.appendChild(span) document.body.appendChild(div)

这样就将其直接编译成了命令式代码

总结

  • 纯运行时:没有编译过程,无法分析用户输入,也就只能傻傻的全局改变
  • 运行时 + 编译时:如果加入编译,则可以分析用户输入,有些可能不会改变,有些内容可能改变了,这样我们修改改变的部分就好啦。
  • 纯编译时:代码必须编译好才能运行,性能更好,但是灵活性较差。

Vue3选择了运行时 + 编译时,并且其核心也是Diff算法。同时,Vue在保留运行时的情况下,性能也在逼近纯编译时。

你可能感兴趣的:(前端笔记,vue.js,javascript,前端)