|
|
|
|
公众号矩阵

JS UI框架下,List组件运行时的内存优化

List组件是JS UI框架下最基本的容器组件之一,提供了一系列相同宽度的列表项。在应用开发过程中,经常会使用List容器组件来呈现大量的数据。

作者:tongshijia 来源:鸿蒙社区|2021-10-14 09:53

想了解更多内容,请访问:

51CTO和华为官方战略合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

每种编程语言都有它的内存管理机制,不同设备上可用内存不同,分配给JS引擎可用的内存范围也不同。例如运行内存在128MB以下的轻量设备,对应JS引擎的可用内存范围为48 64KB。本文也将以此类设备为例进行分析。

当整个页面渲染比较复杂时,JS运行内存峰值就可能会超过JS引擎分配到的最大可用内存,导致页面无法渲染。

List组件是JS UI框架下最基本的容器组件之一,提供了一系列相同宽度的列表项。在应用开发过程中,经常会使用List容器组件来呈现大量的数据。所以,在List组件应用的开发过程中,开发者应充分考虑内存优化问题。

本期,我们将通过List组件开发一个通讯录页面,并采用list+for的方案对整个页面进行优化,达到减小JS运行内存的目的。

一、代码实现

如下所示,是一张简单的通讯录页面,包含了姓名、电话及对应图片。下面将通过两种实现方式来对比代码性能。

JS UI框架下,List组件运行时的内存优化-鸿蒙HarmonyOS技术社区

图1 简单的通讯录页面

方法一:直接书写对应的组件页面

使用HML直接撰写整个组件页面的内容,代码如下:

  1. <div class="container"
  2.     <list class="list"
  3.         <list-item class="list-item"
  4.             <image class="image" src="/common/1.png"></image> 
  5.             <div class="info"
  6.                 <text class="text">张三</text> 
  7.                 <marquee class="detail">电话:+86 130XXXXXXXX</marquee> 
  8.             </div> 
  9.         </list-item> 
  10.         <list-item class="list-item"
  11.             <image class="image" src="/common/1.png"></image> 
  12.             <div class="info"
  13.                 <text class="text">李四</text> 
  14.                 <marquee class="detail">电话:027-6128XXXX</marquee> 
  15.             </div> 
  16.         </list-item> 
  17.         <list-item class="list-item"
  18.             <image class="image" src="/common/1.png"></image> 
  19.             <div class="info"
  20.                 <text class="text">王五</text> 
  21.                 <marquee class="detail">电话:+86 150xxxxxx</marquee> 
  22.             </div> 
  23.         </list-item> 
  24.         <list-item class="list-item"
  25.             <image class="image" src="/common/1.png"></image> 
  26.             <div class="info"
  27.                 <text class="text">小明</text> 
  28.                 <marquee class="detail">电话:+86 130XXXXXXXX</marquee> 
  29.             </div> 
  30.         </list-item> 
  31.         <list-item class="list-item"
  32.             <image class="image" src="/common/2.png"></image> 
  33.             <div class="info"
  34.                 <text class="text">小红</text> 
  35.                 <marquee class="detail">电话:+86 180XXXX </marquee> 
  36.             </div> 
  37.         </list-item> 
  38.         ... 
  39.     </list> 
  40.     <input value="非for" on:click="changeNextPage" class="button"></input> 
  41. </div> 

方法二:通过for指令来书写对应的组件页面

针对方法一中的实现,采用for指令来改进,使对应页面更简洁,对应修改后代码如下:

  1. <div class="container"
  2.     <list class="list" on:scrollend="changeNextPage"
  3.         <list-item class="list-item" for = "{{listData}}"
  4.             <image class = "image" src = "/common/{{$item.src}}"></image> 
  5.             <div class = "info"
  6.                 <text class="text">{{$item.name}}</text> 
  7.                 <marquee class = "detail">电话: {{$item.phone}}</marquee> 
  8.             </div> 
  9.         </list-item> 
  10.     </list> 
  11. </div> 

