Skip to content

Commit 33e38ee

Browse files
committed
add snippets
1 parent 6915811 commit 33e38ee

File tree

9 files changed

+189
-257
lines changed

9 files changed

+189
-257
lines changed

docs/docs/docs/instrumentation-react/__common-directive.mdx

Lines changed: 0 additions & 14 deletions
This file was deleted.

docs/docs/docs/instrumentation-react/class-components.mdx

Lines changed: 0 additions & 86 deletions
This file was deleted.

docs/docs/docs/instrumentation-react/function-components.mdx

Lines changed: 0 additions & 76 deletions
This file was deleted.

docs/docs/docs/instrumentation-react/hooks.mdx

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# Ottrelite Instrumentation for React
2+
3+
Ottrelite Instrumentation for React provides two main ways to add performance tracing to your React applications:
4+
5+
1. **React Hooks API** - Manual instrumentation using React hooks like `useComponentRenderTracing`
6+
2. **Babel Plugin** - Automatic instrumentation using the `"use trace"` directive
7+
8+
:::note
9+
If you're using a recent version of React Native, consider using [React Performance Tracks](/docs/introduction#react-native-devtools) instead.
10+
11+
React Performance Tracks offer significantly more features compared to Ottrelite's basic render time tracking, including:
12+
13+
- **Scheduler tracking** with 4 priority levels (Blocking, Transition, Suspense, Idle)
14+
- **Detailed render phases** (Update, Render, Commit, Effects) with flamegraph visualization
15+
- **Cascading update detection** to identify performance regressions
16+
- **Component-level insights** with render and effect durations
17+
- **Props change inspection** to identify unnecessary renders
18+
- **Integration with browser DevTools** alongside network requests, JavaScript execution, and event loop activity
19+
20+
Ottrelite serves as an alternative solution for those who haven't upgraded to the latest React Native version yet.
21+
:::
22+
23+
## Installation
24+
25+
First, ensure you are already using `@ottrelite/core`. Then, add this package:
26+
27+
```bash
28+
npm install @ottrelite/instrumentation-react
29+
```
30+
31+
## Features
32+
33+
### React Hooks API
34+
35+
The React API provides hooks that allow you to manually instrument your components. The main hook is `useComponentRenderTracing`, which traces a component's render lifecycle.
36+
37+
#### `useComponentRenderTracing`
38+
39+
This hook traces a component's render lifecycle (i.e., any - first or subsequent - render).
40+
41+
```typescript
42+
function MyComponent() {
43+
const { markJSRenderEnd } = useComponentRenderTracing("MyComponent");
44+
45+
// Your component logic here...
46+
47+
const contents = <View>{/* ... */}</View>;
48+
49+
markJSRenderEnd();
50+
51+
return contents;
52+
}
53+
```
54+
55+
The hook **must** be called first in the component to mark the JS logic start time undelayed. Any components you render & return **must** first be stored in a variable, and returned **after** calling the hook's returned `markJSRenderEnd` function.
56+
57+
:::important
58+
The traced span starts after the JS render logic finishes and ends after the component is rendered to the tree. Additionally, the JS render execution time is measured and reported as a `jsLogicDuration` attribute within the span.
59+
:::
60+
61+
### Babel Plugin for Automatic Instrumentation
62+
63+
The Babel plugin automatically instruments React components and hooks using the `"use trace"` directive. This provides a convenient way to add tracing without manually calling hooks.
64+
65+
#### Setting up the Babel Plugin
66+
67+
Add the plugin to your Babel configuration. If you are using a `babel.config.js` file:
68+
69+
```javascript
70+
module.exports = {
71+
...,
72+
plugins: ['module:@ottrelite/instrumentation-react'],
73+
...
74+
};
75+
```
76+
77+
#### Using the "use trace" Directive
78+
79+
Add the `"use trace"` directive as the first line in functions you want to instrument:
80+
81+
- **Function components**: First line of the component function body
82+
- **Class components**: First line of the `render` method body
83+
- **Hooks**: First line of the hook function body
84+
85+
The directive schema is `"use trace [API] [Name]"` where:
86+
87+
- `[API]` (default: `dev`) - Either `dev` (Ottrelite Development API) or `otel` (OpenTelemetry JS SDK)
88+
- `[Name]` (optional) - Custom name for the tracer; if not provided, the function/component name is used
89+
90+
#### Functions
91+
92+
```typescript
93+
export function MyFunction() {
94+
"use trace";
95+
// Your logic here
96+
});
97+
```
98+
99+
#### Function Components
100+
101+
```typescript
102+
import { memo } from 'react';
103+
104+
export const MyComponent = memo(function MyComponent() {
105+
"use trace";
106+
107+
// Your component logic here
108+
109+
return <div>Hello World</div>;
110+
});
111+
```
112+
113+
:::note
114+
As seen in the examples above, the components are wrapped in `memo` to prevent unnecessary re-renders. This is a common practice in React to optimize performance, but it is not compulsory - the instrumentation would still work without it. However, in such case, it would be expected that most likely the instrumentation would produce many entries, for invocations of the component which didn't actually result in an update to the shadow tree.
115+
:::
116+
117+
When using `memo()`, you must either:
118+
1. Use a named function: `memo(function MyComponent() { ... })`
119+
2. Provide an explicit name: `"use trace dev MyComponent"`
120+
121+
:::important
122+
Anonymous functions without explicit names will result in an error.
123+
:::
124+
125+
#### Class Components
126+
127+
```typescript
128+
import { Component } from 'react';
129+
130+
export class MyClassComponent extends Component {
131+
render() {
132+
'use trace';
133+
134+
// Your render logic here
135+
136+
return <div>Hello World</div>;
137+
}
138+
139+
shouldComponentUpdate(nextProps, nextState, nextContext) {
140+
// only rerender if props, state, or context have changed
141+
return (
142+
!_.isEqual(this.props, nextProps) ||
143+
!_.isEqual(this.state, nextState) ||
144+
!_.isEqual(this.context, nextContext)
145+
);
146+
}
147+
}
148+
```
149+
150+
:::note
151+
As seen in the example above, the component includes an explicit implementation of `shouldComponentUpdate` to prevent unnecessary re-renders. This is a common practice in React to optimize performance, but it is not compulsory - the instrumentation would still work without it. However, in such case, it would be expected that most likely the instrumentation would produce many entries, for invocations of the component which didn't actually result in an update to the shadow tree.
152+
:::
153+
154+
#### Tracer Name Resolution
155+
156+
The tracer name is determined in the following priority order:
157+
158+
| Declaration style / context | Name |
159+
| --------------------------------------------------- | ---------------------------------------- |
160+
| Explicit name from the string after `"use trace"` | The passed string |
161+
| component with `displayName` or `name` | `displayName` or `name` property |
162+
| named function/class | Name of the function/class |
163+
| arrow function | Name of the assignment target identifier |
164+
| anonymous function/class | Name of the assignment target identifier |
165+
166+
Both `[API]` and `[Name]` parameters are optional. The shortest form is `"use trace"` which is equivalent to `"use trace dev <resolved component name>"`.
167+
168+
:::tip
169+
If you pass only one parameter, it will be treated as `[API]` first; if the value doesn't match the API options, it will be treated as the `[Name]` parameter.
170+
:::
171+
172+
:::tip
173+
Components wrapped in `memo()` or class components with `shouldComponentUpdate` are recommended to prevent unnecessary re-renders and reduce noise in tracing data.
174+
:::

docs/docs/docs/instrumentation-react/quick-start.mdx

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)