NativeScript-Vue рендеринг RadListView очень медленно под Android и заморозить интерфейс - PullRequest
2 голосов
/ 26 апреля 2019

У меня есть приложение nativescript-vue с компонентом RadListView для отображения данных пользователю.Каждая строка списка содержит несколько сведений для текущего элемента.Когда я нажимаю на кнопку, чтобы загрузить и показать список, пользовательский интерфейс зависает (быстрое оборудование -> короткое; медленное оборудование -> длинное).Я понял, что часть кода для загрузки / объединения данных выполняется очень коротко, но внутренняя визуализация сценария или создание элементов пользовательского интерфейса являются проблемой.Консоль андроида показывает информацию

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

Подобные сообщения о проблемах

Я смотрю на stackoverflow и github, но проблемытам (например, NativeScript Angular RadListView рендеринг очень медленно ) выглядит аналогично, но решения не подходят для меня.

Я использую LinearListView (не Grid или Stagged) и, возможно, в моем реальном приложении я будубыть в состоянии упростить элементы строки из списка, но в моем примере приложения (посмотрите вниз) я использую простой дизайн пользовательского интерфейса строки.

Пример приложения

Для более простого и лучшего отчета я создалПример приложения на {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;
}    

Примечание. Я использую 10000 элементов, чтобы сделать проблему видимой, даже если пример приложения работает на S9 или другом смартфоне высокого класса.

Полный источник данных работает под https://play.nativescript.org/?template=play-vue&id=Td1GWR

Немного другая версия с ObservableArray вместо простого массива находится под https://play.nativescript.org/?template=play-vue&id=5BXOFG

В обеих версиях обработка данных происходит быстро, но как только элементы пользовательского интерфейса, сгенерированные из внутренних функций, пользовательский интерфейс будутбыть замороженным.

Пример: на моем Nexus 7 2013 с Android 6.x пользовательский интерфейс зависает почти на 6 секунд, а другие приложения не работают в фоновом режиме.

iOS

Если я попробую те же приложения на устройстве iOS (например, iPhone 7s), рендеринг будет очень быстрым, и пользовательский интерфейс будет работать плавно, несмотря на 10000 элементов и более.

Идеи?

Кто-нибудь знает, как я могу ускорить рендеринг?Если нет, то есть ли предложение, как я могу создать анимацию (например, ActivityIndicator), чтобы показать пользователю, что устройство работает?В тот момент, когда я помещаю ActivityIndicator в пользовательский интерфейс, пользователь не может его увидеть из-за замороженного пользовательского интерфейса.

...