首页 > 其他分享 >长列表加载性能优化

长列表加载性能优化

时间:2024-09-22 17:20:52浏览次数:3  
标签:缓存 复用 列表 组件 屏幕 优化 加载

一、长列表优化概述

        列表是应用开发中最常见的一类开发场景,它可以将杂乱的信息整理成有规律、易于理解和操作的形式,便于用户查找和获取所需要的信息。应用程序中常见的列表场景有新闻列表、购物车列表、各类排行榜等。随着信息数据的累积,特别是一些新闻应用、购物应用、聊天应用,列表数据往往会达到上万条,针对这类大量数据加载的长列表应用,如何对长列表的性能进行优化是非常重要的。一个正确、高性能的长列表应用能明显降低列表渲染时间、提升页面的滑动帧率、降低应用内存占用,大幅提升用户体验。

二、优化手段

        1、懒加载

        提供列表数据按需加载能力,解决一次性加载长列表数据耗时长、占用过多资源的问题,可以提升页面响应速度。 

        (1)ForEach

        ForEach循环渲染的过程如下:

        a、从列表数据源一次性加载全量数据

        b、为列表数据的每一个元素都创建对应的组件,并全部挂载在组件树上。即,ForEach遍历多少个列表元素,就创建多少个ListItem组件节点并依次挂载在List组件树根节点上

        c、列表内容显示时,只渲染屏幕可视区内的ListItem组件,可视区外的ListItem组件滑动进入屏幕内时,因为已经完成了数据加载和组件创建挂载,直接渲染即可

        

        如果列表数据较少,数据一次性全量加载不是性能瓶颈时,可以直接使用ForEach;但是当数据量大、组件结构复杂的情况下ForEach会出现性能瓶颈。这是因为要一次性加载所有的列表数据,创建所有组件节点并完成组件树的构建,在数据量大时会非常耗时,从而导致页面启动时间过长。另外,屏幕可视区外的组件虽然不会显示在屏幕上,但是仍然会占用内存。在系统处于高负载的情况下,更容易出现性能问题,极限情况下甚至会导致应用异常退出。

        (2)LazyForEach 

        LazyForEach懒加载的原理和渲染过程如下:

        a、LazyForEach会根据屏幕可视区能够容纳显示的组件数量按需加载数据

        b、根据加载的数据量创建组件,挂载在组件树上,构建出一棵短小的组件树。即,屏幕可以展示多少列表项组件,就按需创建多少个ListItem组件节点挂载在List组件树根节点上

        c、 屏幕可视区只展示部分组件。当可视区外的组件需要在屏幕内显示时,需要从头完成数据加载、组件创建、挂载组件树这一过程,直至渲染到屏幕上

        

        LazyForEach实现了按需加载,针对列表数据量大、列表组件复杂的场景,减少了页面首次启动时一次性加载数据的时间消耗,减少了内存峰值。不过在长列表滑动的过程中,因为需要根据用户的滑动行为不断地加载新的内容,这需要进行额外的数据请求和处理,会增加滑动时的计算量,从而对性能产生一定的影响。然而,合理使用LazyForEach的按需加载能力,通过在滑动停止或达到某个阈值时才进行加载,可以减少不必要的计算和请求,从而提高性能,给用户带来更好的体验。总之,在实现按需加载的场景中,需要综合考虑性能和用户体验的平衡,合理地优化加载逻辑和渲染方式,以提升整体的性能表现。

        2、缓存列表项

        提供屏幕可视区域外列表项长度的自定义调节能力,配合懒加载设置可缓存列表项参数,通过预加载数据提升列表滑动体验。

        LazyForEach懒加载可以通过设置cachedCount来指定缓存数量,在设置cachedCount后,除屏幕内显示的ListItem组件外,还会预先将屏幕可视区外指定数量的列表项数据缓存。这样当一个屏幕数据加载完成后,再次向下滑动时,会先加载上一次请求的数据,加载完成后,再加载本次请求的数据。LazyForEach添加了cachedCount缓存列表项后,其渲染过程如下:

        a、首先,请求n+cachedCount条数据,并在屏幕上显示n条数据

        b、当列表滑动,缓存列表项需要从屏幕可视区外进入可视区内时,此时只用渲染组件即可,相比不设置cachedCount提升了显示效率

        c、当列表不断滑动,屏幕可视区外缓存的列表项数量少于cachedCount设置数量时,会触发列表项数据加载事件,继续预加载下一组缓存列表项(cachedCount个)

        d、当上滑下滑间隔进行时,列表两个方向分别缓存cachedCount条数据

        e、如果不显式设置cachedCount,cachedCount默认为1

        

        缓存列表项适合加载列表项数据请求比较耗时的场景。比如,滑动列表中含有短视频、高清图片等数据量比较大的资源,可以通过预先从网络加载并缓存相关数据,缩短渲染前的准备时间,提升列表响应速度。

        使用限制为:缓存列表项仅在使用LazyForEach懒加载时有效,ForEach循环渲染会一次性加载全量数据,故无法也不需要设置缓存列表项。 

        3、动态预加载

        根据历史任务加载耗时情况,动态调整屏幕可视区域外数据预取数量,配合懒加载设置,可在列表不断滑动时,屏幕可视区外实时更新列表数据,通过预取和预渲染数据提升列表滑动体验

        HarmonyOS提供了内容预取的能力Prefetcher,支持应用动态自适应网络状态,通过提前下载一些图片或资源,确保相关资源在需要时能立即显示,以尽可能减少白块出现的概率。

        LazyForEach懒加载可以通过使用Prefetcher来预取和预渲染数据。在使用Prefetcher后,除屏幕内显示的ListItem组件外,还会预先将屏幕可视区外的部分列表项数据进行预渲染和预取。这样当列表向下滑动时,会先显示预渲染组件,屏幕可视区外会动态调整预取范围。预取逻辑在Prefetcher的BasicPrefetcher类中实现,BasicPrefetcher支持预取和预渲染(图像解码、添加到组件树等)过程分离、自适应调整预获取范围、优先加载可视区域、以及取消不必要任务(快速滚动列表的场景下,智能取消不必要任务),其渲染过程如下:

        a、首先,请求n条数据,并在屏幕上显示m条数据

        b、当列表滑动,缓存列表项需要从屏幕可视区外进入可视区内时,此时显示预渲染组件,屏幕可视区外会动态调整预取范围,相比仅设置cachedCount提升了显示效率

        c、当列表不断滑动,屏幕可视区外实时更新列表项、更新预取数据和预渲染数据

        

        动态预加载适合加载列表项数据请求比较耗时的场景。

        4、组件复用

        提供可复用组件对象的缓存资源池,通过重复使用已经创建过并缓存的组件对象,降低相同组件短时间内频繁创建和销毁的开销,提升组件渲染效率。

        HarmonyOS应用框架提供了组件复用能力,可复用组件从组件树上移除时,会进入到一个回收缓存区。后续创建新组件节点时,会复用缓存区中的节点,节约组件重新创建的时间。尤其在列表等场景下,其自定义子组件具有相同的组件布局结构,列表更新时仅有状态变量等数据差异。通过组件复用可以提高列表页面的加载速度和响应速度。

        组件复用机制如下:

        a、标记为@Reusable的组件从组件树上被移除时,组件和其对应的JSView对象都会被放入复用缓存中

        b、当列表滑动新的ListItem将要被显示,List组件树上需要新建节点时,将会从复用缓存中查找可复用的组件节点

        c、找到可复用节点并对其进行更新后添加到组件树中。从而节省了组件节点和JSView对象的创建时间

        

        组件复用生效的条件是:

        (1)自定义组件被@Reusable装饰器修饰,即表示其具备组件复用的能力

        (2)在一个自定义父组件下创建出来的具备组件复用能力的自定义子组件,在可复用自定义组件从组件树上移除之后,会被加入到其自定义父组件的可复用节点缓存中

        (3)在一个自定义父组件下创建可复用的子组件时,若其父自定义组件的可复用节点缓存中有对应类型的可复用子组件,会通过更新可复用子组件的方式,快速创建可复用子组件

        (4) ForEach循环渲染会一次性加载全量数据,因此不支持组件复用

        若业务实现中存在以下场景,并成为UI线程的帧率瓶颈,推荐使用组件复用:

        (1)列表滚动:当应用需要展示大量数据的列表,并且用户进行滚动操作时,频繁创建和销毁列表项的视图可能导致卡顿和性能问题。在这种情况下,使用列表组件的组件复用机制可以重用已经创建的列表项视图,提高滚动的流畅度

        (2)动态布局更新:如果应用中的界面需要频繁地进行布局更新,例如根据用户的操作或数据变化动态改变视图结构和样式,重复创建和销毁视图可能导致频繁的布局计算,影响帧率。在这种情况下,使用组件复用可以避免不必要的视图创建和布局计算,提高性能

        (3)地图渲染:在地图渲染这种场景下,频繁创建和销毁数据项的视图可能导致性能问题。使用组件复用可以重用已创建的视图,只更新数据的内容,减少视图的创建和销毁,能有效提高性能

        5、布局优化

        使用扁平化布局方案,减少视图嵌套层级和组件数,避免过度绘制,提升页面渲染效率。

        列表不同于其他布局,包含了大量重复循环的ListItem,所以对每一个ListItem的布局优化格外重要。错误的布局方式可能会导致组件树和嵌套层数过多,在创建和布局绘制阶段产生较大的性能开销,导致界面卡顿。合理使用布局,减少嵌套层数,能提高布局效率。

