写这篇文章的缘由: 最近在公司的小程序项目中遇到了页面图片元素过多导致的性能问题. 从小程序提供的性能检测面板分析, 确定是图片元素占用了过多内存导致.
因为本人之前主要是做桌面端应用开发和原生app开发, 没有太顾及过移动端图片的内存占用问题. 这次既然遇到了, 也就趁这个机会学习一下其优化的技巧.
什么造成的性能问题
简单的来说: DOM节点过多 && 图片节点过多
DOM节点过多会造成更多的内存占用. 按照目前的微信小程序限制, 内存占用500M以上会出现卡顿, 甚至闪退. 如果列表中节点没有图片标签, 内存占用现象还不会太明显, 只是DOM节点过多会造成页面渲染耗时增加. 但当列表节点中含有图片时, 内存占用会迅速攀升.
上图中可以看到, 该页面为很多的卡片组成的列表页面. 假设一个卡片的DOM子节点数为 30, 那么当列表元素加载到1000时, 页面会有 30 * 1000 = 30,000
个DOM节点. 小程序显然是吃不消的 (注: 微信小程序推荐总节点数不超过: 1000)
那我们该如何处理来减少节点数呢"htmlcode">
Page({ showCards: [], totalCards: [] })
接下来我们来写页面布局部分:
<view wx:for="{{showCards}}" wx:key="{{index}}"> <self-define-component data-card-data="{{item}}"> </self-define-component> </view>
简单的代码框架就是这样 (这里省略了很多不影响理解思路的代码细节)
我们先实现没有优化DOM节点的代码逻辑. 在页面滑动到最底部时, 向showCards
push进新的卡片, 并通过 setData
更新页面. 这样就实现了一个简单的下拉无限加载的列表页面.
async onReachBottom() { const newCards = await fetchNewCards(); this.data.showCards.push(newCards); this.setData({ showCards: this.data.showCards }) },
接下来我们实现优化DOM节点的代码逻辑. 我们会再用户滑动页面(onScroll
事件) 时, 对当前页面每个card
的位置进行判断, 如果该 card在用户可见范围内的上下两屏内, 则展示真实数据, 否则将其替换为宽高与原卡片一致的空白占位节点.
在 Page 的 onPageScroll
回调中, 我们进行回收函数的调用 (注意这里回调时要进行节流处理, 否则频繁调用会导致页面闪动) . 让我们看看这个回收页面节点函数的主要逻辑:
回调中, 我们首先通过小程序提供的获取页面元素位置的api: createSelectorQuery().boundingClientRect
来拿到每个卡片的位置信息.
接下来, 我们通过位置信息, 判断是否展示card的真实数据. 对于不展示真实数据的card, 我们需要保存其高度信息, 以便在渲染页面时使用高度信息填充页面. 同时我们给空card一个 type 属性, 方便我们在 wxml中渲染时判断卡片类型.
async onScrollCallback() { try { const rectList = await this.calcCardsHeight(); this.recycleCard(rectList); } catch (e) { console.error(e); } } calcFeedHeight() { return new Promise((resolve, reject) => { this.createSelectorQuery() .selectAll(`.card`) .boundingClientRect(rectList => { resolve(rectList); }) .exec() }) }, recycleCard(rectList) { const newShowCards = []; for (let i = 0; i < this.data.showCards.length; i++) { const rect = rectList[i]; if (rect && Math.abs(rectList[i].top - 0) > pageHeight * 2) { newShowCards.push({ type: 'empty-card', height: rectList[i].bottom - rectList[i].top }); } else { const feed = totalCards[i]; newShowCards.push(feed); } } this.setData({ showCards: newShowCards }); }
接下来, 我们要对wxml布局文件进行相应的修改:
<view wx:for="{{showCards}}" wx:key="{{index}}"> <view wx:if="{{item.type === 'empty-card'}}" class="card empty-card" style="height: {{item.height}}px"> </view> <self-define-component wx:if="{{item.type !== 'empty-card'}}" data-card-data="{{item}}" class="card read-card"> </self-define-component> </view>
这样, 我们就解决了 DOM节点数目过多的问题. 并且最大限度的不影响用户的体验. (虽然用户快速上下滑动时还是会看到一些空白, 但大多数情况用户不会非常快速的上下滑, 而是阅读内容并慢速滑动)
2. 图片节点过多
通过上面一步的优化, 我们其实已经大幅减少了页面加载的图片数目. 但是有些情况, 我们的列表中的每一个卡片并不是只有一张图, 有时我们的图片组件是一个 swiper. 我们假设每个swiper平均展示10张图片, 那么我们展示5张card的话,<Image/>
节点就有 50 个. 对于一些低端的安卓机, 这样的开销依然会造成卡顿.
那有什么好的优化方案呢"text-align: center">
我们使用一个变量记录当前swiper控件展示图片的坐标: curIndex
, 然后我们改造一下 wxml布局文件. 代码逻辑很简单, 就是通过判断当前Image 节点的index和swiper展示节点的 index之间距离, 大于2就不显示.
经过这样的处理后, 我们的每个swiper组件, 最多只会有三个占用实际内存的 <Image/>
节点.
<swiper-item wx:for="{{images}}" wx:key="{{index}}"> <view > <image class="img" mode="widthFix" src="/UploadFiles/2021-04-02/{{index - curIndex < 2 && index - curIndex > -2 ">最后
以上就是我在这次性能优化中用到的一些小技巧, 希望能为你带来一些帮助 :)
如果你对我的文章感兴趣, 这里有我的一些 数据可视化, D3.js 方面的文章, 欢迎 fork && star:
https://github.com/ssthouse/ssthouse-blog
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]