对应的for指令的渲染数组代码如下:

  1. export default { 
  2.     data: { 
  3.         listData:[] 
  4.     }, 
  5.     onInit() { 
  6.         for (var i = 0; i < 10; i++) { 
  7.             this.listData.push({'name':'张三', src :'1.png', phone:"+86 130XXXXXX"}); 
  8.             this.listData.push({'name':'李四', src :'2.png', phone:"027-6128XXXX"}); 
  9.             this.listData.push({'name':'王五', src :'1.png', phone:"+ 86 150XXXXXX"}); 
  10.             this.listData.push({'name':'小明', src :'1.png', phone:'+86 130XXXXXX'}); 
  11.             this.listData.push({'name':'小红', src :'2.png', phone:'+86 180XXXX'}); 
  12.         } 
  13.     } 

二、性能测试

这里,我们针对不同的item数量,分别测试了以上两种实现方式的JS运行性能,JS运行内存与JS运行内存峰值如下图所示:

JS UI框架下,List组件运行时的内存优化-鸿蒙HarmonyOS技术社区

图2 两种方法的内存占用

由上表测试数据可以看出,采用方法二进行渲染,JS运行内存会出现比较大的浮动。但是使用方法一,对应的JS运行内存基本保持不变,这种差异是由两种不同的页面加载渲染机制造成的。

方法一的加载机制: 对整个页面一次性全部进行加载,在加载完成后,会对List组件页面占用的JS运行内存进行释放。页面后续滑动,并不会触发组件的解析,从而不会影响JS运行时内存数据。

方法二的加载机制: 每次滑动屏幕会加载当前显示页面以及缓存部分的item,超出屏幕之外的item会对其占用的JS内存资源进行回收。当List组件页面下滑到新的item时会重新创建请求,这种情况下会降低一部分的滑动性能,但是可以实现按需加载,降低JS运行内存峰值。

三、优缺点对比

方法一的优缺点:

优点:

首次页面显示成功后,JS运行内存比较稳定,不会出现后续滑动崩溃的问题,且稳定显示后占用的JS运行内存较小。

缺点:

由于页面会一次性全部进行解析,在解析比较复杂的页面时,会对JS运行内存峰值造成比较大的压力,甚至会导致对应的页面无法启动。

方法二的优缺点:

优点:

在页面启动时,只对显示部分进行加载,因此可以降低页面启动时JS运行内存。

由于整个页面始终只保持对显示界面的元素进行渲染。因此,针对稍复杂的界面,相较于方法一JS运行内存峰值更小。

缺点:

List组件的内容,需要通过$item进行访问, item显示时会创建对应的数据监听对象来检测数据的变化,比如上述界面中,一个item会创建3个数据监听,list中进行绘制的item的数量为5,因此会创建15个数据监听,从而增加 15 * 200B(单个字节) = 3000B的数据监听开销。

随着list组件向下滑动,会增加数组监听占用的内存,从而增加对应的JS运行内存。因此使用方法二,JS运行内存会一直上涨,直到最后一个item渲染。

四、使用建议

针对上述表现,我们总结了如下使用场景供开发者参考:

图3 使用建议

总而言之,采用方法二开发List组件可以降低JS运行内存峰值,但是会增加JS运行时内存。当页面比较简单,item数量低于20个,建议采用方法一。当页面item超过20个,或者页面占用JS内存峰值比较大,建议采用方法二。

想了解更多内容,请访问:

51CTO和华为官方战略合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

【编辑推荐】

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区
  2. 《基于Python鸿蒙开发板外设控制》直播图文及答疑
  3. HarmonyOS实战—TextField文本输入框组件基本使用
  4. 鸿蒙开源全场景应用开发—通讯协议
  5. 鸿蒙应用开发:如何与组件库(Glide)衔接?
  6. 【鸿蒙应用开发】【HCIA认证】模拟题每日1练(第50题)
【责任编辑:jianghua TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微