最近在基于 Taro.js 开发微信小程序。由于小程序与 web 存在很大差异,踩了很多坑。
小程序实质就是 hybrid,但是是受限的。js 运行在逻辑层,是一个没有 html 的单纯的 js 解释器,只能通过 API 和视图层、Native 层交互。逻辑层和视图层是两个独立的线程,完全隔离。
对于平台方而言,这种设计极大增加了平台对应用的控制,也减少了各种风险。但是对于开发者而言,很多 h5 的能力在小程序中被阉割甚至不被提供,开发小程序相当于戴着镣铐跳舞。
小程序的性能可以类比 React Native,每次交互都需要通过 native 的 bridge 进行,差于 native 和 h5。
实现一个抽屉浮层,
状态1:高度为屏幕高度的一半
状态2:占满屏幕
状态3:关闭
通过拖动在三个状态之间切换
touch 方案
scroll 方案
微信小程序 wxs 响应事件 https://developers.weixin.qq.com/miniprogram/dev/framework/view/interactive-animation.html
小程序 Swiper 组件方案
现象:首页在页面跳转后返回,多出返回按钮
原因:页面跳转时进行了 setState 导致 re-render,然后组件获取到跳转后的路由信息进行渲染
解决:对按钮状态使用 useMemo,使用第一次 render 时的缓存
webview 无效:客户端 6.7.2 版本开始,navigationStyle: custom 对 web-view 组件无效(详见https://developers.weixin.qq.com/miniprogram/dev/component/web-view.html)
该问题类似于 web 的 SPA 应用,在从当前页面 A 返回到上一页面后,A 页面的异步工作仍然会运行。
区别于在 web react 环境下第一次 useEffect 能获取到 dom 节点,在第一次 useEffect/useDidShow中,小程序的页面 dom 节点尚未挂载,获取不到。
onLoad -> onShow -> useEffect -> onReady
路由跳转后,异步的 SelectorQuery.exec 等方法的回调不会执行,比如 react 生命周期/定时器/Promise等情况
例子如下
Taro.navigateTo({
url: '/',
});
setTimeOut(() => {
const query = Taro.createSelectorQuery();
query
.select('#a')
.fields({ node: true })
.exec((res) => {
console.log(res[0].node);
});
}, 0);
因为 webpack 打包时,遇到 require('crypto'),会引入对应的 polyfill ,导致包 size 大大增加
开发小程序时,打包的 size 很大,分析发现是打包了很多 polyfill,如 bn.js。
追踪依赖链,bn.js -> browserify-sign -> crypto-browserify -> node-libs-browser,node-libs-browser 包提供了某些 Node 库供浏览器使用,可能是 crypto 的浏览器环境的 polyfill。
全局搜索,发现使用的公司的图片上传组件中使用了 require('crypto'),并且实质上与 crypto 相关的方法并没有实际调用。
移除 require('crypto') 后,size 减少了 600 KB。
在使用 InnerAudioContext 播放音频时,当进行调整播放进度(seek)/重新播放等操作后,onTimeUpdate 不会触发。
音频加载导致 onUpdateTime 失效(比如调用 seek 的时候,触发了音频自动加载)
audioManager.onCanplay(() => {
audioManager.paused;
});
InnerAudioContext 与 BackgroundAudioManager 的区别:
在微信中,对于 canvas 的支持存在很多问题,目前已知的问题有:
给定了一张原图和四边形坐标,裁剪出四边形所框选出的区域作为独立的图片。
最开始的做法是通过小程序的 Canvas 实现,但是微信小程序对于 Canvas 的支持存在问题,因此采用一种折中的方案完成。
这种方案有两个需要注意的点:
点击阅读原文,了解更多技术干货~