每种编程语言都有它的内存管理机制,不同设备上可用内存不同,分配给js引擎可用的内存范围也不同。例如运行内存在128mb以下的轻量设备,对应js引擎的可用内存范围为48-64kb。本文也将以此类设备为例进行分析。
当整个页面渲染比较复杂时,js运行内存峰值就可能会超过js引擎分配到的最大可用内存,导致页面无法渲染。
list组件是js ui框架下最基本的容器组件之一,提供了一系列相同宽度的列表项。在应用开发过程中,经常会使用list容器组件来呈现大量的数据。所以,在list组件应用的开发过程中,开发者应充分考虑内存优化问题。
本期,我们将通过list组件开发一个通讯录页面,并采用list+for的方案对整个页面进行优化,达到减小js运行内存的目的。
一、代码实现
如下所示,是一张简单的通讯录页面,包含了姓名、电话及对应图片。下面将通过两种实现方式来对比代码性能。
方法一:直接书写对应的组件页面
使用hml直接撰写整个组件页面的内容,代码如下:
《div class=“container”》 《list class=“list”》 《list-item class=“list-item”》 《image class=“image” src=“/common/1.png”》《/image》 《div class=“info”》 《text class=“text”》张三《/text》 《marquee class=“detail”》电话:+86 130xxxxxxxx《/marquee》 《/div》 《/list-item》 《list-item class=“list-item”》
《image class=“image” src=“/common/1.png”》《/image》 《div class=“info”》 《text class=“text”》李四《/text》 《marquee class=“detail”》电话:027-6128xxxx《/marquee》
《/div》 《/list-item》 《list-item class=“list-item”》 《image class=“image” src=“/common/1.png”》《/image》
《div class=“info”》 《text class=“text”》王五《/text》 《marquee class=“detail”》电话:+86 150xxxxxx《/marquee》 《/div》 《/list-item》 《list-item class=“list-item”》 《image class=“image” src=“/common/1.png”》《/image》 《div class=“info”》
《text class=“text”》小明《/text》 《marquee class=“detail”》电话:+86 130xxxxxxxx《/marquee》
《/div》 《/list-item》 《list-item class=“list-item”》 《image class=“image” src=“/common/2.png”》《/image》 《div class=“info”》 《text class=“text”》小红《/text》
《marquee class=“detail”》电话:+86 180xxxx 《/marquee》 《/div》 《/list-item》 。。. 《/list》 《input value=“非for” on:click=“changenextpage” class=“button”》《/input》《/div》
方法二:通过for指令来书写对应的组件页面
针对方法一中的实现,采用for指令来改进,使对应页面更简洁,对应修改后代码如下:
《div class=“container”》 《list class=“list” on:scrollend=“changenextpage”》 《list-item class=“list-item” for = “{{listdata}}”》 《image class = “image” src = “/common/{{$item.src}}”》《/image》 《div class = “info”》 《text class=“text”》{{$item.name}}《/text》
《marquee class = “detail”》电话: {{$item.phone}}《/marquee》 《/div》 《/list-item》 《/list》《/div》
对应的for指令的渲染数组代码如下:
export default { data: { listdata:[] }, oninit() { for (var i = 0; i 《 10; i++) { this.listdata.push({‘name’:‘张三’, src :‘1.png’, phone:“+86 130xxxxxx”}); this.listdata.push({‘name’:‘李四’, src :‘2.png’, phone:“027-6128xxxx”});
this.listdata.push({‘name’:‘王五’, src :‘1.png’, phone:“+ 86 150xxxxxx”}); this.listdata.push({‘name’:‘小明’, src :‘1.png’, phone:‘+86 130xxxxxx’}); this.listdata.push({‘name’:‘小红’, src :‘2.png’, phone:‘+86 180xxxx’}); } }}
二、性能测试
这里,我们针对不同的item数量,分别测试了以上两种实现方式的js运行性能,js运行内存与js运行内存峰值如下图所示:
图2 两种方法的内存占用
由上表测试数据可以看出,采用方法二进行渲染,js运行内存会出现比较大的浮动。但是使用方法一,对应的js运行内存基本保持不变,这种差异是由两种不同的页面加载渲染机制造成的。
方法一的加载机制:对整个页面一次性全部进行加载,在加载完成后,会对list组件页面占用的js运行内存进行释放。页面后续滑动,并不会触发组件的解析,从而不会影响js运行时内存数据。
方法二的加载机制:每次滑动屏幕会加载当前显示页面以及缓存部分的item,超出屏幕之外的item会对其占用的js内存资源进行回收。当list组件页面下滑到新的item时会重新创建请求,这种情况下会降低一部分的滑动性能,但是可以实现按需加载,降低js运行内存峰值。
三、优缺点对比
方法一的优缺点:
优点:首次页面显示成功后,js运行内存比较稳定,不会出现后续滑动崩溃的问题,且稳定显示后占用的js运行内存较小。
缺点:由于页面会一次性全部进行解析,在解析比较复杂的页面时,会对js运行内存峰值造成比较大的压力,甚至会导致对应的页面无法启动。
方法二的优缺点:
优点:
1. 在页面启动时,只对显示部分进行加载,因此可以降低页面启动时js运行内存。
2. 由于整个页面始终只保持对显示界面的元素进行渲染。因此,针对稍复杂的界面,相较于方法一js运行内存峰值更小。
缺点:
1. list组件的内容,需要通过$item进行访问, item显示时会创建对应的数据监听对象来检测数据的变化,比如上述界面中,一个item会创建3个数据监听,list中进行绘制的item的数量为5,因此会创建15个数据监听,从而增加 15 * 200b(单个字节) = 3000b的数据监听开销。
2. 随着list组件向下滑动,会增加数组监听占用的内存,从而增加对应的js运行内存。因此使用方法二,js运行内存会一直上涨,直到最后一个item渲染。
四、使用建议
针对上述表现,我们总结了如下使用场景供开发者参考:
图3 使用建议
总而言之,采用方法二开发list组件可以降低js运行内存峰值,但是会增加js运行时内存。当页面比较简单,item数量低于20个,建议采用方法一。当页面item超过20个,或者页面占用js内存峰值比较大,建议采用方法二。
黄晓庆:1年内Ophone技术即可超越iPhone
通过嵌入式虚拟化充分利用多核芯片
OPPO陈明永:明年研发投入100亿,将推智能手表等移动终
华为p10终于要开售了,振奋人心呐
接触器为什么要通过小电流控制大电流
如何用List组件减小JS运行内存
米尔科技Rico Board - TI 437X开发板介绍
三安光电LED巨头还能亮多久
TCL发布了搭载展锐芯SC7731E的Alcatel 1C新机
阿里云ET城市大脑发布“天擎”系统
电能管理系统的设计以及实例案例的分析
边缘计算网关是什么?有什么功能?
太阳能LED路灯的主要优点什么?
配套银隆 锦帛方“出击”激光极耳设备
散热处理为高亮度LED灯具设计关键
区块链私链的价值是什么
玉米株高测量仪是什么,它的作用又是什么
传星纪魅族拟调整芯片业务 今年应届生或被全部优化
2018传感新技术之钙钛矿单晶数字图像传感器
继半导体后 韩国将显示专利申请指定为优先审查对象