【发布时间】:2025-11-29 00:30:01
【问题描述】:
我有一个带有 RadListView 组件的 nativescript-vue 应用程序来向用户显示数据。列表的每一行都包含当前项目的多个信息。当我点击按钮加载并显示列表时,UI 冻结(快速硬件 -> 短;慢速硬件 -> 长)。我发现加载/组合数据的代码部分运行时间很短,但原生脚本内部渲染或 UI 元素的创建是问题所在。 android控制台显示信息
I/Choreographer: Skipped 430 frames! The application may be doing too much work on its main thread.
平台信息:
- tns-ios 5.2.0
- tns-android 5.2.1
- nativescript-ui-listview 6.2.0
- tns-core-modules 5.3.1
类似问题报告
我查看了 * 和 github,但那里的问题(例如 NativeScript Angular RadListView rendering extremely slowly)看起来相似,但解决方案不适合我。
我使用 LinearListView(不是 Grid 也不是 Stagged),也许在我的真实应用程序中,我将能够简化列表中的行元素,但在我的示例应用程序(向下看)中,我使用了简单的行 ui 设计。
示例应用
为了获得更简单更好的报告,我在 {N}-Playground 上创建了一个示例应用程序。该应用程序创建 10000 个数组元素并将它们设置为 RadListView 的源,其中每个元素都有一个标签、一个开关和一个 ActivityIndicator。
<RadListView ref="listView"
for="alarm in alarms"
layout="linear">
<v-template>
<StackLayout class="list-element" orientation="vertical" >
<GridLayout columns="*, auto, auto" rows="*">
<Label col="0" row="0">{{alarm.name}}</Label>
<Switch col="1" row="0" :checked="alarm.active" />
<ActivityIndicator col="2" row="0" :busy="alarm.active"/>
</GridLayout>
<Label class="list-element-divider"></Label>
</StackLayout>
</v-template>
</RadListView>
第一步将在一个临时数组中生成 10000 个元素:
loadData() {
this.tmpAlarms = [];
for (let i = 0; i <= 10000; i++) {
this.tmpAlarms.push({
name: "Hase " + i,
active: i % 2 === 0,
});
}
}
使用第二个按钮将临时数组设置为源:
setData() {
this.alarms = this.tmpAlarms;
}
注意:即使示例应用程序在 S9 或其他高端智能手机上运行,我也使用 10000 个元素来显示问题。
完整源码可在https://play.nativescript.org/?template=play-vue&id=Td1GWR下运行
https://play.nativescript.org/?template=play-vue&id=5BXOFG 下有一个稍微不同的版本,带有 ObservableArray 而不是普通数组。
在这两个版本中,数据处理速度都很快,但是一旦从内部函数生成的 UI 元素,UI 就会被冻结。
示例:在装有 Android 6.x 的 Nexus 7 2013 上,UI 冻结了近 6 秒,并且没有其他应用在后台运行。
iOS
如果我在 iOS 设备(例如 iPhone 7s)上尝试相同的应用程序,渲染速度非常快,并且 UI 运行流畅,即使有 10000 个元素等等。
想法?
有人知道如何加快渲染速度吗?如果没有,是否有建议我如何构建动画(例如 ActivityIndicator)来向用户显示设备正在工作?当我在 UI 上放置 ActivityIndicator 时,由于 UI 冻结,用户无法看到它。
【问题讨论】:
-
ListView 的全部目的是减少加载时间,因为它实际上不会一次渲染 10k 个项目。在我的设备上渲染列表需要一秒/不到一秒,我正在使用带有 Android 8.1 的 Moto G5 Plus。如果您从模板中删除活动指示器,是否会有所不同?
-
感谢@Manoj 的建议。我删除了 ActivityIndicator 和 Switch,但在我的慢速设备上,渲染仍然很慢。看来有无Switch+ActivityIndicator没有时间上的区别。
-
我添加了一个赏金,因为我们在 Android 上看到了类似的东西,但在 iOS 上没有。 @TeHa,你有没有做任何事情来改善你在 Android 上的缓慢渲染?
-
@clay,不抱歉。我最终切换到了 Nativescript + Angular。即使在 Android 下,“相同”的代码也快得多,因为我在 iOS 下编写的早期 Vue 没有问题。我对 Vue + Android 的最后看法表明,GUI 元素的内部生成速度很慢。
标签: nativescript nativescript-vue nativescript-telerik-ui radlistview