网罗开发小红书、快手、视频号同名大家好我是展菲目前在上市企业从事人工智能项目研发管理工作平时热衷于分享各种编程领域的软硬技能知识以及前沿技术包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。图书作者《ESP32-C3 物联网工程开发实战》图书作者《SwiftUI 入门进阶与实战》超级个体COC上海社区主理人特约讲师大学讲师谷歌亚马逊分享嘉宾科技博主华为HDE/HDG我的博客内容涵盖广泛主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告同时也会提供产品优缺点分析、横向对比并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。展菲您的前沿技术领航员 大家好我是展菲 全网搜索“展菲”即可纵览我在各大平台的知识足迹。 公众号“Swift社区”每周定时推送干货满满的技术长文从新兴框架的剖析到运维实战的复盘助您技术进阶之路畅通无阻。 微信端添加好友“fzhanfei”与我直接交流不管是项目瓶颈的求助还是行业趋势的探讨随时畅所欲言。 最新动态2025 年 3 月 17 日快来加入技术社区一起挖掘技术的无限潜能携手迈向数字化新征程文章目录前言为什么渲染性能会成瓶颈控制 UI 的更新范围列表用懒加载和复用主线程少做重计算图片与资源别拖后腿布局别写太复杂结合实际场景的几点习惯前言最近在做一个鸿蒙应用列表一长或者页面动效一多就感觉有点卡帧率掉得比较明显。后来查了下发现不少问题都出在 UI 渲染和主线程的计算上要么是整页整页地重绘要么是在 UI 线程里做了不该做的重活。ArkUI方舟 UI本身是声明式框架理论上已经帮我们做了不少优化但用不对姿势照样会把 CPU 拉满、帧率拉低。今天就从实际开发角度聊聊怎么利用 ArkUI 的特性做渲染优化减少不必要的 CPU 计算把帧率稳住。为什么渲染性能会成瓶颈界面要流畅一般需要稳定在 60 帧甚至更高也就是一帧大约 16 毫秒内要完成布局、绘制和提交。一旦主线程在这段时间里做了太多事——比如复杂计算、频繁创建组件、列表项过于复杂——就会挤占渲染时间造成掉帧。ArkUI 是声明式的你描述「界面长什么样」框架负责把变化算出来再渲染。但如果你描述得「粒度太粗」——比如一个很大的状态对象一变就整页刷新或者列表不用懒加载、一次性把几百个组件都建出来——框架也很难帮你省掉这些开销。所以优化的一大方向就是让「需要重算、重绘」的范围尽量小让主线程少干重活。控制 UI 的更新范围ArkUI 会根据状态变化做差量更新但前提是状态拆得合理。如果整页就绑在一个大对象上这个对象里任意一个字段变了都可能触发整棵组件树参与比较甚至重绘CPU 就会在「算 diff」和「重画」上花很多时间。尽量把状态拆细让「变什么就更新什么」。比如列表里每一项有自己的数据那就用ObservedV2包在单项数据上而不是把整份列表塞进一个大的响应式对象里。这样改某一项时主要只会更新对应的那一项组件而不是整列表。在实际项目里我们遇到过「勾选列表某一项就卡一下」的情况把列表数据改成按项可观察、勾选只改当前项状态之后帧率就稳多了。// 不推荐整列表一个状态改一项容易触发大范围更新Statelist:ArrayItem[...]// 推荐单项可观察更新局限在单条ObservedV2classItem{id:stringtitle:stringchecked:booleanfalse// ...}再比如一个页面里既有「和用户操作强相关」的局部状态比如弹窗显隐、输入框内容又有「全局共享」的数据可以分开局部用State放在对应组件全局用状态管理。这样点击某个按钮只改局部状态时不会把整页都带进更新逻辑里渲染范围小自然就更省 CPU。列表用懒加载和复用长列表是性能问题的重灾区。如果不用懒加载成百上千条数据会一次性建出成百上千个组件布局和测量都会在主线程堆在一起首屏就会卡滚动也更吃内存。ArkUI 提供了LazyForEach配合List使用只对可见区域以及少量缓冲创建和布局组件滚动时再按需创建和复用。这样列表再长实际参与渲染的也只是屏幕上的那一小部分CPU 和内存都会稳定很多。我们之前有一个「消息记录」页从普通ForEach改成LazyForEach之后进入页面的时间从明显卡顿降到几乎无感长列表滚动帧率也稳定在 60 左右。LazyForEach(this.dataSource,(item:Item){ListItem(){Text(item.title).fontSize(14)}},(item:Item)item.id)注意最后一个参数是 key 生成函数保证每条数据有稳定唯一 id这样在数据源增删改时框架才能正确复用节点避免整列表抖动或重复创建。key 不稳定会导致列表项错乱或多余重建反而拖慢性能。主线程少做重计算渲染是在主线程完成的如果在主线程里做复杂运算、大数组遍历、复杂对象构造就会直接拖慢每一帧的完成时间表现就是滑动不跟手、点击反应慢。能放到异步的尽量放到异步比如网络请求、大列表的过滤排序、复杂数据的预处理用async/await或Task在后台做完再把结果写回状态。主线程只做「拿到结果 → 更新状态 → 交给 ArkUI 去差量更新」这样界面就不会因为计算卡住。我们有个页面要在列表里做关键词高亮和分段一开始在 build 里现场算列表一长就卡后来改成在数据层算好再塞进模型列表只负责展示帧率马上上来。对于确实要在 UI 里用到的轻量计算可以尽量放到Computed或类似「按需计算」的机制里避免在每次 build 里重复算同一份东西也能减少无效重绘。图片与资源别拖后腿图片尺寸过大、数量过多解码和绘制都会占 CPU 和内存。尽量用合适分辨率的资源必要时在服务端或本地做缩略图列表里先展示小图再按需加载大图。ArkUI 的图片组件支持按宽高加载和裁剪避免把一张巨图直接塞进一个小 Image 里由系统去做缩放这样能减轻渲染压力。动图、大图能懒加载就懒加载不要一屏堆几十张一起解一起画。布局别写太复杂层级过深、嵌套过重布局测量和摆放的计算量都会上去。能扁平就扁平能用一个容器搞定的就别多套几层。约束尽量简单明确减少「先测一遍再又测一遍」的二次布局。对重复使用的布局结构可以抽成Builder或自定义组件既减少重复代码也方便框架做节点复用和比较。结合实际场景的几点习惯列表页数据源用LazyForEach单项用ObservedV2key 稳定唯一避免在单项里放特别重的子视图或复杂动效否则即使懒加载单条渲染成本一高快速滑动时还是会掉帧。详情页大块内容可以按模块拆状态首屏先渲染次要内容稍后或懒加载避免一打开页面就一次性算完、画完所有模块。动效优先用 ArkUI 提供的动画 API由框架在渲染管线里做比自己在定时器里改属性再触发布局要省 CPU也更顺滑。调试利用系统提供的性能分析工具看主线程耗时和渲染耗时找到具体是「布局多」「绘制多」还是「逻辑计算多」再针对性地收窄更新范围或挪走重计算比盲目改要高效得多。把这些习惯和 ArkUI 的声明式、差量更新、懒加载机制结合起来就能在不大改业务的前提下明显减轻 CPU 负担、提高帧率让鸿蒙应用的渲染更稳、更顺。性能优化是个持续过程先抓住「更新范围、列表懒加载、主线程别算重活」这几块往往就能解决大部分卡顿问题。