背景
这其实也符合 过去的版本迭代中, 在 可能不少开发者有某种误解:多端框架要适配多端,所以性能肯定不如原生。我们想纠正一下:
优化难点想优化H5端的性能,并不是一件容易的事。 “功能全面”和“小巧极速”,这是一对最难调和的冤家。 为了保障多端的一致性, 但这也造成了老版的 这确实是一个非常大的runtime,包含了几十个内置组件,数百个API。而且这些API仍然在快速增加中。 不能像其他框架一样因为功能少,所以体积小。我们不会用功能换性能,我们需要更好的方案。 优化方法
摇树优化(Tree-Shaking),顾名思义,摇晃树干,将枯死无用的枝条摇掉,仅保留有用的树枝。对应到框架层面理解,就是一个框架的众多组件和API,可以按需使用,把未引用的框架部分裁剪掉。Tree-Shaking 最早由 Rollup 提出,属于死码删除的一种形式。 常见的前端框架摇树,一般是基于明确的 但 幸好对DCloud团队而言,AST语法分析是看家本事,多年来HBuilder以js和vue语法提示著称。通过AST分析, 不过这还不够,分析工程源码使用了什么组件和API之后,还得考虑框架各组件和API之间可能存在依赖和耦合关系,这需要进一步的计算和关系梳理,具体而言:
在工程师持续的加班奋战后, 除了大幅降低发行包体积,新版还调整了预载策略,可以进一步加快页面的渲染速度。 优化结果搭建环境我们使用 vue create -p dcloudio/uni-preset-vue my-project 项目创建后,编译生成H5端的发行目录 npm run build:h5 然后配置 server { ... gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_comp_level 4; gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; ... } runtime 动态裁剪然后通过 Chrome DevTools 的 Network 面板,查看优化前的首页网络请求包大小,结果如下: 然后启用H5平台的优化开关,重新查看首页的网络请求包大小,结果如下: 可以看到框架主库(chunk-vendors.js)从162k变为92.8k,体积压缩43%! 实际上,框架主库主要分为三个部分:
如果对这三个部分再拆开对比,我们会看到uni-app组件库优化比例更高: | |vue/vue-router |es6 polyfill库 |uni-app runtime|累计 | |-- |-- |-- |-- |-- | |优化前 |38k |43k |81k |162k | |优化后 |38k |26k |28.8k |92.8k | Tips:
脚本执行时间然后,我们再通过Chrome DevTools 的 Performance 面板,查看优化前后的性能数据,对比结果如下: 可以看出,最耗时的脚本执行时间,从227ms提升为154ms,时间提升达到32%。 如何使用虽然内部实现比较复杂,但 "h5" : { "optimization":{ "treeShaking":{ "enable":true //启用摇树优化 } } } 2.2版的其他优化在 现在可以自定义支持所有小程序平台,包括钉钉小程序、高德小程序、抖音小程序...等。这样除了标准的8大平台(iOS、Android、H5、微信小程序、支付宝小程序、百度小程序、头条小程序、QQ小程序),这些生态的子生态也可以分版本条件编译。 同样,也支持对H5端进行多子端编译,比如微信里的内嵌的H5、App里内嵌的H5...都可以分开条件编译。 如此灵活的条件编译,对于一套工程的多端发布、共享复用、同步升级,有莫大的好处。即便是仅开发H5版, 2.2版本还可以设置各种静态资源、js、小程序自定义组件的编译和拷贝策略。如果你之前的h5项目或小程序项目想转换至uni-app下,又不想挪动某些目录结构,那么在vue-config.js里配置策略即可。 使用uni-app开发H5和直接开发H5相比的优势在与直接开发h5拉齐性能的基础之上,
无论开发者想找一个电商的模板,还是找一个图表组件,都可以手到擒来。开发效率更胜以往。
uni-app解决了这些烦恼,它的条件编译非常灵活强大:
例如微信、QQ等在支持x5内核的内置浏览器中,使用x5的视频同层渲染;或者在微信服务号中调用微信卡劵,这段代码只有build到 dist/h5-weixin 这个目录下的版本才会被编译进去,其他平台不会有这段代码 // #ifdef H5-WEIXIN wx.openCard({ cardList: [{ cardId: '', code: '' }]// 需要打开的卡券列表 }); // #endif 后续计划接下来, |