diff --git a/docs/profile-hermes.md b/docs/profile-hermes.md
new file mode 100644
index 00000000000..3f4daefb478
--- /dev/null
+++ b/docs/profile-hermes.md
@@ -0,0 +1,155 @@
+---
+id: profile-hermes
+title: Profiling with Hermes
+---
+
+You can visualize JavaScript's performance in a React Native app using [Hermes](https://github.com/facebook/hermes). Hermes is a small and lightweight JavaScript engine optimized for running React Native on Android (you can [read more about using it with React Native here](hermes). Hermes helps improve app performance and also exposes ways to analyze the performance of the JavaScript that it runs.
+
+In this section, you will learn how to profile your React Native app running on Hermes and how to visualize the profile using [the Performance tab on Chrome DevTools](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/reference)
+
+> Be sure to [enable hermes in your app](hermes) before you get started!
+
+Follow the instructions below to get started profiling:
+
+1. [Record a Hermes sampling profile](profile-hermes.md#record-a-hermes-sampling-profile)
+2. [Execute command from CLI](profile-hermes.md#execute-command-from-cli)
+3. [Open the downloaded profile on Chrome DevTools](profile-hermes.md#open-the-downloaded-profile-on-chrome-devtools)
+
+## Record a Hermes sampling profile
+
+To record a sampling profiler from the Developer Menu:
+
+1. Navigate to your running Metro server terminal.
+2. Press `d` to open the **Developer Menu.**
+3. Select **Enable Sampling Profiler.**
+4. Execute your JavaScript by in your app (press buttons, etc.)
+5. Open the **Developer Menu** by pressing `d` again.
+6. Select **Disable Sampling Profiler** to stop recording and save the sampling profiler.
+
+A toast will show the location where the sampling profiler has been saved, usually in `/data/user/0/com.appName/cache/*.cpuprofile`
+
+
+
+## Execute command from CLI
+
+You can use the [React Native CLI](https://github.com/react-native-community/cli) to convert the Hermes tracing profile to Chrome tracing profile, and then pull it to your local machine using:
+
+```sh
+npx react-native profile-hermes [destinationDir]
+```
+
+### Enabling source map
+
+A source map is used to enhance the profile and associate trace events with the application code. You can automatically generate a source map when converting the Hermes tracing profile to a Chrome tracing profile by enabling `bundleInDebug` if the app is running in development mode. This allows React Native to build the bundle during its running process. Here's how:
+
+1. In your app's `android/app/build.gradle` file, add:
+
+```java
+project.ext.react = [
+ bundleInDebug: true,
+]
+```
+
+> Be sure to clean the build whenever you make any changes to `build.gradle`
+
+2. Clean the build by running:
+
+```sh
+cd android && ./gradlew clean
+```
+
+3. Run your app:
+
+```sh
+npx react-native run-android
+```
+
+### Common errors
+
+#### `adb: no devices/emulators found` or `adb: device offline`
+
+- **Why this happens** The CLI cannot access the device or emulator (through adb) you are using to run the app.
+- **How to fix** Make sure your Android device/emulator is connected and running. The command only works when it can access adb.
+
+#### `There is no file in the cache/ directory`
+
+- **Why this happens** The CLI cannot find any **.cpuprofile** file in your app's **cache/** directory. You might have forgotten to record a profile from the device.
+- **How to fix** Follow the [instructions](profile-hermes.md#record-a-hermes-sampling-profile) to enable/disable profiler from device.
+
+#### `Error: your_profile_name.cpuprofile is an empty file`
+
+- **Why this happens** The profile is empty, it might be because Hermes is not running correctly.
+- **How to fix** Make sure your app is running on the latest version of Hermes.
+
+## Open the downloaded profile in Chrome DevTools
+
+To open the profile in Chrome DevTools:
+
+1. Open Chrome DevTools.
+2. Select the **Performance** tab.
+3. Right click and choose **Load profile...**
+
+
+
+## How does the Hermes Profile Transformer work?
+
+The Hermes Sample Profile is of the `JSON object format`, while the format that Google's DevTools supports is `JSON Array Format`. (More information about the formats can be found on the [Trace Event Format Document](https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview))
+
+```ts
+export interface HermesCPUProfile {
+ traceEvents: SharedEventProperties[];
+ samples: HermesSample[];
+ stackFrames: { [key in string]: HermesStackFrame };
+}
+```
+
+The Hermes profile has most of its information encoded into the `samples` and `stackFrames` properties. Each sample is a snapshot of the function call stack at that particular timestamp as each sample has a `sf` property which corresponds to a function call.
+
+```ts
+export interface HermesSample {
+ cpu: string;
+ name: string;
+ ts: string;
+ pid: number;
+ tid: string;
+ weight: string;
+ /**
+ * Will refer to an element in the stackFrames object of the Hermes Profile
+ */
+ sf: number;
+ stackFrameData?: HermesStackFrame;
+}
+```
+
+The information about a function call can be found in `stackFrames` which contains key-object pairs, where the key is the `sf` number and the corresponding object gives us all the relevant information about the function including the `sf` number of its parent function. This parent-child relationship can be traced upwards to find the information of all the functions running at a particular timestamp.
+
+```ts
+export interface HermesStackFrame {
+ line: string;
+ column: string;
+ funcLine: string;
+ funcColumn: string;
+ name: string;
+ category: string;
+ /**
+ * A parent function may or may not exist
+ */
+ parent?: number;
+}
+```
+
+At this point, you should define a few more terms, namely:
+
+1. Nodes: The objects corresponding to `sf` numbers in `stackFrames`
+2. Active Nodes: The nodes which are currently running at a particular timestamp. A node is classified as running if its `sf` number is in the function call stack. This call stack can be obtained from the `sf` number of the sample and tracing upwards till parent `sf`s are available
+
+The `samples` and the `stackFrames` in tandem can then be used to generate all the start and end events at the corresponding timestamps, wherein:
+
+1. Start Nodes/Events: Nodes absent in the previous sample's function call stack but present in the current sample's.
+2. End Nodes/Events: Nodes present in the previous sample's function call stack but absent in the current sample's.
+
+
+
+You can now construct a `flamechart` of function calls as you have all the function information including its start and end timestamps.
+
+The `hermes-profile-transformer` can convert any profile generated using Hermes into a format that can be directly displayed in Chrome DevTools. More information about this can be found on [ `@react-native-community/hermes-profile-transformer` ](https://github.com/react-native-community/hermes-profile-transformer)
diff --git a/website/i18n/en.json b/website/i18n/en.json
index 7bd5d1aaa5c..ae7e9f4f12e 100644
--- a/website/i18n/en.json
+++ b/website/i18n/en.json
@@ -272,6 +272,9 @@
"pressevent": {
"title": "PressEvent Object Type"
},
+ "profile-hermes": {
+ "title": "Profiling with Hermes"
+ },
"profiling": {
"title": "Profiling"
},
@@ -284,6 +287,9 @@
"props": {
"title": "Props"
},
+ "publishing-to-app-store": {
+ "title": "Publishing to Apple App Store"
+ },
"pushnotificationios": {
"title": "🚧 PushNotificationIOS"
},
diff --git a/website/sidebars.json b/website/sidebars.json
index 3b26a4073f3..29558f57b9e 100644
--- a/website/sidebars.json
+++ b/website/sidebars.json
@@ -39,7 +39,8 @@
"performance",
"optimizing-flatlist-configuration",
"ram-bundles-inline-requires",
- "profiling"
+ "profiling",
+ "profile-hermes"
],
"JavaScript Runtime": ["javascript-environment", "timers", "hermes"],
"Connectivity": ["network", "security"],
diff --git a/website/static/docs/assets/CallStackDemo.jpg b/website/static/docs/assets/CallStackDemo.jpg
new file mode 100644
index 00000000000..987ad8dff89
Binary files /dev/null and b/website/static/docs/assets/CallStackDemo.jpg differ
diff --git a/website/static/docs/assets/HermesProfileSaved.png b/website/static/docs/assets/HermesProfileSaved.png
new file mode 100644
index 00000000000..9213b810ac9
Binary files /dev/null and b/website/static/docs/assets/HermesProfileSaved.png differ
diff --git a/website/static/docs/assets/openChromeProfile.png b/website/static/docs/assets/openChromeProfile.png
new file mode 100644
index 00000000000..332bea045d2
Binary files /dev/null and b/website/static/docs/assets/openChromeProfile.png differ
diff --git a/website/yarn.lock b/website/yarn.lock
index 0d9429dcbb6..c7cd882335b 100644
--- a/website/yarn.lock
+++ b/website/yarn.lock
@@ -9,7 +9,7 @@
dependencies:
"@babel/highlight" "^7.0.0"
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.8.3":
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
@@ -47,7 +47,7 @@
semver "^5.4.1"
source-map "^0.5.0"
-"@babel/generator@^7.11.0", "@babel/generator@^7.8.4":
+"@babel/generator@^7.11.0":
version "7.11.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.0.tgz#4b90c78d8c12825024568cbe83ee6c9af193585c"
integrity sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==
@@ -137,7 +137,7 @@
"@babel/traverse" "^7.10.4"
"@babel/types" "^7.10.4"
-"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.8.3":
+"@babel/helper-function-name@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a"
integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==
@@ -146,7 +146,7 @@
"@babel/template" "^7.10.4"
"@babel/types" "^7.10.4"
-"@babel/helper-get-function-arity@^7.10.4", "@babel/helper-get-function-arity@^7.8.3":
+"@babel/helper-get-function-arity@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2"
integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==
@@ -242,7 +242,7 @@
dependencies:
"@babel/types" "^7.11.0"
-"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.8.3":
+"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0":
version "7.11.0"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f"
integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==
@@ -264,7 +264,7 @@
"@babel/traverse" "^7.10.4"
"@babel/types" "^7.10.4"
-"@babel/helpers@^7.10.4", "@babel/helpers@^7.8.4":
+"@babel/helpers@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044"
integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==
@@ -273,7 +273,7 @@
"@babel/traverse" "^7.10.4"
"@babel/types" "^7.10.4"
-"@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4", "@babel/highlight@^7.8.3":
+"@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143"
integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==
@@ -282,7 +282,7 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1", "@babel/parser@^7.8.3", "@babel/parser@^7.8.4":
+"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1":
version "7.11.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.3.tgz#9e1eae46738bcd08e23e867bab43e7b95299a8f9"
integrity sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==
@@ -910,7 +910,7 @@
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/template@^7.10.4", "@babel/template@^7.8.3":
+"@babel/template@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==
@@ -919,7 +919,7 @@
"@babel/parser" "^7.10.4"
"@babel/types" "^7.10.4"
-"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.8.4", "@babel/traverse@^7.9.0":
+"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.9.0":
version "7.11.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24"
integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==
@@ -934,7 +934,7 @@
globals "^11.1.0"
lodash "^4.17.19"
-"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.4.4", "@babel/types@^7.8.3", "@babel/types@^7.9.0":
+"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.4.4", "@babel/types@^7.9.0":
version "7.11.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d"
integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==
@@ -4676,7 +4676,7 @@ json5@^1.0.1:
dependencies:
minimist "^1.2.0"
-json5@^2.1.0, json5@^2.1.2:
+json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==
@@ -4957,7 +4957,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
-lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@~4.17.10:
+lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@~4.17.10:
version "4.17.19"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
@@ -6760,7 +6760,7 @@ regenerate@^1.4.0:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
-regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4:
+regenerator-runtime@^0.13.4:
version "0.13.7"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==