淘先锋技术网

首页 1 2 3 4 5 6 7

第一篇 框架设计概览

本篇主要对于框架设计思路的取舍进行讲解

权衡的艺术

命令式和声明式

首先来介绍一下命令式和声明式的区别和优缺点

  • 原生js
    const div = document.querySelector('#app')
    div.innerHTML = 'hello world'
    div.addEventListener('click', () => { alert('ok') })
  • 命令式(以jQuery为例)
    $('#app') // 获取div
      .text('hello world')  // 设置文本
      .on('click', () => { 'ok' }) // 绑定事件
  • 声明式(Vue.js)
<div @click="()=>alert('ok')" > hello world</div>

从上面的代码可以感觉到,命令式的代码与原生js相似,代码描述的是“做事的过程”;而声明式框架则更关注结果。实际上,Vue.js帮我们封装了过程,内部还是命令式,暴露给用户的则更加声明式。

二者的权衡

先抛出一个结果,在代码性能层面:命令式优于声明式(该结论的前提是,命令式代码编写的足够优雅)

因为在运行代码时,命令式明确知道要修改什么;而声明式为了实现最优更新,需要在内部找到前后代码的差异,再进行修改

  • 命令式代码的更新性能消耗 = 修改消耗
  • 声明式代码的更新性能消耗 = 寻找差异的消耗 + 修改消耗

既然性能方面命令式由于声明式,那声明式有什么优点呢?

声明式避免了手动操作DOM的问题,更加易于入门(比较难写出性能较差的代码)以及后期的维护

Vue.js,或者说开发声明式框架的设计者目标则是:在保持可维护性的同时让性能损失最小化

虚拟DOM

在上面的内容中我们说了声明式框架在内部进行了差异寻找,Vue为了实现寻找差异时对性能的最小化消耗,使用了虚拟DOM

在本节我们可以简单的将虚拟DOM理解为使用一个方法将html文件中的节点都转化为了JS(树)格式的数据(我们将该过程的实现用VNode表示),这颗树就是虚拟DOM

下面我们对JS层面的计算和DOM层面的计算进行性能比较

请添加图片描述

如上图,上边的代码是纯JS层面的计算,循环了10000次;下面是DOM操作循环10000,可以看出JS比DOM操作快几个量级

得出这个结论后,我们来看一下使用innerHTML创建页面和使用虚拟DOM创建页面的性能区别

  • 使用innerHTML创建页面性能:HTML 字符串拼接的计算量 + innerHTML 的 DOM计算量
  • 使用虚拟DOM创建页面性能:创建 JavaScript 对象的计算量 (html转js)+ 创建真实 DOM 的计算量

请添加图片描述

经过比较可以发现:在创建页面时,虚拟DOM和innerHTML的性能消耗差距不大,都是一次JS层面的运算+一次DOM层面的运算

接下来我们比较一下二者在更新页面时的性能

请添加图片描述

  • innerHTML采用的是,一次js运算+摧毁旧的DOM+创建新DOM
  • 虚拟DOM采用,将新页面VNode+Diff算法比较+个别DOM更新

二者相比:innerHTML的DOM操作相比于虚拟DOM多的多,这时虚拟DOM的优势就体现出来了

所以得出一个结论

请添加图片描述
Vue的便选择了一个较为折中的办法