赞
踩
uni小程序项目,页面需要展示多个echarts图表, 并且支持数据切换。性能稍差的手机多次切换数据维度后,图表渲染不出来,控制台不报错。
(图表使用uni-app 的renderjs 渲染模式)
切换几次数据维度后,数据渲染不出来。猜测因为同时渲染过多图表导致卡顿出错,所以使用setTimeout 设置一定的事件间隔,降低峰值性能消耗。
添加分页展示能直接减少当前页同时渲染的图表数量,降低性能消耗。(此方法产品pass,不做考虑)
使用虚拟列表方案,只渲染当前视窗内的图表。
let barList = []
barList.forEach((item, index) => {
setTimeout(() => {
// 渲染图表
setBarData(item)
}, 200 * index)
})
在iphone 6、iphone6s plus 手机上测试,多次切换数据维度,最终70个图表只能渲染50个,剩余的全是空白。
首先格式化数据结构如下
pages = [
{
page: 1,
chartsShow: true,
pageData: [] // 内含n条数据
}
]
调整dom结构
<view class="page" v-for="(item,index) in pages" :id="'list'+index">
<view class='item' v-for="(items,indexs) in item.pageData">
<mycharts v-if="item.chartsShow"></mycharts>
</view>
</view>
每20个分一页,根据滚动的高度和每页高度计算出当前需要渲染的页码,更改chartsShow为true,触发chartsShow 为true 的页面数据图表渲染
在iphone 6、iphone6s plus 手机上测试,多次切换数据维度后依然回出现图表渲染空白的问题。
查阅资料发现一个信息,ios设备的 “canvas 最大内存限制”。大意是 chrome、Firefox、Safari 等浏览器对 canvas 的总内存占用限制、单个 canvas 的限制(如 width、height、像素密度)不尽相同。在大量使用 canvas 时没有注意及时回收,导致了他在 chrome 测试没问题的代码,Firefox 中完全没有反应,在 Safari 中报错。
重新去echarts 官网生成echarts.js 文件,在其它选项内勾选SVG渲染,替换现有的echarts.js,
echarts 替换为svg渲染模式后在苹果设备上测试结果:图表渲染个数能达到200+
但是在频繁切换数据维度后,手机出现明显卡顿现象。
首次渲染测试没问题,但是频繁切换数据维度后,手机卡顿,怀疑图表占用的内存没有被释放掉。
使用xcode的内存监测工具,通过频繁切换数据维度,观察内存使用情况,发现当内存占用曲线突然上升以后,手机卡顿,图表渲染异常;更证实了之前的分析
既然确定是内存未被正确释放,那么就手动清除(html/js)占用的内存。
let myChart = {}
disposeCharts (id) {
myChart[id].dispose();//销毁实例,重新渲染
delete myChart[id];//删除数据
let dom = document.getElementById(id);//图表dom
if(dom){
dom.innerHTML = '';
}
}
renderjs是一个运行在视图层的js。它比WXS更加强大。它只支持app-vue和h5。
renderjs的主要作用有2个:
1、大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力
2、在视图层操作dom,运行for web的js库
1、就像官方描述的,在某些特定需求/页面上,页面性能较于普通写法会有大幅提升。
1、renderjs 写法的文档不全面、开发效率低下,只适合特定业务场景。
2、renderjs 操作dom元素不能及时释放数据变量的内存(多个社区bug,官方未确认)。
虽然js 有自己的垃圾回收机制,但也要在写代码的时候一定要留意高发场景,尽可能在写代码的时候就避免潜在的内存泄漏。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。