使用 React 和 Capacitor v6 的 Android WebView 的性能问题:用户交互期间空闲时间过多

问题描述 投票:0回答:1

我目前正在使用 React 和 Capacitor v6 构建一个词汇训练器应用程序。虽然该应用程序在网络上表现得非常好,并且在 iOS 上也有良好的性能,但我在 Android 上面临着严重的性能问题。这些问题存在于不同的设备和 Android 版本中,包括物理设备和运行 Android 14(API 级别 34)的 AVD 模拟器。

应用程序概述:

应用程序向用户显示一个单词,单击“解决”按钮后,它:

  • 从 API 获取单词的翻译。
  • 根据交互更新多个用户的统计数据。

性能分析:

我通过连接我的 AVD 设备(模拟器),使用 Chrome DevTools 进行了性能分析。该分析捕获单个用户交互。

以下是性能分析的结果:

enter image description here

如屏幕截图中突出显示的,交互过程中存在大量空闲时间,这导致应用程序的响应能力明显延迟。

此外,Android-Studio Profiler 显示我的 CPU 消耗最多为 22%,内存消耗最多为 95MB。

  • 我已经尝试将尽可能多的处理工作转移给 API。
  • 我已经确保在我的 Android 上启用硬件加速 应用程序。
  • 我尝试通过进行更多代码分割来提高性能。

补充说明:

  • 我正在使用 fetch API 来执行我的请求,并使用 TanStack-Query 进行异步状态管理。
  • 请求使用 HTTP/2,并且发出请求的连接是为多个请求共享的,而不是为每个请求打开一个新连接。
  • 请求之前有 4 个预检调用,但只需要 15-25ms。
  • 在此用例中我没有使用任何动画。
  • 当我在设备上的 Chrome 应用程序(或任何其他浏览器应用程序)中打开我的应用程序时,它的性能非常好。

问题:

  • Android 上空闲时间过长的原因可能是什么?如何进一步诊断?
  • 我可以采取哪些额外步骤来专门针对 Android 设备优化应用程序的性能?

不幸的是,我无法提供我的应用程序的链接,因为它尚未发布。我正在我的临时环境中测试它,并且该应用程序仅在应用程序商店中处于内部测试状态。不过,如果您需要更多信息,请随时询问。

我将非常感谢任何有助于解决此问题的见解或建议。预先感谢您!

android reactjs performance android-webview capacitor
1个回答
0
投票

我能够显着提高应用程序的性能,将时间从 1660 毫秒减少到仅 410 毫秒。

performanc analysis

我遇到的问题涉及使用

capacitor-secure-storage-plugin
存储 OAuth JWT。最初,每次我向 API 发出 HTTP 请求时,我都会从安全存储中检索访问令牌,结果证明这非常消耗性能。

为了解决这个问题,我实施了一种混合方法。我仍然使用安全存储来保存令牌,确保它们安全存储。但是,在第一次检索令牌后,我将其存储在内存中以供后续访问。这大大减少了重复访问安全存储的需要,从而提高了性能。

这是我自定义的实现

CapacitorSecureStorage

import { KeyValueStorageInterface } from '@aws-amplify/core';
import { SecureStoragePlugin } from 'capacitor-secure-storage-plugin';

export default class CapacitorSecureStorage
    implements KeyValueStorageInterface
{
    storageObject: Record<string, string | null> = {};
    private static instance: CapacitorSecureStorage;

    private constructor() {}

    public static getInstance(): CapacitorSecureStorage {
        if (!CapacitorSecureStorage.instance) {
            CapacitorSecureStorage.instance = new CapacitorSecureStorage();
        }

        return CapacitorSecureStorage.instance;
    }

    async setItem(key: string, value: string): Promise<void> {
        try {
            await SecureStoragePlugin.set({ key, value });
            this.storageObject[key] = value;
        } catch (error) {
            return Promise.resolve();
        }
    }

    async getItem(key: string): Promise<string | null> {
        try {
            if (key in this.storageObject) {
                return this.storageObject[key];
            }

            const result = await SecureStoragePlugin.get({ key });
            this.storageObject[key] = result.value || null;

            return result.value || null;
        } catch (error) {
            this.storageObject[key] = null;
            return null;
        }
    }

    async removeItem(key: string): Promise<void> {
        try {
            await SecureStoragePlugin.remove({ key });
            delete this.storageObject[key];
        } catch (error) {
            return Promise.resolve();
        }
    }

    async clear(): Promise<void> {
        try {
            await SecureStoragePlugin.clear();
            this.storageObject = {};
        } catch (error) {
            return Promise.resolve();
        }
    }
}

通过使用这种方法,我成功地显着减少了 HTTP 请求所花费的时间,因为在第一次从安全存储中检索令牌后,现在可以快速从内存中访问令牌。

© www.soinside.com 2019 - 2024. All rights reserved.