HarmonyOS 鸿蒙Next中Refresh组件下拉刷新动画超过2秒再结束会卡顿

HarmonyOS 鸿蒙Next中Refresh组件下拉刷新动画超过2秒再结束会卡顿 目前试了执行2秒后结束刷新很流畅,3秒后结束,动画回弹的时候有一次明显的卡顿,这个怎么解决?

demo如下

import { TestView } from '../view/TestView';

// xxx.ets
@Entry
@Component
struct RefreshPage {
  @State isRefreshing: boolean = false;

  build() {
    Column() {
      Refresh({ refreshing: $$this.isRefreshing }) {
        Scroll() {
          Column() {
            TestView()
          }.justifyContent(FlexAlign.Center)
          .width('100%')
          .layoutWeight(1)
        }.scrollBar(BarState.Off)
        .edgeEffect(EdgeEffect.None)
      }
      .onRefreshing(() => {
        setTimeout(() => {
          this.isRefreshing = false;
        }, 2000)
      })
      .onStateChange((state)=>{
        console.info('TAGRefresh',`onStateChange:${state}`)
      })
      .backgroundColor(0x89CFF0)
      .refreshOffset(200)
      .pullToRefresh(true)
    }
  }
}
@Component
export struct TestView {
  @State arr: string[] = []
  aboutToAppear(): void {
    for (let index = 0; index < 20; index++) {
      this.arr[index] = index +
        'itemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitemitem'
    }
  }
  build() {
    Grid() {
      Repeat(this.arr).each((rep: RepeatItem<string>) => {
        GridItem() {
          Text(rep.item)
        }
      }).key((item) => item)
        .virtualScroll()
    } .nestedScroll({
      scrollForward: NestedScrollMode.PARENT_FIRST,
      scrollBackward: NestedScrollMode.SELF_FIRST
    })
    .width('100%')
    .height("100%")
    .columnsGap(12)
    .rowsGap(12)
    .columnsTemplate('1fr '.repeat(2))
  }
}

更多关于HarmonyOS 鸿蒙Next中Refresh组件下拉刷新动画超过2秒再结束会卡顿的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

TestView组件中使用的Grid+Repeat组合在大数据量场景下存在性能隐患,建议

使用LazyForEach替代Repeat实现动态加载

开启cachedCount预加载机制

LazyForEach(this.dataSource, (item: string) => {
  GridItem() {
    Text(item)
  }
}, (item: string) => item)
.cachedCount(5)

当前nestedScroll配置可能导致手势冲突

.nestedScroll({
  scrollForward: NestedScrollMode.SELF_FIRST, // 优先处理子组件滚动
  scrollBackward: NestedScrollMode.SELF_FIRST
})

更多关于HarmonyOS 鸿蒙Next中Refresh组件下拉刷新动画超过2秒再结束会卡顿的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


我觉得和TestView中Grid布局嵌套Repeat渲染大量数据项的文本内容,触发频繁重绘有关。另外nestedScroll模式与虚拟滚动参数未充分优化。

试一下将Grid布局改为更高效的List组件,减少网格布局的复杂计算

// 优化TestView

build() {

  List() {

    ForEach(this.arr, (item: string) => {

      ListItem() {

        Text(item)

          .fontSize(16)

          .padding(12)

      }

    }, (item) => item)

  }

  .width('100%')

  .height("100%")

  .nestedScroll({

    scrollForward: NestedScrollMode.PARENT_FIRST,

    scrollBackward: NestedScrollMode.SELF_FIRST 

  })

}

将状态更新操作放入微任务队列,通过异步队列避免阻塞UI线程:

.onRefreshing(() => {

  setTimeout(() => {

    Promise.resolve().then(() => {

      this.isRefreshing = false; 

    })

  }, 3000)

})

调整Refresh组件参数可提升流畅度:

Refresh({ refreshing: $$this.isRefreshing })

  .springEffect(SpringEffect.LARGE) // 使用更平滑的弹簧效果

  .friction(20) // 增加摩擦力系数

  .refreshOffset(150) // 减小触发距离

在TestView中添加渲染优化参数:

Grid()

  .cachedCount(5) // 开启缓存提升虚拟滚动性能

  .layoutWeight(1) // 避免布局尺寸反复计算

【背景知识】

Refresh:可以进行页面下拉操作并显示刷新动效的容器组件。

【参考方案】 可参考下拉刷新和上拉加载效果自定义示例,通过Refresh实现下拉刷新效果。

下拉页面时,通过设置Refresh的builder自定义刷新区域显示内容,通过reload()实现刷新。

Refresh({ refreshing: $$this.refreshing, builder: this.refreshBuilder() }) {
}
.onRefreshing(() => {
  setTimeout(() => {
    this.dataSource.reload()
  }, Constants.DELAY_TIME)
})

在鸿蒙Next中,Refresh组件的下拉刷新动画若持续超过2秒,可能导致UI渲染阻塞。这通常由于主线程耗时操作或动画资源未及时释放引起。建议检查onRefresh回调中的异步任务执行效率,并确保刷新完成时立即调用finishRefresh()。可通过DevEco Studio的Performance Profiler分析帧率及线程状态,定位具体性能瓶颈。

在HarmonyOS Next中,Refresh组件在超过2秒后结束刷新时出现卡顿,通常与动画帧率和主线程阻塞有关。当刷新动画持续时间较长时,系统可能因资源调度或UI渲染压力导致回弹动画不流畅。

建议优化方法:

  1. 减少setTimeout延迟至2000ms以内,或使用requestAnimationFrame确保动画与刷新率同步。
  2. 检查TestView组件的布局复杂度,Grid嵌套Repeat和大量文本可能加重渲染负担,可尝试简化内容或使用懒加载。
  3. 确认NestedScroll配置是否必要,嵌套滚动可能增加计算开销。

若问题持续,需排查是否有其他后台任务占用主线程,或考虑使用性能分析工具定位具体瓶颈。

回到顶部