diff算法理解第一篇

在vue和react中,diff算法都是重要的部分,经历过jquery的前端开发同行都有体会,发请求拿到接口后,生成一个新的符合html的字符串,各种拼接,然后获取div的节点,在拼到获取的div的里面,很麻烦的,但是在diff里,就变得特别简单了,一个循环,可以搞定原来jquery的很多代码,下面,我说一下我对diff的理解。

所谓的diff算法,是dom的数据化,先处理数据,只操作一次dom,把由原来的拼接一个新的符合html字符串,在获取的div的节点里,塞入拼接好的字符串,在这里可以想一下,假如一个后台管理系统,在jquery的时代,页面进入展示表格,重新渲染一次,你点击查询按钮,如果和进入页面的查询条件没有变(假设返回数据没有变化),表格的内容是要在渲染一次的,但是在diff中,表格的dom是没有变化的,这就能看出性能的差距的。 举个例子

js 复制代码
    let box = document.getElementById("box")
    console.time("a")
    for(let i=0;i<=1000000;i++){
        box.innerHTML=i
    }
    console.timeEnd("a")

    console.time("b")
    let num =0
    for(let i=0;i<=1000000;i++){
        num=i
    }
    console.log(num)
    console.timeEnd("b")

运行结果

同样是循环1000000次,循环一次,操作dom一次,循环一次,操作dom一次,和先处理好数据,然后只操作一次dom,这性能上就明显看出差距来了。

下面说一下diff中一个出名的框架snabbdom,vue2中就是使用的它(vue3中已经不用这个了,不过万变不离其宗,学会了snabbdom,对学习diff底层知识很有帮助的)

sanbbdom的github上的地址github.com/snabbdom/sn...

先写一个最简版的

html部分

js 复制代码
<div id="container"></div>

js部分

js 复制代码
import {
  init,
  classModule,
  propsModule,
  styleModule,
  eventListenersModule,
  h
} from "snabbdom";

const patch = init([
  classModule,
  propsModule, 
  styleModule, 
  eventListenersModule
]);

const container = document.getElementById("container");

const vnode = h("h1",{},"我是sanbbdom");
patch(container, vnode)

运行结果

js代码执行完以后,div里的值就变成了我是sanbbdom。

打印一下vnode,看一下控制台都输出了什么

在控制台中,可以看出来,他把节点变成了一个对象,也就是把dom变成了数据

elm是你的节点类型(如div,span的标签名称)

text是文本内容

现在新生成的div只有一层,如果要生成多层级的div,要变一下第三个参数

js 复制代码
const vnode2 = h("div",{},[
  h("p",{},"我是p标签1"),
  h("p",{},"我是p标签2"),
  h("p",{},"我是p标签3")
])
console.log(vnode2)
patch(container, vnode2)

在浏览器中显示

chilren变成了一个数组,里面是三个p标签的数据,text是undefined,因为div里面是三个子元素,不是文字,这就是一个简单的虚拟节点。

在patch方法里,完成了新旧节点的替换,这个替换规则又是怎么替换的,这样分为两种种情况。(这里只针对刚才写的简单patch讨论,复杂的先不涉及)

1 新旧节点的标签名不一样,path方法会先删除旧节点的内容,然后再把新节点的内容插进去。 2 只能通级别比较。

相关推荐
海带紫菜菠萝汤2 分钟前
FFmpeg.wasm 实践:在浏览器中运行 FFmpeg 的能力边界与性能瓶颈
前端·javascript·ffmpeg·音视频·wasm
名字还没想好☜9 分钟前
React 受控输入框光标跳到末尾:格式化输入时的 selection 丢失 bug 与修复
前端·javascript·react.js·bug·react·next.js
Access开发易登软件10 分钟前
Access 怎么做前后端分离?用 Web API 读写 SQL Server
前端·数据库·人工智能·microsoft·excel·access
10share18 分钟前
React 新一代样式隔离方案 —— 编译时、零运行时、原生写法
前端·react.js
Revolution6129 分钟前
Node.js 是什么:前端项目里哪些事情由它完成
前端·面试·node.js
我要两颗404西柚1 小时前
Stage three:VUE工程化与实战工具
前端·javascript·vue.js
光影少年1 小时前
RN 的EventEmitter 双向通信
前端·react native·react.js
布鲁飞丝1 小时前
从零实现富文本编辑器#-浏览器选区与编辑器选区模型同步
java·前端·编辑器
写不来代码的草莓熊2 小时前
Cesium 地图交互绘制圆形、多边形
前端·javascript·地图
weixin_427771612 小时前
前端版本检测
前端