uni-app2.2的发布,大幅优化了H5性能体验。uni-app自发布以来,已服务数十万开发者。出乎我们的意料,或者意外的是,有大量的开发者使用uni-app只写H5版本,不在多端发布(参考案例)。这其实很符合uni-app的初衷。uni-app的定位是在需要多设备发布的时候不要使用uni-app。uni-app是一个使用vue.js开发所有前端应用的统一框架。对于一个前端工程师来说,用uni-app做多端效率更高,做单端也没问题,而且每一端都有很多亮点。在过去的版本迭代中,uni-app已经成为了一个比较好的小程序开发框架,相比使用微信原生开发有更多的优势。(查看评论)在新版本的uni-app2.2中,我们对H5版本的性能进行了极大的优化,使得使用uni-app开发的H5的性能体验可以媲美直接使用vue.js开发的H5.很多开发者可能会有这样一种误解:多端框架一定要适配多端,所以性能肯定不如原生的。我们想纠正一下:不要想当然,多看数据评估。如果您仍然不相信我,请自己尝试一下。请问是用vue.js开发的web性能好,还是用原生js开发的web性能好?答案是:使用vue.js框架。为什么?因为它在底层自动优化了数据同步和虚拟dom,比大多数开发者手动编写的代码效率更高。使用uni-app也是如此。框架底层的优化处理,比大多数开发者手动编写setdata或dom操作更高效。很多多端的适配都是在编译期做的,不影响运行时的性能优化难点。优化H5端的性能并不是一件容易的事。“功能全面”与“小巧极速”,这是最难调和的一对冤家。为了保证多端的一致性,uni-app实现了一套小程序H5版本Runtime,支持各种小程序组件、API、配置。所以H5版本的uni-app比其他框架的跨终端一致性更好。但是这也造成了老版本的uni-app,输出H5端时,包体积过大(框架没压缩前500k,部署gzip后162k)。这确实是一个非常庞大的运行时,包括几十个内置组件和数百个API。而且这些API仍在快速增长。它不能像其他框架那样因为功能少而体积小。我们不会为了性能而牺牲功能,我们需要更好的解决方案。优化方法uni-app包含数十个内置组件和数百个API。它是一个“大而全”的框架;但是,开发人员在开发特定应用程序时可能无法使用所有组件和API。如果能根据项目的具体情况删除不用的组件和API,保留对项目有用的组件和API,就可以简化框架,减少体积。这就是“tree-shakingoptimization”的思想。Tree-Shaking,顾名思义就是摇树干,抖掉枯死无用的树枝,只保留有用的树枝。对应到框架层面的理解,就是一个框架的很多组件和API都可以按需使用,没有引用的框架部分被切掉。Tree-Shaking最早由Rollup提出,是一种死代码删除的形式。常见的tree-shaking前端框架一般都是基于明确的导入引用关系。比如在引用某个UI库时,使用了A页面UI库的搜索组件,这时候就需要写js代码导入搜索组件,那么tree-shaking分析就非常容易了。不过uni-app和applets是一样的。内置组件和API不需要导入,提高了开发的便利性,但此时增加了tree-shaking的难度。简单的导入分析无法实现tree-shaking。.幸运的是,对于DCloud团队来说,AST语法分析是一项看家技能。多年来,HBuilder一直以js和vue语法提示着称。通过AST分析,新版uni-app可以准确判断本项目使用了哪些组件和API。但这还不够。在分析了项目源码中使用了哪些组件和API之后,需要考虑框架的组件和API之间可能存在依赖和耦合关系,需要进一步计算和关系排序。具体:组件:通过vue-template-compiler解析AST,映射生成项目中使用的组件列表,然后将使用到的组件打包构建基于Webpack插件的API:编译器维护一个json文件apidependencies,描述了每个api可能依赖的文件,然后babel找到对应的api,根据api的依赖自动导入重新编译。经过工程师们不断的加班加点,uni-app终于推出了新的2.2版本,解决了这些问题,大大减少了发布包的大小。gzip后框架的大小从162k减少到92k,只相当于你项目中vue.js、vue-router和一些es6polyfill库的引用。(后面会有详细对比)新版本除了大大减小了发布包的体积,还调整了预加载策略,可以进一步加快页面的渲染速度。优化结果搭建环境我们使用vue-cli创建uni-app默认模板vuecreate-pdcloudio/uni-preset-vuemy-project项目创建完成后在H5端npm编译生成release目录运行build:h5然后配置nginx服务器,指定根目录并启用gzip压缩,示例如下:server{...gzipon;gzip_min_length1k;gzip_buffers416k;gzip_comp_level4;gzip_types文本/普通应用程序/javascript应用程序/x-javascript文本/css应用程序/xml文本/javascript应用程序/x-httpd-php图像/jpeg图像/gif图像/png;...}运行时动态裁剪然后通过ChromeDevTools的Network面板,查看优化前首页的网络请求包大小,结果如下:然后启用H5平台Switch的优化,查看网络请求包再次查看首页大小,结果如下:可以看到框架主库(chunk-vendors.js)从162k变成了92.8k,体积缩小了43%!框架主库其实主要分为三部分:vue/vue-router基础库es6polyfill库uni-app运行时(组件&API实现)如果我们将这三部分拆解对比,就会看到uni-app的组件库优化比例更高:vue/vue-routeres6polyfill库uni-app运行时累计优化前38k43k81k162k优化后38k26k28.8k92.8k使用es6也动态扫描过。项目中使用的es6语法(包括uni-appruntime使用的es6语法)会封装对应的polyfill实现,所以es6polyfill库的脚本执行时间从43k减少到26k然后,我们查看之前和之前的性能通过ChromeDevTools的Performance面板优化后对比结果如下:可以看出,最耗时脚本的执行时间从227ms增加到154ms,时间增加了32%。开发者只需要在配置文件中打开一个开关即可。具体在manifest.json中h5节点配置如下选项:"h5":{"optimization":{"treeShaking":{"enable":true//启用treeshaking优化}}}2.2版本的其他优化有在uni-app2.2版本中,也开放了package.json和vue-config.js的自定义,开发者可以自由配置编译策略。现在您可以自定义支持所有小程序平台,包括钉钉小程序、高德小程序、抖音小程序...等。这样,除了标准的8大平台(iOS、Android、H5、微信小程序、支付宝小程序、百度小程序、今日头条小程序、QQ小程序)之外,这些生态子生态也可以有条件地编译按版本。同样,它也支持H5终端的多终端编译。比如微信内嵌的H5,app内嵌的H5……都可以单独编译。这种灵活的条件编译,对于一组项目的多端发布、共享复用、同步升级大有裨益。即使只开发H5版本,uni-app的多端条件编译也提供了更灵活、更强大的工程能力。2.2版本还可以为各种静态资源、js、小程序自定义组件设置编译复制策略。如果你想把你之前的h5项目或者小程序项目转成uni-app,不想移动一些目录结构,可以在vue-config.js中配置策略。使用uni-app开发H5相比直接开发H5的优势在直接开发H5的性能基础上,uni-app为开发者提供了更多的优势:开发效率uni-app提供海量适合手机端的页面基本组件(实际上是applet组件)。还提供了扩展组件uniui。插件市场上有600多个插件。无论开发者是在寻找电子商务模板还是图表组件,它们都是可用的。比以往任何时候都更有效地开发。多端编译我们在开发H5的时候,经常需要给浏览器输出一份,给微信等超级应用输出一份,给自己的APP输出一份。甚至不同的地域、不同的用户画像,也会输出不同的版本。以前开发者只能有条件地编译js部分,甚至需要搭建多个仓库进行多版本维护。uni-app解决了这些烦恼。它的条件编译非常灵活强大:无论是组件,js还是css,都可以根据平台进行编译输出,可以在多个平台进行“与与或”运算。除了文件中的代码,整个文件,甚至整个目录,都可以进行条件编译。比如微信、QQ等,在内置支持x5内核的浏览器中,使用x5视频同层渲染;或者在微信服务号调用微信卡券,这段代码只有builddist/h5-weixin目录下的版本才会编译进去,其他平台不会有这段代码//#ifdefH5-WEIXINwx.openCard({car??dList:[{car??dId:'',code:''}]//需要开通的优惠券列表});//#endif后续计划接下来uni-app会提供服务端渲染机制(SSR)和H5端PC宽屏界面适配优化,在追求极致性能和大合一的道路上继续前行!所有相关代码都托管在github上,欢迎star或提交pr!
