原生的实时DOM转Virtual DOM


prtyaa
prtyaa 2023-12-25 15:01:09 67156
分类专栏: 资讯

在之前的几篇文章里,我们讨论了MINA的一些原理。晚上在想着怎么结合Vux + Virtual Dom实现一个名为WINV框架的时候,在探索WCC功能才发现:自己又忽略掉了一个很重要的性能优化细节。这个WCC如果内置在浏览器里,就是可以实时的将DOM转换为以JSON表示的DOM。

先将DOM转换为Virtual Dom,再转换回去的优点是可以分离数据和样式。这也就是为什么React的学习成本高的原因之一了。

Virtual Dom的表现形式

为了将真实的DOM转换为Virtual DOM,我们需要将DOM以一定的形式保存下来,如MINA的:

 

<map longitude="23.099994" latitude="113.324520" markers="{{markers}}" covers="{{covers}}" style="width: 375px; height: 200px;"></map>

如:

 

{
    "attr": {
        "covers": "",
        "latitude": "113.324520",
        "longitude": "23.099994",
        "markers": "",
        "style": "width: 375px; height: 200px;"
    },
    "children": [],
    "tag": "wx-map"
}

又或者是React中的:

 

{"type":"ul","key":null,"ref":null,"props":{"className":"my-list","children":{"type":"li","key":null,"ref":null,"props":{"children":"Text Content"},"_owner":null,"_store":{}}},"_owner":null,"_store":{}}

当然我们也可以自己实现一个比较简单的DOM转为Virtual DOM,如将

 

  var newDiv = document.createElement("div"); 
  var newContent = document.createTextNode("Hi there and greetings!"); 
  newDiv.appendChild(newContent); //add the text node to the newly created div. 

转换为接近原生的:

 

{"nodeType":1,"tagName":"div","attributes":[],"childNodes":[{"nodeType":3,"nodeName":"#text","nodeValue":"Hi there and greetings!","childNodes":[]}]}

原生的Parser与JS Parser

我会假装你已经知道了浏览器相关的很多细节,我也假装我已经对这些细节很清晰。下图一份Webkit浏览器的早期架构图:

如果我们使用JS实现一个将WXML将换为DOM JSON,我们就需要间接通过JavaScript Engine(即JSCore )来转换这个JSON文件。当有大量的DOM的时候,这就不是一件轻松的事了。所以,在WCC的生成代码里对DOM的数量限制为16000。

我们可以用原生的接口来将WX DOM转换为JSON,但是我们没有办法用原生的接口来将DOM JSON转换DOM——毕竟我们还有大量的数据和绑定函数。

而这一点对于混合应用来说,就特别有帮助:

如果这个插件可以用在Cordova上,那么它将改善混合应用的性能。

数据绑定

当我们触发了generateFunc方法的时候:

 

document.dispatchEvent(new CustomEvent("generateFuncReady", {
    detail: {
        generateFunc: $gwx('src/index.wxml')
    }
})

我们调用下面的方法去初始化我们的DOM,并把数据传输进去:

 

var node = generateFunc((0, DataClass.getData)());

函数绑定

MINA的函数绑定机制是由函数名来决定的,如:

 

"bind" === propKey.slice(0, 4) ? createEventHandle(domElement, propKey.slice(4), propValue);
"catch" === propKey.slice(0, 5) ? createEventHandle(domElement, propKey.slice(5), propValue, !0);
"on" === propKey.slice(0, 2) ? createEventHandle(domElement, propKey.slice(2), propValue);

对于其他类型的绑定则是:

 

"style" === propKey ? domElement.setAttribute(propKey, (0, r.transformRpx)(propValue)) : domElement.setAttribute(propKey, propValue)
"animation" === propKey && "object" === ("undefined" == typeof propValue ? "undefined" : i(propValue)) && propValue.actions && propValue.actions.length > 0 && !function() {})

PS:我突然就不想看这个if else经过minify以后的代码了,太恶心了。。。

如,我们的wxml:

 

<view bindtap="bindViewTap" class="userinfo"></view>

我们的propKey是bindtap,我们的propValue是bindViewTap,随后我们就会根据当前的函数名去创建相应的事件。

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=30439
赞同 0
评论 0 条
prtyaaL0
粉丝 1 发表 2554 + 关注 私信
上周热门
银河麒麟添加网络打印机时,出现“client-error-not-possible”错误提示  1323
银河麒麟打印带有图像的文档时出错  1236
银河麒麟添加打印机时,出现“server-error-internal-error”  1023
统信桌面专业版【如何查询系统安装时间】  951
统信操作系统各版本介绍  944
统信桌面专业版【全盘安装UOS系统】介绍  903
麒麟系统也能完整体验微信啦!  889
统信【启动盘制作工具】使用介绍  499
统信桌面专业版【一个U盘做多个系统启动盘】的方法  440
信刻全自动档案蓝光光盘检测一体机  386
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
信创开放社区邀请他人注册的具体步骤如下 15
如何玩转信创开放社区—从小白进阶到专家 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

添加我为好友,拉您入交流群!

请使用微信扫一扫!