【问题标题】:Why is `unstable_Profiler` not profiling on production mode?为什么`unstable_Profiler`不在生产模式下进行分析?
【发布时间】:2019-02-14 15:15:01
【问题描述】:

我的 React-Native 项目中的 unstable_Profiler 存在一个问题,它忽略了 onRender 回调,但仅限于生产模式。没有错误,一切都很好。我通过这篇文章去了:https://itnext.io/react-native-profiler-43d131130c5c

我在开发模式(react-native run-android)下测试了解决方案,一切都很完美。应用程序的生产版本不起作用。 我尝试了最新版本的 react 和 react-native、react-dom、schedule、scheduler、modify .babelrc,但没有任何效果。

import React, { unstable_Profiler as Profiler } from 'react';

const withProfiler = (profilerId) => (WrappedComponent) => {

  class ProfilerComponent extends React.Component {

    async logMeasurement(id, phase, actualDuration, baseDuration) {
      // see output during DEV
      console.log({id, phase, actualDuration, baseDuration});

      // also here is some logic to log durations in prod mode. (eg. logcat)
      // but it never happened. 
    }

    render() {
      return (
        <Profiler id={profilerId} onRender={this.logMeasurement}>
          <WrappedComponent {...this.props} />
        </Profiler>
      );
    }
  }

  return ProfilerComponent;
};

export default withProfiler;

.babelrc

{
  "presets": [
    "module:metro-react-native-babel-preset"
  ],
  "plugins": [
    ["module-resolver", {
      "root": ["./"],
      "alias": {
        "react-dom$": "react-dom/profiling",
        "scheduler/tracing": "scheduler/tracing-profiling"
      }
    }]
  ],
  "env": {
    "production": {
      "plugins": [
        "transform-remove-console",
      ]
    },
    "development": {
      "plugins": [
        "@babel/plugin-transform-react-jsx-source"
      ]
    }
  }
}

package.json

 "react": "^16.8.1",
 "react-native": "^0.57.8",
 "react-dom": "16.8.1",
 "react-art": "16.8.1",
 "schedule": "^0.4.0",
 "scheduler": "^0.13.1",

 "@babel/core": "7.1.0",
 "@babel/plugin-proposal-decorators": "^7.3.0",
 "@babel/plugin-transform-react-jsx-source": "^7.2.0",
 "@babel/preset-env": "^7.3.1",
 "@babel/register": "^7.0.0",
 "babel-core": "^7.0.0-bridge.0",
 "babel-loader": "^8.0.4",
 "babel-plugin-module-resolver": "^3.1.3",
 "babel-plugin-transform-remove-console": "^6.9.4",
 "metro-react-native-babel-preset": "^0.48.1",

预期结果是logMeasurement 方法正在生产应用程序中运行。


编辑

我的logMeasurement 绑定无效。这是我修复它的方法。

logMeasurement = async (id, phase, actualDuration, baseDuration) => { ... }

但是,它并没有解决问题。回调仍未被调用。

【问题讨论】:

  • 你不是binding this.logMeasurement,这有关系吗?
  • 感谢@Jacob 的回复。我已经在上面的代码中修复了它,但没有解决这个问题。我已经编辑了这篇文章。
  • 嗨,@user 6547076。您找到解决方案了吗?我被困在同一个问题上。在生产模式下不起作用。

标签: javascript android reactjs react-native


【解决方案1】:

const logProfile = (
  id: string,
  phase: "mount" | "update",
  actualDuration: number,
  baseDuration: number,
  startTime: number,
  commitTime: number,
  interactions: Set<any>
) => {
  console.log("Profiling ID", id);
  console.log("Profiling phase", phase);
  console.log("Profiling actualDuration", actualDuration);
  console.log("Profiling baseDuration", baseDuration);
  console.log("Profiling startTime", startTime);
  console.log("Profiling commitTime", commitTime);
  console.log("Profiling interactions", interactions);
};

class Sample extends React.Component {
  render() {
    return (
          <Profiler id="application" onRender={logProfile}>
              <div id="preload_hidden"></div>
          </Profiler>
    );
  }
}

【讨论】:

  • 对不起,我的英语说得不好。
【解决方案2】:

您需要在构建时选择加入,因为它是实验性的。

yarn build --profile

您还可以将其添加到您的 prod js 文件上的 webpack 构建中并添加别名

'react-dom$': 'react-dom/profiling'

【讨论】:

    【解决方案3】:

    我有一个非常相似的问题。显然这是由“id”中的“-”引起的。

    改成

    <Profiler id="Main-Value-Circle" onRender={this.profilerCallback}>
    

    <Profiler id="MainValueCircle" onRender={this.profilerCallback}>
    

    解决了我的问题。

    【讨论】:

      【解决方案4】:

      react-native的答案

      您可以在 babel 配置中通过别名导入使用 release 构建中的 &lt;Profiler&gt; 组件捕获分析信息

      babel.config.js

      require('dotenv').config();
      
      const config = {
          presets: [require('metro-react-native-babel-preset')],
          plugins: [],
      };
      
      /* When REACT_ENABLE_RELEASE_PROFILE is set we add these aliases 
       * to also capture React.Profiler metrics in release builds */
      if (process.env.REACT_ENABLE_RELEASE_PROFILE) {
          const path = require('path');
      
          const profilingRenderer = path.resolve(
              __dirname,
              './node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-profiling',
          );
      
          config.plugins.push(['module-resolver', {
              root: ['./'],
              alias: {
                  'ReactNativeRenderer-prod': profilingRenderer,
                  'scheduler/tracing': 'scheduler/tracing-profiling',
              },
          }]);
      }
      
      module.exports = config;
      
      

      这将使onRender 回调也可以在生产/发布包中工作

      默认情况下,分析在发布中被禁用,因为它增加了一些开销 这就是为什么最好只像上面的例子那样有条件地启用它

      您可以通过多种方式设置此变量 - 在运行脚本之前,或作为.env config 的一部分

      package.json

      {
        "scripts": {
          "profile:android": "REACT_ENABLE_RELEASE_PROFILE=true npm run android",
          "profile:ios": "REACT_ENABLE_RELEASE_PROFILE=true npm run ios"
        }
      }
      

      或在.env

      REACT_ENABLE_RELEASE_PROFILE=true
      

      【讨论】:

        猜你喜欢
        • 2014-06-01
        • 2021-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多