主机参考:VPS测评参考推荐/专注分享VPS服务器优惠信息!若您是商家可以在本站进行投稿,查看详情!此外我们还提供软文收录、PayPal代付、广告赞助等服务,查看详情! |
我们发布的部分优惠活动文章可能存在时效性,购买时建议在本站搜索商家名称可查看相关文章充分了解该商家!若非中文页面可使用Edge浏览器同步翻译!PayPal代付/收录合作 |
微信小程序开发教程专栏介绍了Rax小程序运行时的方案。2020年3月,在支持编译时方案后,rax小程序发布了支持运行时方案的版本。到目前为止,rax仍然是业界唯一同时支持编译时和运行时解决方案的小程序开发框架。本文将介绍rax applet运行时方案的原理和我们的思考。
回顾编译时方案在介绍运行时方案之前,让我们回顾一下什么是编译时方案。顾名思义,编译时方案侧重于编译,代表框架是tarov2.x,通过静态编译,将JSX转化为applet的模板语言(即WXML/AXML等。),辅以轻量级运行时JS代码,抹平了小程序生命周期和React生命周期的差异,使用户可以用熟悉的React DSL开发小程序。Rax的编译时scheme原理和Tarov2.x类似,具体实现可以参考之前的文章:Rax到applet链接原理分析(一)和Rax applet编译时scheme原理分析。与编译时方案不同,运行时方案侧重于运行时的渲染能力,不依赖静态编译,因此几乎没有语法限制,这也是其最大的特点。让我们来看看运行时方案的实现原理。
基础小程序的底层实现其实是基于Web技术的,但是体现到开发者层面就和Web大不相同了。在applet中,逻辑层和视图层是隔离的。逻辑层通过独特的setData方法向视图层发送数据触发渲染,视图层通过事件触发逻辑层代码。其架构如下图所示。相比Web开发,开发者可以通过JS调用浏览器提供的DOM/BOM API随意渲染内容,小程序的架构更加封闭,也更加安全,但这也意味着Web代码不能直接在小程序上运行。
对于现代前端框架(React/Vue),底层基本上是通过调用DOM API来创建视图。applet的视图层模板需要开发者提前编写,也就是说applet中不允许动态创建DOM的方式。但是,小程序自定义组件的“自引用”特性为动态创建DOM打开了一个突破口。所谓自引用,是指自定义组件支持使用自身作为子节点,也就是说我们可以通过递归引用的方式构造任意级别任意个数的DOM树。
例如,假设applet自定义组件元素的WXML模板如下所示:
& lt视图& gt& ltblock & gt& lt元素& gt& lt/element & gt;& lt/block & gt;& lt/view & gt;& lttext & gt{ { r.content } } & lt/text & gt;复制代码注意到元素在模板中递归引用自身,并通过条件判断终止递归。因此,当逻辑层通过setData传递以下数据时:
{ & quot节点& quot:& quot1 & quot,& quot标记名":& quot查看& quot,& quot儿童& quot:
事件系统Rax小程序运行时,模拟DOM/BOM API的库为miniapp-render,支持的API如下:
除了处理渲染数据,另一个重要的是事件系统。它通过EventTarget基类实现了一套完整的事件调度机制。逻辑层的DOM节点都继承自EventTarget,通过唯一的nodeId收集自己的绑定事件。视图层模板上的每个内置组件都会绑定nodeId,监听所有可触发的事件,比如一个简单的视图标签,它会绑定BindTap/bindtuchstart/bindtuchend等事件。当事件被触发时,通过事件获取目标节点id。currenttarget.dataset.nodeid,然后触发用户在这个节点上绑定的对应函数。
工程设计Rax小程序运行时的主要流程遵循Rax Web的设计,Web端Webpack封装的JS捆绑包可以在小程序运行时重用。我们通过插件将miniapp-render模拟的窗口和文档变量注入到bundle中,然后生成一个固定的小程序项目骨架,在app.js中加载JS Bundle,整体工程结构如下图所示:
MPA还是SPA?以上架构是逐渐演变的结果。最初,我们使用webpack的多入口模式来封装运行时小程序代码,即每个页面都会作为一个入口独立封装。这使得小程序在行为上更像一个MPA。这样带来的问题是,页面之间普遍依赖的代码不是在同一个内存中执行的,这与原生小程序的性能不一致。这种差异导致我们最终决定改变项目打包模式。目前版本的Rax运行时小程序更符合SPA的形式,所有业务代码都打包成一个JS文件。
我们在小程序运行时上修改了Rax项目入口的Rax -APP包的链接。初始化的时候会根据路由返回每个页面的渲染函数。render函数创建根节点(document.createElement)以在其上安装相应的RAX组件,并将根节点附加到正文节点(document.body.appendChild)上。小程序的每一页都会创建一个独立的文档,并在onLoad生命周期内将其设置为全局变量,然后调用其对应的render函数独立渲染每一页。
性能调优从上面小程序运行时的原理来看,其性能与原生相比有一定差距,主要是以下几个方面造成的:一是逻辑层运行一个完整的Rax+处理VDOM,通过模拟DOM/BOM API生成setData数据需要更多的计算时间;其次,与原生小程序相比,需要传输更多的setData数据,如果容器层的数据序列化能力较弱,会大大增加数据传输的时间消耗;第三,视图层通过自定义组件动态递归生成视图,我们知道递归动作本身就是一个性能损失点。另外,由于无法提前知道用户需要绑定的属性和事件,所有的属性和事件都只能提前在自定义组件模板中绑定,导致小程序运行过程中出现很多无用的事件,进一步增加了负担。经过我们的基准计算,运行时小程序框架(包括Rax/Taro/Remax等)之间有40%左右的性能差距。)和支付宝小程序平台上的原生小程序。
Rax小程序运行时发布后,其性能明显不同于其他运行时框架,因此我们推出了专门的性能调优计划。通过以下几个方面的重构,Rax小程序的性能成功提升到业界领先水平,与Taro/Remax基本处于同一水平。
准确更新数据。在旧版本中,setData的数据是完全更新的。虽然有dom子树划分和批量更新的设计,但是数据传输还是有很多冗余。在重构版本中,Rax增加了节点渲染判断,未挂载的节点不需要触发更新;所有更新都聚集在顶层根节点进行统一批处理,通过精确计算数据更新的路径实现局部更新。例如,更新节点的class属性时,setData的数据可能是:
{ & quotroot.children.[0].children.[1].class & quot:& quot活动& quot}复制代码的内置applet组件不需要维护其属性列表,而是直接根据用户传递的参数赋值。在旧版本中,我们维护所有内置组件的属性,在获取属性值时需要调用domNode.getAttribute,这有一定的性能开销。重构版Rax直接根据用户传递的属性赋值,将默认值设置的操作移到视图层WXS/SJS进行处理。
更新miniapp-render中的数据结构。经过梳理,Rax去掉了冗余的树数据,重写了API如getaElementById重构类,如属性和类列表;使用了更适合场景的Map/Set等数据结构,提升了整体数据处理性能。
渲染模板优化。支付宝小程序中,Rax使用模板进行递归调用;在微信中,Rax先用模板调用元素,再用模板,避免了微信上递归调用模板的层数限制。在模板中,我们尝试使用模板is语法进行判断,减少a:if/wx:if条件的判断,提高模板递归的性能。
混合使用,无论是出于旧业务迁移还是性能考虑,Rax小程序运行时都需要混合使用。目前Rax已经可以和小程序内置组件、小程序自定义组件、小程序页面、小程序插件混合使用。其中,使用小程序定制组件是最复杂的。
与applet定制组件混合在Rax中使用applet定制组件时,引入路径需要与usingComponents一致(例如,从'导入定制组件../components/customcomp/index ')。在编译阶段,Rax项目使用Babel插件进行静态代码分析。当它检测到JSX使用的组件是applet自定义组件时(根据其导入路径中是否有同名的axml文件),会缓存其使用的属性和事件,然后通过webpack插件动态生成递归模板。在运行时创建节点的阶段,通过查询缓存来判断该节点是否为自定义组件。如果是自定义组件,缓存中的属性将被插入到其呈现数据中,并且事件将被绑定到自定义组件实例。
与编译时组件混合(双引擎混合)Rax小程序编译时方案产生的组件,从使用形式上可以直接视为小程序自定义组件。Rax项目加强了运行时和编译时之间的联系。在Rax小程序运行时使用编译时组件的npm包时,用户不需要引入组件的具体路径,只需要像使用普通组件一样引入即可。Rax项目会根据组件package.json中是否有miniappConfig字段来自动判断是否是Rax多端组件,然后直接使用其编译时组件来实现。
未来优化方向Rax作为业内唯一同时支持编译期和运行期引擎的小程序开发方案,由于能够同时使用两种引擎,可以实现性能和开发效率的完美平衡。未来,Rax将实现更灵活的双引擎混合使用模式,例如支持指定单个项目中的一个组件由编译时引擎编译,这将为业务提供更大的灵活性。
综上所述,以上是Rax小程序运行时方案的原理分析。运行时方案解决了编译时方案固有的语法限制,但也有明显的性能约束。可以说,在2020年的当前节点,小程序开发仍然没有所谓的银弹,或许整合Rax小程序双引擎会是一个相对范围内的最优方案。没有人能说对标的小程序能走多远,开发者在未来相当一段时间内还是会面临各种问题。站在小程序开发框架的角度,只希望所有开发者都能选择最适合自己的框架,快速高效的完成小程序的开发。
这几篇文章你可能也喜欢:
本文由主机参考刊发,转载请注明:Rax applet运行方案的解密与思考 https://zhujicankao.com/120752.html
评论前必须登录!
注册