javascript - React Native - 处理繁重的 JS 代码而不影响性能/渲染的最佳方法

标签 javascript reactjs react-native webview

我正在研究 React Native 中的一些特定用例,我希望在不干扰在 React Native 中运行 UI 和动画的主线程的情况下执行一些繁重的 JS 操作。

示例是,一旦应用程序组件安装或用户触发任何动画序列(例如导航到新 View 动画、打开一些详细信息页面动画等),就运行 for 循环 10K 次。

如果我在动画开始之前执行以下代码,

// animate the item details page (from item list page)
onItemPressed() {
// Some JS code to mimic heavy processing
console.log('starting...');
for (let i = 0; i < 5000; i++) {
  (Math.random() * 9999999) / 7;         
}
console.log('Finished');

// starting animation sequence
this.setState({animationPhase: 'phase-2'});
}

直接运行上面的代码后,由于动画开始之前运行的代码,动画会出现延迟。

我正在研究以下方法:

  1. 使用 RN 的 InteractionManager - 阅读文档后,可以按照文档中提到的方式实现它 - 将 for 循环包装在 InteractionManager.runAfterInteractions() 处理程序中。然而,这并不能完全解决问题。它下面还有另一种方法,称为setDeadline,该方法的记录很少。我认为它对于处理数据 block 很有用,而不是一次处理整个代码。不知道如何使用它。

  2. RequestAnimationFrame/SetTimeout - 未按预期工作

  3. React native 线程/工作线程 - Web Workers 喜欢 API 在后台处理任务。这可以正常工作,并具有额外的优点,即我们可以向工作线程发送/监听消息以启动/停止任务执行。根据 RNThreads 的文档,我们可以将其用作 -

    import { Thread } from 'react-native-threads'; // import it in the required component
    
    this.thread = new Thread('./JS_FILE_THAT_HAS_HEAVY_DUTY_CODE.js'); // create new instance of it
    
    this.thread.onmessage = (message) => {} // listen to messages coming from the JS file
    
    this.thread.postMessage('Start'); // post message to the thread
    
    
    componentWillUnmount() {
        // stop the JS process
        this.thread.terminate();
     }
    
    // In thread.js file,
    
    import { self } from 'react-native-threads'; // import current worker context obj
    
    self.onmessage = message => {    // Listen to messages coming from parent script
    
       // start execution
    
    }
    
    self.postMessage('Completed');  // post messages to parent script
    
  4. 使用 WebView - 我还没有尝试过,但是this post在这种情况下似乎很有用,但是将字符串化的 javascript 注入(inject)到 Web View 中可以吗?没有把握。

我的问题是 -

  1. 我想了解有关 RN Interaction Manager 的更多信息,尤其是 setDeadline() 方法 - 如何使用它以及它的作用。
  2. 在此类用例中哪种方法更好?

最佳答案

我没有给你一个可靠的答案,因为我对 InteractionManager.setDeadline() 也不太熟悉,但我认为查看测试可以为你提供见解。重新之后。通常,测试可以很好地替代文档的缺乏。

因此,请查看 InteractionManager-test.js, specifically L230-L261

在那里,您会找到这些测试...

it('should execute tasks in loop within deadline', () => {
    InteractionManager.setDeadline(100);
    BatchedBridge.getEventLoopRunningTime.mockReturnValue(10);
    const task1 = createSequenceTask(1);
    const task2 = createSequenceTask(2);
    InteractionManager.runAfterInteractions(task1);
    InteractionManager.runAfterInteractions(task2);

    jest.runOnlyPendingTimers();

    expectToBeCalledOnce(task1);
    expectToBeCalledOnce(task2);
  });

  it('should execute tasks one at a time if deadline exceeded', () => {
    InteractionManager.setDeadline(100);
    BatchedBridge.getEventLoopRunningTime.mockReturnValue(200);
    const task1 = createSequenceTask(1);
    const task2 = createSequenceTask(2);
    InteractionManager.runAfterInteractions(task1);
    InteractionManager.runAfterInteractions(task2);

    jest.runOnlyPendingTimers();

    expectToBeCalledOnce(task1);
    expect(task2).not.toBeCalled();

    jest.runOnlyPendingTimers(); // resolve1
    jest.runOnlyPendingTimers(); // task2

    expectToBeCalledOnce(task2);
});

在我看来,这是一种划分工作的方式,这可能很有用。

你的解决方案3.很有趣。我个人很想看到一些关于此的代码。我在这方面没有经验,但这听起来很令人兴奋。我认为 webview 绝对应该有助于将工作卸载到单独的线程,但我以前从未在这种情况下使用过它。

关于javascript - React Native - 处理繁重的 JS 代码而不影响性能/渲染的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53805122/

相关文章:

javascript - Node.js 初学者 - 没有查询字符串的请求

javascript - Promise.all 解决得太早

javascript - 如何使用React从Fantasy Premier League检索授权信息

ios - AsyncStorage 引用崩溃 react iOS 上的 native 应用程序

javascript - 如何让我的类装饰器只在继承链中最外层的类上运行?

javascript - DOM 对象克隆器 Javascript 小部件

html - 获取WebView中脚本的事件响应到react native

javascript - 在react-native中导入npm模块时出错

javascript - 在 Highcharts 条形图中绘制自定义条形

javascript - 在 Axios 调用后设置状态后无法让 React 组件更新