小程序的免安装、用完即走的功能自发布以来就非常受欢迎,现在依然很受欢迎。小程序虽然是一个软件,但是通过限制开发者的编写方式,提供了一套定制化的组件和编写方式,并且对于一些性能密集型的组件使用客户端渲染,从而大大提高网页的性能。
小程序虽然和网页区别不大,但难免会遇到坑,下面我就说说我最近遇到的一些经典问题的解决办法。
遇到的问题
数据传输长度超出最大长度
在一个新闻推送项目中,用户可以无限下拉加载数据,而内部会使用一个数组来存储列表数据,在我重构项目准备尝试的时候发现,当我加载的数据超过一定量(大概200条数据之后)时,控制台就会报错“输出传输长度超出最大长度”。
滚动问题
我们的小程序有一个下拉刷新的功能,官方小程序本身也有封装好的接口帮我们完成这个任务,但是因为我们的下拉刷新是自定义样式的,所以不能使用官方的接口。
一开始我是使用组件来实现滚动触发下拉事件的,内部是通过操作来实现下拉卡片的展开,操作了一阵子觉得很完美,但是后来突然发现官方的提示:
由于这些组件是使用 实现的,所以只能固定存在于屏幕上,无法在-view中使用,同时使用该组件之后,修改其他外部组件会非常麻烦,每个组件都需要自己维护一套事件,增加了业务的复杂度。
画布问题
另外一个问题就是画布,这个画布最大的问题是小程序是使用客户端组件实现的,但是在开发者工具中,由于是网页预览,所以这里的画布是用HTML来实现一些接口的,但是不得不说还是有很多区别的,所以在开发者工具上看到的效果和客户端实际看到的效果可能完全不一样,这给我们的开发过程带来了无穷的阻碍。
解决方案
和作者一一分析之后,我发现可能是自定义组件的错,因为我的列表元素样式不一样,所以用自定义组件定义了不同样式类型的组件,有些组件有共同的部分,所以我们要把它抽出来,变成一个组件,也就是说我的列表其实是经过多层嵌套的自定义组件循环渲染的,我们猜测是小程序渲染的时候,每个自定义组件传入的数据都会被复制一次,导致我原本150K的数据一瞬间就超出了他们的限制。
最终的解决办法也很简单,由于我的组件大部分都是纯渲染的,所以我在组件内部使用模板来渲染自定义组件,这样的话就不会触发数据的拷贝,我试过了,不行。当然,除了减少数据量,使用自定义模板代替自定义组件来减少数据拷贝层级之外,我们还可以对数据进行分页,以减少一次渲染的数据量。
最后我还是回归到了普通的view监听和事件,通过根据移动的距离来确定下拉百分比的方式实现了这个功能,最终的实现可以说是难度极大,但是这样实现之后又出现了一个问题,在iOS中会有一个阻尼效果,就是你下拉的时候,滚动条会有回弹的效果,导致虽然你下拉了,但是事件却没有得到有效的执行。这个问题目前还没有比较好的解决办法,也有网友提出需要提供禁用页面阻尼效果的参数,但是目前还没有官方的回应。
既然是客户端渲染的画布,小程序的画布有以下几个明显的特点:
还有一个问题是小程序的画布必须要可见才可以绘制成功,也就是说如果你把画布设置为:none然后等它绘制成功再显示的话,是不行的。必须先绘制然后再获取页面中用户不可见区域内的图片内容。