沐鸣娱乐


        使用uni-app开发小程序,比直接原生开发小程序好在哪里(uni app开发小程序)

        小程序原生开发有不少槽点 :

        1. 原生wxml开发对Node、预编译器、webpack支持不好,影响开发效率和工程构建流程 。所以大公司都会用框架开发
        2. 微信定义的这套语法,wxml 、wxs ,以及wx:if等语法 ,私有化太强 。不如正经学vue,学会了全端通用,而不是只为微信小程序
        3. vue生态里有太多周边工具,可以提高开发效率,比如ide、校验器、三方库 。。。而微信的开发者工具和专业编辑器相比实在不好用,个性化设置也非常少

        作为前端工程师 ,除了微信小程序 ,还要开发web 、其他小程序甚至App,人们不喜欢来回切换开发工具和变更语法思考方式。

        uni-app自然可以解决这些问题,但开发者又经常有些顾虑:

        1. 怕使用uni-app后,微信小程序里有的功能无法实现 ,受制于uni-app的更新
        2. 怕性能不如原生WXML
        3. 怕框架不成熟,跳到坑里
        4. 担心社区生态不完善

        本文从开发者关心的功能、性能、学习门槛、开发体验、生态  、可扩展性等维度,逐个分析对比,给予说明。

        1.功能实现

        开发者最常问的问题:如果小程序迭代升级 ,新增了一批API,但uni-app框架未及时更新 ,该怎么办 ?

        其实这是误解,uni-app不限制底层API 调用;在小程序端,uni-app支持直接编写微信原生代码。

        类比传统web开发,如果vue、react等框架的使用,造成开发者无法操作浏览器提供的所有api ,那这样的框架肯定是不成熟的 。小程序开发也一样,uni-app框架中  ,同样可调用微信提供的所有原生代码。

        故如果存在某些API(平台特有或新增API) ,uni-app尚未封装 ,开发者可直接在uni-app中编写微信原生API ,即wx.开头的各种API。

        举个例子,目前uni-app虽然尚未封装跨平台的广告(ad)组件 ,但开发者在小程序端依然可以使用微信<ad>组件来展现广告,代码示例如下 :

        <view> <view class=”title”>微信官方banner广告</view> <view style=”min-height: 50px;”> <!– uni-app尚未封装,但可直接使用微信原生的ad组件–> <ad unit-id=”adunit-01b7axxxbf53d74e”></ad> </view> <view class=”title”>微信官方视频广告</view> <view style=”min-height: 50px;”> <!– uni-app尚未封装,但可直接使用微信原生的ad组件–> <ad unit-id=”adunit-9f340xxx64533″ ad-type=”video” ad-theme=”white”></ad> </view></view>

        小程序端运行效果如下:

        使用uni-app开发小程序,比直接原生开发小程序好在哪里(uni app开发小程序)

        包括微信小程序自定义组件、WXS、云开发这些复杂用法 ,在uni-app里一样全面支持。

        所以,结论是 :使用uni-app框架开发,在功能上和原生小程序开发没有区别 ,不会有任何限制 。

        2. 性能体验

        开发者常问的第二个问题 :三方框架 ,内部大多做了层层封装,这些封装是否会增加运行负载,导致性能下降 ?

        同样是多虑了,uni-app不会导致性能下载,甚至对很多环节做了自动优化 ,很多场景下性能体验比微信原生开发更好。

        类似使用vue.js开发web,不但不会造成性能比原生js差,反而由于虚拟dom和差量更新技术的运用,在大多数场景下,比开发者手动写代码操作dom的性能还好。

        小程序中需要频繁的写setData代码来更新数据,这里很重要的就是差量数据更新。如果不做差量,代码性能不好,如果每处逻辑都判断差量数据更新,那代码写起来太麻烦了 。

        使用uni-app,底层自动差量数据更新 ,简单而高性能。

        我们从优化理论、实测数据两个维度来仔细说明 。

        2.1 理论:框架优化方案

        为提高性能体验,小程序从架构设计层面做了很多工作:

        • 逻辑层、视图层分离 ,避免JS运算阻塞视图渲染
        • 单独定义组件标签(wxml),减少DOM复杂度
        • 精简样式(wxss) ,提升渲染性能
        • 复杂组件原生化(video/map等) ,解决web组件的功能/体验缺失

        通过这些规范约束 ,大幅提升了小程序的整体性能体验,但依然存在不少性能坑点 ,其中以setData最为频繁普遍。

        这里引用微信官方的描述,简单介绍一下setData背后的工作原理:

        小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。在架构上,WebView 和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道。当前 ,视图层和逻辑层的数据传输 ,实际上通过两边提供的 evalsuateJavascript 所实现 。

        为简化开发 ,微信将evalsuateJavascript调用封装成了setData JS方法 ,实现视图层和逻辑层的数据传输 ,数据流示意图如下:

        使用uni-app开发小程序,比直接原生开发小程序好在哪里(uni app开发小程序)

        setData的执行会受到很多因素的影响 ,setData每次传递数据量过大或频繁被调用(见微信官方介绍) ,都可能引发性能体验问题。

        幸运的是,uni-app在这两个方面都有优化 。

        2.1.1 减少 setData 传递数据量

        假设当前页面有一个列表(初始值为a,b,c,d),现在要向列表后追加4个新列表项(e,f,g,h) ,我们分别以微信原生、uni-app 两种模式编写代码。

        小程序原生代码:

        page({ data:{ list:[‘a’,’b’,’c’,’d’] }, change:function(){ let newData = [‘e’,’f’,’g’,’h’]; this.data.list.push(…newData); this.setData({ list:this.data.list }) }})

        如上微信原生代码,change方法执行时,会将list中的a,b,c,d,e,f,g,h8个列表项通过setData全部传输过去。

        uni-app 代码:

        export default{ data(){ return { list:[‘a’,’b’,’c’,’d’] } }, methods:{ change:function(){ let newData = [‘e’,’f’,’g’,’h’]; this.list.push(…newData) } }}

        如上uni-app代码 ,change方法执行时,仅会将list中的e,f,g,h4个新增列表项传输过去 ,实现了setData传输量的极简化。

        uni-app借鉴了 westore JSON Diff库 ,在调用setData之前,会先比对历史数据,精确 、高效计算出有变化的差量数据,然后再调用setData ,仅传输变化的数据 ,这样就实现 setData 传递数据量的最小化,大幅提高通讯性能 。

        Tips:也许有些同学对传递数据从a,b,c,d,e,f,g,h8个列表项优化为e,f,g,h4个列表项,不以为然,但我们提醒,不要小看这个机制,上述只是demo示例。

        • 在实际列表场景中,每个列表项可能包含缩略图、标题、摘要、时间等各种信息,每个列表项数据都会更大(假设为1k);
        • 假设当前页面有20个列表项,连续上拉4次后 ,页面变成100条记录;如果再次上拉 ,页面变成120条记录时 ,情况会有不同
        • 上述微信原生的方式,将120条记录数据(120k)全部传输过去
        • 上述 uni-app 模式 ,仅会将新增的20条(101 ~ 120)记录数据(20k)传输过去,数据量是原生方式的1/6!
        • 当页面列表项数据越多,这个差别就越大,页面有200条记录时,uni-app传递数据量会变成微信原生数据传递量的1/10!

        2.1.2 减少 setData 调用频次

        假设我们有更改多个变量值的需求 ,我们分别以微信原生 、uni-app 两种模式编写代码 。

        小程序原生代码:

        change:function(){ this.setData({a:1}); this.setData({b:2}); this.setData({c:3}); this.setData({d:4});}

        如上四次调用setData ,就会引发4次逻辑层 、视图层数据通讯

        uni-app 代码 :

        change:function(){ this.a = 1; this.b = 2; this.c = 3; this.d = 4;}

        如上uni-app的代码,最后会被合并成{“a”:1,”b”:2,”c”:3,”d”:4}一条数据,然后仅调用一次setData完成所有数据传递,大幅降低了setData的调用频次 。

        uni-app之所以有这样的优势,是因为 uni-app 基于 Vue Runtime 深度定制实现,并借助了 Vue 的 nextTick 机制。

        2.2 实测 :性能对比数据

        有了如上的理论分析 ,我们接着进行真机实测,用数据来对比。

        测试模型如下 :

        • 开发内容:开发一个仿微博小程序首页的复杂长列表,支持下拉刷新 、上拉翻页 、点赞。

        仿微博的列表是一个包含很多组件的列表,这种复杂列表对性能的压力更大,很适合做性能测试 。

        • 界面如下:

        使用uni-app开发小程序,比直接原生开发小程序好在哪里(uni app开发小程序)

        • 开发版本:使用微信原生、uni-app分别开发两套代码,uni-app使用cli方式默认安装。
        • 测试代码开源(Github仓库地址:https://github.com/dcloudio/test-framework), Tips:若有同学觉得测试代码写法欠妥,欢迎提交 PR 或 Issus,本项目下还有其它框架的测试代码,开发者可忽略
        • 测试机型:红米 Redmi 6 Pro、MIUI 10.2.2.0 稳定版(最新版)、微信版本 7.0.3(最新版)
        • 测试环境:每个框架开始测试前 ,杀掉各App进程 、清空内存 ,保证测试机环境基本一致 ;每次从本地读取静态数据 ,屏蔽网络差异。

        从触发上拉加载到数据更新 、页面渲染完成,需要准确计时 。人眼视觉计时肯定不行,我们采用程序埋点的方式,制定了如下计时时机:

        • 计时开始时机 :交互事件触发 ,框架赋值之前,如:上拉加载(onReachBottom)函数开头
        • 计时结束时机:页面渲染完毕(微信setData回调函数开头)

        Tips:setData回调函数开头可认为是页面渲染完成的时间,是因为微信setData定义如下(微信规范) :

        使用uni-app开发小程序,比直接原生开发小程序好在哪里(uni app开发小程序)

        测试方式 :从页面空列表开始 ,通过程序自动触发上拉加载,每次新增20条列表 ,记录单次耗时;固定间隔连续触发 N 次上拉加载 ,使得页面达到 20*N 条列表,计算这 N 次触发上拉到渲染完成的平均耗时 。

        测试结果如下:

        使用uni-app开发小程序,比直接原生开发小程序好在哪里(uni app开发小程序)

        说明 :以400条微博列表为例 ,从页面空列表开始 ,每隔1秒触发一次上拉加载(新增20条微博),记录单次耗时,触发20次后停止(页面达到400条微博),计算这20次的平均耗时,结果微信原生在这20次 触发上拉 -> 渲染完成 的平均耗时为876毫秒,uni-app是741毫秒。

        这个数据,可能违反了很多人的直觉 ,uni-app 的性能竟然比微信原生还好!

        当然,使用微信原生开发,也可以自己单独写代码优化setData。但每处业务都编写太多判断是不现实的,自然是用框架更舒心 。

        这个结果,和web开发类似,web开发也有原生js开发、vue、react框架等情况。如果不做特殊优化,原生js写的网页,性能经常还不如vue 、react框架的性能。

        也恰恰是因为Vue、react框架的优秀 ,性能好,开发体验好 ,所以原生js开发已经逐渐减少使用了。

        3.社区生态

        3.1 周边轮子

        小程序是脱离web自造生态 ,很多web生态中轮子无法使用。

        微信小程序还是有周边生态的,而其他几家小程序平台的生态基本没建起来 。

        uni-app的周边生态非常丰富,在插件市场有近800个插件 ,详见 ext.dcloud.net.cn。

        首先uni-app兼容小程序的生态 ,各种自定义组件均可直接引入使用。在此基础上,uni-app的插件市场,有更多vue组件 ,同时可跨多端使用,并且性能优秀 。

        这使得uni-app的生态成为最丰富的小程序开发生态。

        比如富文本解析、图表等组件,uni-app的插件性能均超过了wxparse 、wx-echart等微信小程序组件。

        如果开发者需要丰富和高性能的组件,更应该使用uni-app ,而不是原生小程序开发 。

        3.2 活跃的QQ/微信群和论坛

        uni-app官方有 70 个开发者QQ/微信交流群(大多2千人群 ,近10万开发者) ,三方群更多。

        问答社区,每天有数百篇帖子。活跃度与微信小程序官方论坛相同 ,远超过其他小程序官方论坛。

        uni-app三方培训活跃,腾讯课堂官方都为uni-app制作了课程,各种培训网站到处可见免费或收费的uni-app培训视频教程。

        4.学习门槛、开发体验

        首先微信原生的开发语法 ,既像React ,又像Vue ,有点不伦不类,对于开发者来说,等于又要学习一套新的语法,大幅提升了学习成本  ,这一直被大家所诟病。

        uni-app则对开发者更为友好,简单来说是 vue的语法 小程序的api。

        它遵循Vue.js语法规范,组件和API遵循微信小程序命名,这些都属于通用技术栈,学习它们是前端必备技能 ,uni-app没有太多额外学习成本。

        有一定 Vue.js 和微信小程序开发经验的开发者可快速上手 uni-app  。

        没学过vue的同学,也不用掌握vue的全部,只需了解vue基础语法、数据绑定、列表渲染 、组件等,其他如路由、loader 、cli、node.js、webpack并不需要学。

        因为HBuilderX工具搭配uni-app可以免终端开发,可视化创建项目 、可视化安装组件和扩展编译器 ,也就是uni-app的学习门槛,比web开发的vue.js还低 。

        开发体验层面,微信原生开发相比uni-app有较大差距 ,主要体现在 :

        • 更为强大的组件化开发能力:vue的组件开发比小程序自定义组件开发的体验要好很多
        • 应用状态管理:uni-app支持vuex
        • 使用 Sass 等 CSS 预处理器
        • 完整的 ES Next 语法支持
        • 自定义构建策略

        开发工具维度 ,差距更大:

        • 微信开发者工具被吐槽无数
        • uni-app的出品公司 ,同时也是HBuilder的出品公司 ,DCloud.io。HBuilder/HBuilderX系列是四大主流前端开发工具(可对比百度指数),其为uni-app做了很多优化,故uni-app的开发效率、易用性非微信原生开发可及 。

        这里可以输出一个结论:如果你需要工程化能力 ,那就直接忘了微信原生开发吧。

        5.未来扩展性

        虽然当前产品仅要求发布到微信小程序 ,但若有一天,老板和外来的一个和尚喝完咖啡 ,转身就要求覆盖阿里 、百度、字节跳动等各家小程序平台,此时程序员该怎么办?

        难道真的每个平台到处搬砖吗  ?

        此时 ,uni-ap的跨端功能将成为程序员的自救神器,基于uni-app开发的小程序,无需修改 ,即可同时发布到多家小程序 ,甚至App 、H5平台。这不是梦想 ,而是现实 。大家可依次扫描如下8个二维码 ,亲自体验最全面的跨平台效果!。

        使用uni-app开发小程序,比直接原生开发小程序好在哪里(uni app开发小程序)

        6.结语

        使用uni-app开发小程序,比直接原生开发小程序好在哪里(uni app开发小程序)

        结论 :只开发微信小程序 ,也应该使用uni-app

        相关新闻

        联系我们
        联系我们
        分享本页
        返回顶部

          XML地图