首页 > 解决方案 > 为什么`unstable_Profiler`不在生产模式下进行分析?

问题描述

unstable_Profiler我的React-Native 项目有一个问题,它忽略了 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"
      ]
    }
  }
}

包.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) => { ... }

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

标签: javascriptandroidreactjsreact-native

解决方案


回答react-native

您可以通过在 babel 配置中对导入进行别名来使用构建中的<Profiler>组件捕获分析信息release

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配置的一部分

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

推荐阅读