├── example ├── .node-version ├── .watchmanconfig ├── .ruby-version ├── app.json ├── .bundle │ └── config ├── .eslintrc.js ├── babel.config.js ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ └── drawable │ │ │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── jni │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── MainApplicationModuleProvider.h │ │ │ │ │ ├── OnLoad.cpp │ │ │ │ │ ├── MainComponentsRegistry.h │ │ │ │ │ ├── MainApplicationModuleProvider.cpp │ │ │ │ │ ├── MainApplicationTurboModuleManagerDelegate.h │ │ │ │ │ ├── MainApplicationTurboModuleManagerDelegate.cpp │ │ │ │ │ └── MainComponentsRegistry.cpp │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ ├── newarchitecture │ │ │ │ │ ├── components │ │ │ │ │ │ └── MainComponentsRegistry.java │ │ │ │ │ ├── modules │ │ │ │ │ │ └── MainApplicationTurboModuleManagerDelegate.java │ │ │ │ │ └── MainApplicationReactNativeHost.java │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ └── debug │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── ReactNativeFlipper.java │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ ├── build_defs.bzl │ │ ├── _BUCK │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ ├── build.gradle │ ├── gradle.properties │ ├── gradlew.bat │ └── gradlew ├── ios │ ├── example │ │ ├── Images.xcassets │ │ │ ├── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── AppDelegate.h │ │ ├── main.m │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── AppDelegate.mm │ ├── example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── .xcode.env │ ├── exampleTests │ │ ├── Info.plist │ │ └── exampleTests.m │ ├── Podfile │ └── example.xcodeproj │ │ └── xcshareddata │ │ └── xcschemes │ │ └── example.xcscheme ├── .buckconfig ├── .prettierrc.js ├── Gemfile ├── index.js ├── __tests__ │ └── App-test.js ├── metro.config.js ├── package.json ├── .gitignore ├── .flowconfig └── App.js ├── flipper-desktop ├── .gitignore ├── src │ ├── utils │ │ ├── round.ts │ │ ├── getFPS.ts │ │ ├── sanitizeData.ts │ │ ├── getTotalTimeAndFrames.ts │ │ └── getThreadMeasures.ts │ ├── components │ │ ├── ScrollContainer.tsx │ │ ├── Title.tsx │ │ ├── StartButton.tsx │ │ ├── Table.tsx │ │ ├── CircularProgressWithLabel.tsx │ │ └── Chart.tsx │ ├── types │ │ └── Measure.ts │ ├── openMigrationDialog.tsx │ ├── index.tsx │ ├── Report.tsx │ ├── __tests__ │ │ └── Plugin.spec.tsx │ ├── PerfMonitorView.tsx │ └── GfxInfo.tsx ├── jestSetup.ts ├── jest.config.js ├── tsconfig.json └── package.json ├── flipper-native ├── app.plugin.js ├── plugin │ ├── jest.config.js │ ├── .eslintrc.js │ ├── tsconfig.json │ └── src │ │ └── index.ts ├── src │ └── index.ts ├── .eslintrc.js ├── android │ ├── src │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── tech │ │ │ │ └── bam │ │ │ │ └── rnperformance │ │ │ │ └── flipper │ │ │ │ ├── FlipperPerformancePluginPackage.java │ │ │ │ └── FlipperPerformancePluginModule.java │ │ └── debug │ │ │ └── java │ │ │ └── tech │ │ │ └── bam │ │ │ └── rnperformance │ │ │ └── flipper │ │ │ ├── FPSMonitor.java │ │ │ └── RNPerfMonitorPlugin.java │ └── build.gradle ├── tsconfig.json ├── index.js ├── ios │ ├── FlipperPerformancePlugin.h │ ├── FBDefines │ │ └── FBDefines.h │ ├── FlipperPerformancePlugin.m │ └── FlipperPerformancePlugin.xcodeproj │ │ └── project.pbxproj ├── package.json ├── .gitignore └── react-native-flipper-performance-plugin.podspec ├── react-native-startup-trace ├── index.d.ts ├── android │ ├── src │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── tech │ │ │ └── bam │ │ │ └── rnperformance │ │ │ └── startuptrace │ │ │ ├── StartupTracePackage.java │ │ │ └── StartupTraceModule.java │ ├── README.md │ └── build.gradle ├── jest.setup.js ├── ios │ ├── StartupTrace.xcworkspace │ │ └── contents.xcworkspacedata │ ├── StartupTrace.h │ ├── StartupTrace.m │ └── StartupTrace.xcodeproj │ │ └── project.pbxproj ├── index.js ├── .gitignore ├── package.json ├── react-native-startup-trace.podspec └── README.md ├── expo-example ├── assets │ ├── icon.png │ ├── splash.png │ ├── favicon.png │ └── adaptive-icon.png ├── README.md ├── babel.config.js ├── .expo-shared │ └── assets.json ├── metro.config.js ├── .gitignore ├── index.js ├── eas.json ├── package.json ├── app.json └── App.js ├── .travis.yml ├── LICENSE └── README.md /example/.node-version: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /example/.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.5 2 | -------------------------------------------------------------------------------- /flipper-desktop/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /flipper-native/app.plugin.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./plugin/build'); -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "displayName": "example" 4 | } -------------------------------------------------------------------------------- /react-native-startup-trace/index.d.ts: -------------------------------------------------------------------------------- 1 | export const useStopStartupTrace: () => void; 2 | -------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /flipper-native/plugin/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require("expo-module-scripts/jest-preset-plugin"); 2 | -------------------------------------------------------------------------------- /example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; 5 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | example 3 | 4 | -------------------------------------------------------------------------------- /flipper-native/src/index.ts: -------------------------------------------------------------------------------- 1 | // keep this empty file, otherwise expo-module-scripts will throw an error that "no inputs found" 2 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /flipper-native/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // @generated by expo-module-scripts 2 | module.exports = require('expo-module-scripts/eslintrc.base.js'); 3 | -------------------------------------------------------------------------------- /expo-example/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/expo-example/assets/icon.png -------------------------------------------------------------------------------- /expo-example/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/expo-example/assets/splash.png -------------------------------------------------------------------------------- /expo-example/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/expo-example/assets/favicon.png -------------------------------------------------------------------------------- /flipper-native/plugin/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // @generated by expo-module-scripts 2 | module.exports = require('expo-module-scripts/eslintrc.base.js'); 3 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /expo-example/README.md: -------------------------------------------------------------------------------- 1 | # Expo example 2 | 3 | ``` 4 | npm install 5 | npx expo prebuild --clean 6 | npx expo run:android 7 | npx expo run:ios 8 | ``` 9 | -------------------------------------------------------------------------------- /expo-example/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/expo-example/assets/adaptive-icon.png -------------------------------------------------------------------------------- /expo-example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /flipper-desktop/src/utils/round.ts: -------------------------------------------------------------------------------- 1 | export const round = (n: number, decimals: number) => { 2 | const power = Math.pow(10, decimals); 3 | return Math.floor(n * power) / power; 4 | }; 5 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /flipper-native/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby '2.7.5' 5 | 6 | gem 'cocoapods', '~> 1.11', '>= 1.11.2' 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /expo-example/.expo-shared/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true, 3 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true 4 | } 5 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /expo-example/metro.config.js: -------------------------------------------------------------------------------- 1 | // Learn more https://docs.expo.io/guides/customizing-metro 2 | const { getDefaultConfig } = require('expo/metro-config'); 3 | 4 | module.exports = getDefaultConfig(__dirname); 5 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /react-native-startup-trace/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bamlab/react-native-flipper-performance-monitor/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /flipper-desktop/jestSetup.ts: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom"; 2 | 3 | // See https://github.com/facebook/flipper/pull/3327 4 | // @ts-ignore 5 | global.electronRequire = require; 6 | require("@testing-library/react"); 7 | -------------------------------------------------------------------------------- /expo-example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .expo/ 3 | dist/ 4 | npm-debug.* 5 | *.jks 6 | *.p8 7 | *.p12 8 | *.key 9 | *.mobileprovision 10 | *.orig.* 11 | web-build/ 12 | 13 | # macOS 14 | .DS_Store 15 | android 16 | ios 17 | -------------------------------------------------------------------------------- /react-native-startup-trace/jest.setup.js: -------------------------------------------------------------------------------- 1 | import { NativeModules } from "react-native"; 2 | 3 | NativeModules.StartupPerformanceTrace = { 4 | stop: jest.fn(), 5 | }; 6 | 7 | module.exports = require("react-native-startup-trace"); 8 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /flipper-desktop/src/utils/getFPS.ts: -------------------------------------------------------------------------------- 1 | import { ThreadMeasure } from "../types/Measure"; 2 | import { round } from "./round"; 3 | 4 | export const getFPS = (measure: ThreadMeasure) => 5 | round((measure.frameCount / measure.time) * 1000, 1); 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | before_install: 3 | - cd flipper-desktop 4 | cache: 5 | directories: 6 | - ~/.npm 7 | notifications: 8 | email: false 9 | node_js: 10 | - "14" 11 | branches: 12 | except: 13 | - /^v\d+\.\d+\.\d+$/ 14 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /react-native-startup-trace/ios/StartupTrace.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /flipper-desktop/src/components/ScrollContainer.tsx: -------------------------------------------------------------------------------- 1 | import { styled } from "flipper-plugin"; 2 | 3 | export const ScrollContainer = styled("div")<{}>(() => ({ 4 | overflow: "auto", 5 | flex: "auto", 6 | flexDirection: "column", 7 | display: "flex", 8 | })); 9 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /example/ios/example/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /flipper-desktop/src/types/Measure.ts: -------------------------------------------------------------------------------- 1 | export interface Measure extends ThreadMeasure { 2 | thread: "UI" | "JS"; 3 | } 4 | 5 | export interface ThreadMeasure { 6 | frameCount: number; 7 | time: number; 8 | } 9 | 10 | export type ThreadType = "UI" | "JS"; 11 | -------------------------------------------------------------------------------- /flipper-native/tsconfig.json: -------------------------------------------------------------------------------- 1 | // @generated by expo-module-scripts 2 | { 3 | "extends": "expo-module-scripts/tsconfig.base", 4 | "compilerOptions": { 5 | "outDir": "./build" 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["**/__mocks__/*", "**/__tests__/*"] 9 | } 10 | -------------------------------------------------------------------------------- /flipper-native/plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "expo-module-scripts/tsconfig.plugin", 3 | "compilerOptions": { 4 | "outDir": "build", 5 | "rootDir": "src" 6 | }, 7 | "include": [ 8 | "./src" 9 | ], 10 | "exclude": [ 11 | "**/__mocks__/*", 12 | "**/__tests__/*" 13 | ] 14 | } -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | # Define the library name here. 4 | project(example_appmodules) 5 | 6 | # This file includes all the necessary to let you build your application with the New Architecture. 7 | include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake) 8 | -------------------------------------------------------------------------------- /expo-example/index.js: -------------------------------------------------------------------------------- 1 | import { registerRootComponent } from 'expo'; 2 | 3 | import App from './App'; 4 | 5 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App); 6 | // It also ensures that whether you load the app in Expo Go or in a native build, 7 | // the environment is set up appropriately 8 | registerRootComponent(App); 9 | -------------------------------------------------------------------------------- /example/__tests__/App-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /flipper-desktop/src/components/Title.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Typography } from "@material-ui/core"; 3 | 4 | export const Title = () => ( 5 | 10 | Performance 11 | 12 | ); 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /expo-example/eas.json: -------------------------------------------------------------------------------- 1 | { 2 | "cli": { 3 | "version": ">= 2.6.0" 4 | }, 5 | "build": { 6 | "development": { 7 | "developmentClient": true, 8 | "distribution": "internal" 9 | }, 10 | "preview": { 11 | "distribution": "internal" 12 | }, 13 | "production": {} 14 | }, 15 | "submit": { 16 | "production": {} 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /flipper-native/index.js: -------------------------------------------------------------------------------- 1 | import { NativeModules } from "react-native"; 2 | 3 | function fibonacci(n) { 4 | return n < 1 ? 0 : n <= 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); 5 | } 6 | 7 | export const killJSThread = (intensity) => fibonacci(intensity); 8 | 9 | export const killUIThread = (intensity) => 10 | NativeModules.FlipperPerformancePlugin.killUIThread(intensity); 11 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: true, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /flipper-native/ios/FlipperPerformancePlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #if __has_include() 4 | #import 5 | #import 6 | 7 | @interface FlipperPerformancePlugin : NSObject 8 | 9 | @end 10 | 11 | #else 12 | @interface FlipperPerformancePlugin : NSObject 13 | 14 | @end 15 | #endif 16 | -------------------------------------------------------------------------------- /flipper-desktop/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | testRegex: "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$", 7 | testPathIgnorePatterns: ["\\.snap$", "/node_modules/"], 8 | testEnvironment: "jsdom", 9 | setupFilesAfterEnv: ["/jestSetup.ts"], 10 | }; 11 | -------------------------------------------------------------------------------- /flipper-desktop/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "module": "ES6", 5 | "jsx": "react", 6 | "sourceMap": true, 7 | "noEmit": true, 8 | "strict": true, 9 | "moduleResolution": "node", 10 | "esModuleInterop": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "skipLibCheck": true 13 | }, 14 | "files": ["src/index.tsx"] 15 | } 16 | -------------------------------------------------------------------------------- /flipper-native/ios/FBDefines/FBDefines.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #ifndef FB_SK_MACROS_H 9 | #define FB_SK_MACROS_H 10 | #define FB_LINK_REQUIRE_(NAME) 11 | #define FB_LINKABLE(NAME) 12 | #define FB_LINK_REQUIRE_CATEGORY(NAME) 13 | #endif 14 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationModuleProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | std::shared_ptr MainApplicationModuleProvider( 12 | const std::string &moduleName, 13 | const JavaTurboModule::InitParams ¶ms); 14 | 15 | } // namespace react 16 | } // namespace facebook 17 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/OnLoad.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "MainApplicationTurboModuleManagerDelegate.h" 3 | #include "MainComponentsRegistry.h" 4 | 5 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { 6 | return facebook::jni::initialize(vm, [] { 7 | facebook::react::MainApplicationTurboModuleManagerDelegate:: 8 | registerNatives(); 9 | facebook::react::MainComponentsRegistry::registerNatives(); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /flipper-desktop/src/utils/sanitizeData.ts: -------------------------------------------------------------------------------- 1 | import { ThreadMeasure } from "../types/Measure"; 2 | 3 | export const sanitizeData = ({ frameCount, time }: ThreadMeasure) => { 4 | if (frameCount > (60 * time) / 1000) { 5 | return { 6 | frameCount: (60 * time) / 1000, 7 | time, 8 | }; 9 | } 10 | 11 | if (frameCount < 0) { 12 | return { 13 | frameCount: 0, 14 | time, 15 | }; 16 | } 17 | 18 | return { 19 | frameCount, 20 | time, 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /flipper-desktop/src/utils/getTotalTimeAndFrames.ts: -------------------------------------------------------------------------------- 1 | import { ThreadMeasure } from "../types/Measure"; 2 | 3 | export const getTotalTimeAndFrames = ( 4 | measures: ThreadMeasure[] 5 | ): ThreadMeasure => { 6 | if (measures.length === 0) { 7 | return { frameCount: 0, time: 0 }; 8 | } 9 | 10 | return measures.reduce((current, measure) => { 11 | return { 12 | time: current.time + measure.time, 13 | frameCount: current.frameCount + measure.frameCount, 14 | }; 15 | }); 16 | }; 17 | -------------------------------------------------------------------------------- /example/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /react-native-startup-trace/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { NativeModules } from 'react-native'; 3 | 4 | const { StartupTrace } = NativeModules; 5 | 6 | const stopStartupTrace = () => NativeModules.StartupPerformanceTrace.stop(); 7 | 8 | const useStopStartupTrace = () => { 9 | React.useEffect(() => { 10 | /** 11 | * Applying a timeout to make sure we wait for JS to be responsive 12 | */ 13 | const traceTimeout = setTimeout(stopStartupTrace); 14 | 15 | return () => { 16 | clearTimeout(traceTimeout); 17 | }; 18 | }, []); 19 | }; 20 | 21 | export { useStopStartupTrace }; 22 | -------------------------------------------------------------------------------- /react-native-startup-trace/ios/StartupTrace.h: -------------------------------------------------------------------------------- 1 | // Created by react-native-create-bridge 2 | 3 | // import RCTBridgeModule 4 | #if __has_include() 5 | #import 6 | #elif __has_include(“RCTBridgeModule.h”) 7 | #import “RCTBridgeModule.h” 8 | #else 9 | #import “React/RCTBridgeModule.h” // Required when used as a Pod in a Swift project 10 | #endif 11 | 12 | #import 13 | 14 | @interface StartupPerformanceTrace : NSObject 15 | 16 | @property (class, nonatomic, assign, readonly) FIRTrace* startupTrace; 17 | + (void)start; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /react-native-startup-trace/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # node.js 6 | # 7 | node_modules/ 8 | npm-debug.log 9 | yarn-error.log 10 | 11 | # Xcode 12 | # 13 | build/ 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata 23 | *.xccheckout 24 | *.moved-aside 25 | DerivedData 26 | *.hmap 27 | *.ipa 28 | *.xcuserstate 29 | project.xcworkspace 30 | 31 | # Android/IntelliJ 32 | # 33 | build/ 34 | .idea 35 | .gradle 36 | local.properties 37 | *.iml 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'example' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/react-native-gradle-plugin') 5 | 6 | if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") { 7 | include(":ReactAndroid") 8 | project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid') 9 | include(":ReactAndroid:hermes-engine") 10 | project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine') 11 | } 12 | -------------------------------------------------------------------------------- /example/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /react-native-startup-trace/android/README.md: -------------------------------------------------------------------------------- 1 | README 2 | ====== 3 | 4 | If you want to publish the lib as a maven dependency, follow these steps before publishing a new version to npm: 5 | 6 | 1. Be sure to have the Android [SDK](https://developer.android.com/studio/index.html) and [NDK](https://developer.android.com/ndk/guides/index.html) installed 7 | 2. Be sure to have a `local.properties` file in this folder that points to the Android SDK and NDK 8 | ``` 9 | ndk.dir=/Users/{username}/Library/Android/sdk/ndk-bundle 10 | sdk.dir=/Users/{username}/Library/Android/sdk 11 | ``` 12 | 3. Delete the `maven` folder 13 | 4. Run `./gradlew installArchives` 14 | 5. Verify that latest set of generated files is in the maven folder with the correct version number 15 | -------------------------------------------------------------------------------- /flipper-desktop/src/components/StartButton.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button } from "@material-ui/core"; 3 | import { PlayArrow, Stop } from "@material-ui/icons"; 4 | 5 | export const StartButton = ({ 6 | isMeasuring, 7 | start, 8 | stop, 9 | }: { 10 | isMeasuring: boolean; 11 | start: () => void; 12 | stop: () => void; 13 | }) => 14 | isMeasuring ? ( 15 | 23 | ) : ( 24 | 32 | ); 33 | -------------------------------------------------------------------------------- /expo-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-example", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "start": "expo start --dev-client", 6 | "android": "expo run:android", 7 | "ios": "expo run:ios", 8 | "web": "expo start --web" 9 | }, 10 | "dependencies": { 11 | "expo": "~46.0.16", 12 | "expo-community-flipper": "^46.0.2", 13 | "expo-dev-client": "~1.3.1", 14 | "expo-splash-screen": "~0.16.2", 15 | "expo-status-bar": "~1.4.0", 16 | "react": "18.0.0", 17 | "react-dom": "18.0.0", 18 | "react-native": "0.69.6", 19 | "react-native-flipper": "^0.173.0", 20 | "react-native-flipper-performance-plugin": "0.4.0-rc.0", 21 | "react-native-web": "~0.18.7" 22 | }, 23 | "devDependencies": { 24 | "@babel/core": "^7.12.9" 25 | }, 26 | "private": true 27 | } 28 | -------------------------------------------------------------------------------- /example/ios/exampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /flipper-desktop/src/components/Table.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import MaterialTable from "@material-ui/core/Table"; 3 | import TableBody from "@material-ui/core/TableBody"; 4 | import TableCell from "@material-ui/core/TableCell"; 5 | import TableRow from "@material-ui/core/TableRow"; 6 | 7 | export const Table = ({ 8 | rows, 9 | }: { 10 | rows: { title: string; value: string | number }[]; 11 | }) => { 12 | return ( 13 | 14 | 15 | {rows.map(({ title, value }) => ( 16 | 17 | 18 | {title} 19 | 20 | {value} 21 | 22 | ))} 23 | 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint ." 11 | }, 12 | "dependencies": { 13 | "react": "18.1.0", 14 | "react-native": "0.70.3" 15 | }, 16 | "devDependencies": { 17 | "@babel/core": "^7.12.9", 18 | "@babel/runtime": "^7.12.5", 19 | "@react-native-community/eslint-config": "^2.0.0", 20 | "babel-jest": "^26.6.3", 21 | "eslint": "^7.32.0", 22 | "jest": "^26.6.3", 23 | "metro-react-native-babel-preset": "0.72.3", 24 | "react-native-flipper-performance-plugin": "0.4.0", 25 | "react-test-renderer": "18.1.0" 26 | }, 27 | "jest": { 28 | "preset": "react-native" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /react-native-startup-trace/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-startup-trace", 3 | "title": "React Native Startup Trace", 4 | "version": "0.5.0", 5 | "description": "Measure RN app startup trace with Firebase performance", 6 | "main": "index.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/bamlab/react-native-performance.git", 10 | "directory": "react-native-startup-trace" 11 | }, 12 | "keywords": [ 13 | "react-native" 14 | ], 15 | "author": { 16 | "name": "Almouro", 17 | "email": "alexandrem@bam.tech" 18 | }, 19 | "license": "MIT", 20 | "licenseFilename": "LICENSE", 21 | "readmeFilename": "README.md", 22 | "peerDependencies": { 23 | "react": "^16.8.1", 24 | "react-native": ">=0.60.0-rc.0 <1.0.x" 25 | }, 26 | "devDependencies": { 27 | "react": "^16.9.0", 28 | "react-native": ">=0.64.2" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /flipper-native/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-flipper-performance-plugin", 3 | "version": "0.4.0-rc.0", 4 | "description": "Native side of flipper-rn-perf-monitor plugin", 5 | "repository": "https://github.com/bamlab/react-native-performance", 6 | "author": "almouro (https://github.com/Almouro)", 7 | "license": "MIT", 8 | "bugs": { 9 | "url": "https://github.com/bamlab/react-native-performance/issues" 10 | }, 11 | "homepage": "https://github.com/bamlab/react-native-performance#readme", 12 | "sideEffects": false, 13 | "scripts": { 14 | "build": "expo-module build", 15 | "clean": "expo-module clean", 16 | "test": "expo-module test", 17 | "prepare": "expo-module prepare", 18 | "prepublishOnly": "expo-module prepublishOnly", 19 | "expo-module": "expo-module" 20 | }, 21 | "devDependencies": { 22 | "expo-module-scripts": "^2.0.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /flipper-native/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .classpath 35 | .cxx 36 | .gradle 37 | .idea 38 | .project 39 | .settings 40 | local.properties 41 | android.iml 42 | 43 | # Cocoapods 44 | # 45 | example/ios/Pods 46 | 47 | # node.js 48 | # 49 | node_modules/ 50 | npm-debug.log 51 | yarn-debug.log 52 | yarn-error.log 53 | 54 | # BUCK 55 | buck-out/ 56 | \.buckd/ 57 | android/app/libs 58 | android/keystores/debug.keystore 59 | 60 | # Expo 61 | .expo/* 62 | 63 | # generated by bob 64 | lib/ 65 | -------------------------------------------------------------------------------- /react-native-startup-trace/android/src/main/java/tech/bam/rnperformance/startuptrace/StartupTracePackage.java: -------------------------------------------------------------------------------- 1 | // Created by react-native-create-bridge 2 | 3 | package tech.bam.rnperformance.startuptrace; 4 | 5 | import com.facebook.react.ReactPackage; 6 | import com.facebook.react.bridge.NativeModule; 7 | import com.facebook.react.bridge.ReactApplicationContext; 8 | import com.facebook.react.uimanager.ViewManager; 9 | 10 | import java.util.Arrays; 11 | import java.util.List; 12 | 13 | public class StartupTracePackage implements ReactPackage { 14 | @Override 15 | public List createNativeModules(ReactApplicationContext reactContext) { 16 | return Arrays.asList( 17 | new StartupTraceModule(reactContext) 18 | ); 19 | } 20 | 21 | 22 | public List createViewManagers(ReactApplicationContext reactContext) { 23 | return Arrays.asList(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /flipper-native/android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | def safeExtGet(prop, fallback) { 4 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 5 | } 6 | 7 | android { 8 | compileSdkVersion safeExtGet('compileSdkVersion', 30) 9 | buildToolsVersion safeExtGet('buildToolsVersion', '30.0.2') 10 | 11 | defaultConfig { 12 | minSdkVersion safeExtGet('minSdkVersion', 16) 13 | targetSdkVersion safeExtGet('targetSdkVersion', 30) 14 | versionCode 1 15 | versionName "1.0" 16 | } 17 | compileOptions { 18 | sourceCompatibility JavaVersion.VERSION_1_8 19 | targetCompatibility JavaVersion.VERSION_1_8 20 | } 21 | } 22 | 23 | dependencies { 24 | debugCompileOnly 'com.facebook.flipper:flipper:0.125.0' 25 | //noinspection GradleDynamicVersion 26 | implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}" 27 | } 28 | -------------------------------------------------------------------------------- /flipper-desktop/src/openMigrationDialog.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Dialog } from "flipper-plugin"; 3 | 4 | const MIGRATION_LINK = 5 | "https://github.com/bamlab/react-native-performance#install-androidios-plugin"; 6 | 7 | export const openMigrationDialog = () => 8 | Dialog.show({ 9 | defaultValue: false, 10 | children: () => ( 11 |
12 | This version of the Performance Android plugin is now deprecated. 13 |
14 |
15 | Please migrate to the new native plugin, 16 | which features: 17 |
    18 |
  • • iOS support 🎉
  • 19 |
  • • easier installation
  • 20 |
  • • more accurate reporting
  • 21 |
22 |
23 | ), 24 | title: "Migrate to new plugin", 25 | okText: "See how to migrate", 26 | onConfirm: () => require("electron").shell.openExternal(MIGRATION_LINK), 27 | }); 28 | -------------------------------------------------------------------------------- /react-native-startup-trace/react-native-startup-trace.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = "react-native-startup-trace" 7 | s.version = package["version"] 8 | s.summary = package["description"] 9 | s.description = <<-DESC 10 | react-native-startup-trace 11 | DESC 12 | s.homepage = "https://github.com/bamlab/react-native-performance" 13 | # brief license entry: 14 | s.license = "MIT" 15 | # optional - use expanded license entry instead: 16 | # s.license = { :type => "MIT", :file => "LICENSE" } 17 | s.authors = { "Almouro" => "alexandrem@bam.tech" } 18 | s.platforms = { :ios => "9.0" } 19 | s.source = { :git => "https://github.com/github_account/react-native-startup-trace.git", :tag => "#{s.version}" } 20 | 21 | s.source_files = "ios/**/*.{h,c,m,swift}" 22 | s.requires_arc = true 23 | 24 | s.dependency "React-Core" 25 | s.dependency "FirebasePerformance" 26 | end 27 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainComponentsRegistry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | class MainComponentsRegistry 12 | : public facebook::jni::HybridClass { 13 | public: 14 | // Adapt it to the package you used for your Java class. 15 | constexpr static auto kJavaDescriptor = 16 | "Lcom/example/newarchitecture/components/MainComponentsRegistry;"; 17 | 18 | static void registerNatives(); 19 | 20 | MainComponentsRegistry(ComponentFactory *delegate); 21 | 22 | private: 23 | static std::shared_ptr 24 | sharedProviderRegistry(); 25 | 26 | static jni::local_ref initHybrid( 27 | jni::alias_ref, 28 | ComponentFactory *delegate); 29 | }; 30 | 31 | } // namespace react 32 | } // namespace facebook 33 | -------------------------------------------------------------------------------- /flipper-native/android/src/main/java/tech/bam/rnperformance/flipper/FlipperPerformancePluginPackage.java: -------------------------------------------------------------------------------- 1 | package tech.bam.rnperformance.flipper; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.facebook.react.ReactPackage; 6 | import com.facebook.react.bridge.NativeModule; 7 | import com.facebook.react.bridge.ReactApplicationContext; 8 | import com.facebook.react.uimanager.ViewManager; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class FlipperPerformancePluginPackage implements ReactPackage { 15 | @NonNull 16 | @Override 17 | public List createNativeModules(@NonNull ReactApplicationContext reactContext) { 18 | List modules = new ArrayList<>(); 19 | modules.add(new FlipperPerformancePluginModule(reactContext)); 20 | return modules; 21 | } 22 | 23 | @NonNull 24 | @Override 25 | public List createViewManagers(@NonNull ReactApplicationContext reactContext) { 26 | return Collections.emptyList(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /flipper-desktop/src/components/CircularProgressWithLabel.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import CircularProgress from "@material-ui/core/CircularProgress"; 3 | import Typography from "@material-ui/core/Typography"; 4 | import Box from "@material-ui/core/Box"; 5 | 6 | export const CircularProgressWithLabel = ({ 7 | color, 8 | ...props 9 | }: { 10 | color: string; 11 | size: number; 12 | value: number; 13 | }) => { 14 | return ( 15 | 16 | 17 | 27 | {`${Math.round(props.value)}`} 33 | 34 | 35 | ); 36 | }; 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Alexandre Moureaux 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationModuleProvider.cpp: -------------------------------------------------------------------------------- 1 | #include "MainApplicationModuleProvider.h" 2 | 3 | #include 4 | #include 5 | 6 | namespace facebook { 7 | namespace react { 8 | 9 | std::shared_ptr MainApplicationModuleProvider( 10 | const std::string &moduleName, 11 | const JavaTurboModule::InitParams ¶ms) { 12 | // Here you can provide your own module provider for TurboModules coming from 13 | // either your application or from external libraries. The approach to follow 14 | // is similar to the following (for a library called `samplelibrary`: 15 | // 16 | // auto module = samplelibrary_ModuleProvider(moduleName, params); 17 | // if (module != nullptr) { 18 | // return module; 19 | // } 20 | // return rncore_ModuleProvider(moduleName, params); 21 | 22 | // Module providers autolinked by RN CLI 23 | auto rncli_module = rncli_ModuleProvider(moduleName, params); 24 | if (rncli_module != nullptr) { 25 | return rncli_module; 26 | } 27 | 28 | return rncore_ModuleProvider(moduleName, params); 29 | } 30 | 31 | } // namespace react 32 | } // namespace facebook 33 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | 35 | # node.js 36 | # 37 | node_modules/ 38 | npm-debug.log 39 | yarn-error.log 40 | 41 | # BUCK 42 | buck-out/ 43 | \.buckd/ 44 | *.keystore 45 | !debug.keystore 46 | 47 | # fastlane 48 | # 49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 50 | # screenshots whenever they are needed. 51 | # For more information about the recommended setup visit: 52 | # https://docs.fastlane.tools/best-practices/source-control/ 53 | 54 | **/fastlane/report.xml 55 | **/fastlane/Preview.html 56 | **/fastlane/screenshots 57 | **/fastlane/test_output 58 | 59 | # Bundle artifact 60 | *.jsbundle 61 | 62 | # Ruby / CocoaPods 63 | /ios/Pods/ 64 | /vendor/bundle/ 65 | -------------------------------------------------------------------------------- /react-native-startup-trace/android/src/main/java/tech/bam/rnperformance/startuptrace/StartupTraceModule.java: -------------------------------------------------------------------------------- 1 | package tech.bam.rnperformance.startuptrace; 2 | 3 | import com.facebook.react.bridge.ReactApplicationContext; 4 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 5 | import com.facebook.react.bridge.ReactMethod; 6 | import com.google.firebase.perf.FirebasePerformance; 7 | import com.google.firebase.perf.metrics.Trace; 8 | 9 | import javax.annotation.Nonnull; 10 | 11 | public class StartupTraceModule extends ReactContextBaseJavaModule { 12 | private static final String REACT_CLASS = "StartupPerformanceTrace"; 13 | private static Trace startupTrace = null; 14 | 15 | StartupTraceModule(ReactApplicationContext context) { 16 | super(context); 17 | } 18 | 19 | @Override 20 | @Nonnull 21 | public String getName() { 22 | return REACT_CLASS; 23 | } 24 | 25 | public static void start() { 26 | startupTrace = FirebasePerformance.getInstance().newTrace("STARTUP_JS"); 27 | startupTrace.start(); 28 | } 29 | 30 | @ReactMethod 31 | public void stop() { 32 | if (startupTrace != null) { 33 | startupTrace.stop(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /expo-example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "expo-example", 4 | "slug": "expo-example", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "userInterfaceStyle": "light", 9 | "splash": { 10 | "image": "./assets/splash.png", 11 | "resizeMode": "contain", 12 | "backgroundColor": "#ffffff" 13 | }, 14 | "updates": { 15 | "fallbackToCacheTimeout": 0 16 | }, 17 | "assetBundlePatterns": [ 18 | "**/*" 19 | ], 20 | "ios": { 21 | "supportsTablet": true, 22 | "bundleIdentifier": "com.almouro.expoexample" 23 | }, 24 | "android": { 25 | "adaptiveIcon": { 26 | "foregroundImage": "./assets/adaptive-icon.png", 27 | "backgroundColor": "#FFFFFF" 28 | }, 29 | "package": "com.almouro.expoexample" 30 | }, 31 | "web": { 32 | "favicon": "./assets/favicon.png" 33 | }, 34 | "extra": { 35 | "eas": { 36 | "projectId": "03cf08d6-d843-40ca-9033-343a7fd51364" 37 | } 38 | }, 39 | "plugins": [ 40 | [ 41 | "expo-community-flipper" 42 | ], 43 | [ 44 | "react-native-flipper-performance-plugin" 45 | ] 46 | ] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | namespace facebook { 8 | namespace react { 9 | 10 | class MainApplicationTurboModuleManagerDelegate 11 | : public jni::HybridClass< 12 | MainApplicationTurboModuleManagerDelegate, 13 | TurboModuleManagerDelegate> { 14 | public: 15 | // Adapt it to the package you used for your Java class. 16 | static constexpr auto kJavaDescriptor = 17 | "Lcom/example/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;"; 18 | 19 | static jni::local_ref initHybrid(jni::alias_ref); 20 | 21 | static void registerNatives(); 22 | 23 | std::shared_ptr getTurboModule( 24 | const std::string &name, 25 | const std::shared_ptr &jsInvoker) override; 26 | std::shared_ptr getTurboModule( 27 | const std::string &name, 28 | const JavaTurboModule::InitParams ¶ms) override; 29 | 30 | /** 31 | * Test-only method. Allows user to verify whether a TurboModule can be 32 | * created by instances of this class. 33 | */ 34 | bool canCreateTurboModule(const std::string &name); 35 | }; 36 | 37 | } // namespace react 38 | } // namespace facebook 39 | -------------------------------------------------------------------------------- /react-native-startup-trace/ios/StartupTrace.m: -------------------------------------------------------------------------------- 1 | // Created by react-native-create-bridge 2 | 3 | #import "StartupTrace.h" 4 | 5 | // import RCTBridge 6 | #if __has_include() 7 | #import 8 | #elif __has_include(“RCTBridge.h”) 9 | #import “RCTBridge.h” 10 | #else 11 | #import “React/RCTBridge.h” // Required when used as a Pod in a Swift project 12 | #endif 13 | 14 | // import RCTEventDispatcher 15 | #if __has_include() 16 | #import 17 | #elif __has_include(“RCTEventDispatcher.h”) 18 | #import “RCTEventDispatcher.h” 19 | #else 20 | #import “React/RCTEventDispatcher.h” // Required when used as a Pod in a Swift project 21 | #endif 22 | 23 | @implementation StartupPerformanceTrace 24 | @synthesize bridge = _bridge; 25 | 26 | static FIRTrace *_startupTrace = nil; 27 | 28 | + (FIRTrace *)startupTrace { 29 | return _startupTrace; 30 | } 31 | 32 | RCT_EXPORT_MODULE(); 33 | 34 | + (void)start { 35 | _startupTrace = [[FIRPerformance sharedInstance] traceWithName:@"STARTUP_JS"]; 36 | [_startupTrace start]; 37 | } 38 | 39 | RCT_EXPORT_METHOD(stop) 40 | { 41 | if (_startupTrace) { 42 | [_startupTrace stop]; 43 | } 44 | } 45 | 46 | - (dispatch_queue_t)methodQueue 47 | { 48 | return dispatch_get_main_queue(); 49 | } 50 | 51 | + (BOOL)requiresMainQueueSetup { return YES; } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/newarchitecture/components/MainComponentsRegistry.java: -------------------------------------------------------------------------------- 1 | package com.example.newarchitecture.components; 2 | 3 | import com.facebook.jni.HybridData; 4 | import com.facebook.proguard.annotations.DoNotStrip; 5 | import com.facebook.react.fabric.ComponentFactory; 6 | import com.facebook.soloader.SoLoader; 7 | 8 | /** 9 | * Class responsible to load the custom Fabric Components. This class has native methods and needs a 10 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/ 11 | * folder for you). 12 | * 13 | *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the 14 | * `newArchEnabled` property). Is ignored otherwise. 15 | */ 16 | @DoNotStrip 17 | public class MainComponentsRegistry { 18 | static { 19 | SoLoader.loadLibrary("fabricjni"); 20 | } 21 | 22 | @DoNotStrip private final HybridData mHybridData; 23 | 24 | @DoNotStrip 25 | private native HybridData initHybrid(ComponentFactory componentFactory); 26 | 27 | @DoNotStrip 28 | private MainComponentsRegistry(ComponentFactory componentFactory) { 29 | mHybridData = initHybrid(componentFactory); 30 | } 31 | 32 | @DoNotStrip 33 | public static MainComponentsRegistry register(ComponentFactory componentFactory) { 34 | return new MainComponentsRegistry(componentFactory); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /flipper-native/android/src/main/java/tech/bam/rnperformance/flipper/FlipperPerformancePluginModule.java: -------------------------------------------------------------------------------- 1 | package tech.bam.rnperformance.flipper; 2 | 3 | import android.os.Handler; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.facebook.react.bridge.Promise; 8 | import com.facebook.react.bridge.ReactApplicationContext; 9 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 10 | import com.facebook.react.bridge.ReactMethod; 11 | import com.facebook.react.module.annotations.ReactModule; 12 | 13 | @ReactModule(name = FlipperPerformancePluginModule.NAME) 14 | public class FlipperPerformancePluginModule extends ReactContextBaseJavaModule { 15 | public static final String NAME = "FlipperPerformancePlugin"; 16 | 17 | public FlipperPerformancePluginModule(ReactApplicationContext reactContext) { 18 | super(reactContext); 19 | } 20 | 21 | @Override 22 | @NonNull 23 | public String getName() { 24 | return NAME; 25 | } 26 | 27 | @ReactMethod 28 | public void killUIThread(int intensity, Promise promise) { 29 | final Handler mainHandler = new Handler(getReactApplicationContext().getMainLooper()); 30 | mainHandler.post(() -> promise.resolve(fibonacci(intensity))); 31 | } 32 | 33 | private int fibonacci(int n) { 34 | return n < 1 ? 0 : n <= 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /expo-example/App.js: -------------------------------------------------------------------------------- 1 | import { SafeAreaView, Text, TouchableOpacity, View } from "react-native"; 2 | 3 | import { 4 | killJSThread, 5 | killUIThread, 6 | } from "react-native-flipper-performance-plugin"; 7 | 8 | const Button = ({ title, onPress, style, testID }) => ( 9 | 22 | {title} 23 | 24 | ); 25 | 26 | const App = () => { 27 | return ( 28 | 29 | 38 |