标签:缓存,复用,列表,组件,屏幕,优化,加载
From: https://blog.csdn.net/sinat_34896766/article/details/142216485

相关文章

  • MySQL 优化器:理解与探秘
    在MySQL数据库的世界里,优化器扮演着至关重要的角色。它就像是一位幕后的魔法师,默默地为数据库的高效运行贡献着力量。那么,MySQL优化器究竟是什么?它又是如何工作的呢?让我们一起来揭开它的神秘面纱。一、MySQL优化器是什么?MySQL优化器是数据库管理系统中的一个核心组件......
  • 数据飞轮的演进与实践:探索出行行业的数据聚类和流程优化
    在当今的数据驱动时代,从数据仓库的构建到数据中台的发展,再到数据飞轮的形成,每一个阶段都是对大数据技术的深度挖掘和运用。在出行行业,这种技术的演化尤为显著,涉及到的技术层面包括数据采集、分析、流计算等多个方面。在这篇文章中,我们将深入探讨如何在出行行业应用这些技术,通过具体......
  • 关于​​Vue学习笔记6中纯JavaScript实现的改进优化1
    0前言在 Vue学习笔记6:分别使用纯JavaScript和Vue的v-if指令来有条件地渲染网页元素_PurpleEndurer@5lcto的技术博客_51CTO博客的纯JavaScript实现有条件地渲染网页元素中,我们列举了苹果、桔子和葡萄3种水果,并使用3个<p>...</p>来对应,在实现显示用户选择的水果的showFruit函数中,......
  • NCNN 源码(1)-模型加载-数据预处理-模型推理
    参考ncnn第一个版本的代码。0整体流程demo:squeezenetncnn自带的一个经典demo:squeezenet的代码://网络加载ncnn::Netsqueezenet;squeezenet.load_param("squeezenet_v1.1.param");squeezenet.load_model("squeezenet_v1.1.bin");//数据预处理ncnn::Matin......
  • 数据飞轮的实践与革新:流失用户挽回与产品体验优化
    在数据飞轮理念的推动下,企业正逐步从依赖传统的数据仓库和数据湖,过渡到更加动态和互动的数据中台架构。这种转变不仅仅是技术的革新,更是对数据的全新理解与利用方式的探索。在本文中,我将借助具体的业务场景—流失用户挽回与产品体验优化,深入探讨如何通过实时数据处理、数据分析和行......
  • 虚幻引擎游戏保存/加载存档功能
    函数名功能DoesSaveGameExist检查存档是否存在LoadGamefromSlot加载存档SaveGametoSlot保存存档DeleteGameinSlot删除存档SlotName是插槽名字存档都是通过插槽名字来读取/加载/检查/删除的先创建一个SaveGame类,这个类里可以存放要保存的数据,比如玩......
  • 广州浮点Creo软件许可优化实施成功案例
    浮动版Creo软件许可证优化、降本增效实施行业:制造业(汽车、机械、工业设计)实施软件:Creo软件一、背景概述1.项目背景Creo是一款功能强大的产品设计和三维建模软件,被广泛应用于机械制造、汽车设计、以及其他工业领域。随着企业项目数量和设计复杂度的提升,某大型制造企业在使用Creo......
  • 前端常见面试-首页性能提升、项目优化
     首页性能提升Vue首页性能提升是Vue应用开发中非常重要的一环,它直接影响用户体验和应用的加载速度。以下是一些关键的Vue首页性能提升策略:1.代码分割与懒加载路由懒加载:利用Webpack的动态导入(import())特性,实现路由级别的代码分割。这样,只有当用户访问某个路由时,其对应的组件代码......
  • 【看过来全网最细节】MySQL大数据量处理:全面优化方案与实践
    一、实施方案针对MySQL数据库数据量过大的问题,具体的实现细节可以包括以下几个方面:1.数据库分区(Partitioning)实现细节:选择分区类型:范围分区(RangePartitioning):适用于按时间范围或数值范围分区的场景。例如,按年份或月份将订单数据分区。列表分区(ListPartitioning):适用......
  • 水母搜索算法(JS)优化BP神经网络原理及Matlab代码
    目录0引言1数学模型2优化方式3Matlab代码3.1伪代码3.2 JS主函数代码3.2JS-BP4视频讲解0引言水母搜索算法(JellyfishSearch,JS)是由Jui-ShengChou在2020年基于水母搜索行为提出的群智能算法。该算法模拟水母搜索行为的包括它们的洋流跟随,它们在水母群中的运......