首页 > 解决方案 > 使用 React Native 运行繁重的 JS 任务

问题描述

寻找有关如何在执行计算量大的 JS 任务时保持 React Native 应用程序 UI 响应的答案/反馈/建议。

我必须解析 JSON 字符串信息,即应用程序设置数据。

我已将此确定为导致我的应用程序中的 UI 卡顿的罪魁祸首。在 JS 中接收到 JSON 字符串(它是本机加载的文件)后,我必须解析 JSON 以为应用程序构建一个“内存数据库”。Sudo 代码如下所示:

function parseSetup(jsonString) {
  var json = JSON.parse(jsonString); //This can take up to 100+ms for a 3MB JSON file

  for (let item of json.items) {
    // Do some parsing
    // Instantiate model objects w/json info
    // could take up to 3000ms
  }

  for (let thing of json.things) {
    // Same as above
  }

  for (let parent of json.parents) {
    //Same as above
    for (let child of parent) {
      //Same as above, but note this is a nested for loop
    }
  }
}

parseSetup,最多可能需要 5,000+ms(5 秒)。这会锁定 JS 线程,使我的应用程序看起来冻结,因为本机触摸事件和 JS 逻辑在 parseSetup 函数之后排队。进入InteractionManager 的runAfterInteraction。我使用 runAfterInteraction 取得了一些成功,但我基本上用 runAfterInteraction 包装了我拥有的每一行代码。感觉不对,而且它不能 100% 工作,因为一些用 runAfterInteraction 包装的函数可能需要比 InteractionManagers.setDeadline 设置的截止日期更长的时间。所以这就是我的结果:

function parseSetup(jsonString) {
  var json = JSON.parse(jsonString); //This can take up to 100+ms for a 3MB JSON file
  InteractionManager.setDeadline(30);

  for (let item of json.items) {
    InteractionManager.runAfterInteraction(() => someInnerFunc()); //Could take 50ms
    InteractionManager.runAfterInteraction(() => someOtherFunc());
  }

  for (let thing of json.things) {
    InteractionManager.runAfterInteraction(() => someInnerFunc());
    InteractionManager.runAfterInteraction(() => someOtherFunc());
  }

  for (let parent of json.parents) {
    InteractionManager.runAfterInteraction(() => someInnerFunc());
    InteractionManager.runAfterInteraction(() => someOtherFunc());
    for (let child of parent) {
      InteractionManager.runAfterInteraction(() => someInnerFunc());
      InteractionManager.runAfterInteraction(() => someOtherFunc());
    }
  }

  //Do the above for more JSON keys (50+ more)
}

我是否正确理解任何执行时间超过 16.67/ms 的函数都会阻塞 JS 线程?

倒数第二个问题:有没有更好的方法来运行这样的长函数而不锁定 JS 线程?谢谢

标签: javascriptperformancereact-native

解决方案


有两种解决方案。

  1. 使用 redux 和 redux-persist。这些可以将javascript对象保存在数据库中。它必须完美地解决这个问题。

  2. 在我看来,移动应用程序不应该运行繁重的任务。构建 API 服务器,解析 json。移动应用程序只显示来自 API 服务器的解析 json。


推荐阅读