第一章 VUE框架设计

107 阅读4分钟

命令式和声明式

  1. 命令式框架的一个最大的特点是关注过程, 如 jquery
  2. 声明式框架更加关注结果, 命令式实现上面的自然语言描述的功能,如 vue, react
// Vue.js帮我们封装了命令式的过程代码,然后暴露给我们的是这种声明式的 。
<div @click="()=>alert('ok')">hello world</div>

性能与可维护性的权衡

  1. 结论:声明式代码的性能 不优于 命令式代码的性能。
  2. 命令式代码的更新性能消耗=更新新内容的性能消耗;
  3. 声明式代码的更新性能消耗=更新新内容的性能消耗+找出差异的性能消耗;
  4. 只有找出差异的性能消耗足够的小无限接近于,性能才能向命令式靠近。
  5. Vue.js 使用声明式框架的主要理由就是可维护性高于命令式框架,框架设计者只能在保持可维护性的同时尽量让性能损耗最小化

关于虚拟 DOM 的性能

  1. JavaScript 层面的操作要比 DOM 操作快得多,速度不是一个数量级的
  2. 虚拟 DOM 树就是 JavaScript 对象,是真实的 DOM 描述, 操作虚拟 DOM 是 javaScript 层面的操作

性能对比

  1. 虚拟 DOM 创建新页面的过程是,第一步创建 JavaScript 对象,真实的 DOM 描述;第二步是 Diff 出差异,递归地遍历虚拟 DOM 树并创建真实的 DOM。
  • innerHTML 创建页面性能 = HTML 字符串拼接的计算量 + innerHTML 的 DOM 计算量
  • 用虚拟 DOM 创建页面性能 = 创建 JavaScript 对象的计算量 + 创建真实 DOM 的计算量
  1. 上面的公式可以看出来,无论是 JavaScript 层面的计算,还是 DOM 层面的计算,其实两者的差距几乎没有。

  2. 创建新页面时性能对比: 都需要创建新建所有的 DOM 元素。只从创建页面的性能对比来看的话,虚拟 DOM 根 innerHTML 没有什么优势。

  3. 页面更新时的性能对比:

  • innerHTML 是重新构建 HTML 字符串,再重新设置 DOM 元素的 innerHTML 属性,哪怕只是只改了一个字,也要重新设置 innerHTML 属性,要销毁所有旧的 DOM 元素,再全部重新创建新的 DOM 元素。

  • 虚拟 DOM 的更新页面:创建新的 JavaScript 对象+Diff,多了一个 Diff 的性能消耗,这个消耗是 JavaScript 层面上运算,不会产生数量级的差异。Diff 作用是判断出页面仅更新的必要元素,而非全部元,所以性能优势极大;

  • 更新页面时 ,innerHTML 的性能消耗是跟更新的页面大小相关的,更新的页面越大,性能的消耗也会越大。而虚拟 DOM 只会更新变化的那一部分元素。

运行时 和 编译时

1.纯运行时程序:灵活,简单,直接基于用户的调用的操作和入参,得到对应的结果

  function render(要渲染的虚拟DOM数据,根节点) {
     根基的.appendChild(字节的)
  }
  // 调用
  render(obj, '#app')

纯运行时的缺点也很明显:用户的输入是在代码运行时,无法对用户的内容进行有效的分析和标记,不利于性能优化

  1. 编译时 + 运行时
  • Vue.js3 是一个编译时+运行时的框架,它在保持灵活性的基础上,还能够通过编译手段分析用户提供的内容,从i而进一步提升更新性能。
  // 模板
  <tempalte>
    <div>
       <h1>{{ title }}</h1>
       <ul>
          <li v-for="item in list">{{ item }}</li>
       <ul>
    </div>
  </tempalte>
  // 渲染函数
  function render(要渲染的虚拟DOM数据,根节点) {
     根基的.appendChild(字节的)
  }

  // 编译函数
  function compiler(模板) {
    // 分析模板中用户内容
    // 那些是静态的
    // 那些是动态了
    // 哪一个点是动的,打上标记
    return 基于模板返回虚拟DOM 
  }
  // 框架调用
  // 编译
  let vdom = compiler(template)
  // 渲染
  render(vdom, '#app')
  // 
  • 优势1:声明式的template,提升用户体验, 开发更直观,易于维护
  • 优势2:编译阶段可对用户代码 进行分析,可在编译成的新代码中打标记, 后续运行时基于标记继续代码性能优化
  1. 纯编译时:有以上的有点,但是用户提供的内容必须编译后才能运行,有损灵活性