Skip to content

Commit a32a625

Browse files
JacksonGLfacebook-github-bot
authored andcommitted
doc(lens): update lens README and tutorial
Summary: This diff updates the MemLens package README file. Differential Revision: D80422996 fbshipit-source-id: e15e40732d4009b5341244f8061918b12c71ee4d
1 parent 8a7c026 commit a32a625

File tree

3 files changed

+139
-40
lines changed

3 files changed

+139
-40
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ memlab.run({scenario});
190190

191191
## Visual Debugging for Memory Leaks in Browser
192192

193-
Check out this [tutorial page](https://facebook.github.io/memlab/docs/guides/visually-debug-memory-leaks-with-memlens)
193+
Please check out this [tutorial page](https://facebook.github.io/memlab/docs/guides/visually-debug-memory-leaks-with-memlens)
194194
on how to use MemLens (a debugging utility) to
195195
visualize memory leaks in the browser for easier memory debugging.
196196

packages/lens/README.md

Lines changed: 136 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,161 @@
11
# MemLens
22

3-
## What is this?
3+
MemLens is a lightweight, in-browser lens for spotting memory issues in React apps. It detects and visualizes:
44

5-
MemLens is a debugging tool that helps identify memory leaks in React applications. It tracks:
5+
- Detached DOM elements still retained in memory
6+
- Unmounted React Fiber nodes that may indicate leaks
7+
- Event listener leaks (optional)
8+
- High-level DOM and heap usage stats (overlay header)
69

7-
- Detached DOM elements that are no longer connected to the document but still held in memory
8-
- Unmounted React Fiber nodes that haven't been properly cleaned up
9-
- Memory usage patterns and growth over time
10+
It can run as a one-line console snippet or as a small library you embed in dev builds.
1011

11-
The tool provides:
12+
### Key features
1213

13-
1. Real-time memory monitoring through the browser console
14-
2. Visual representation of problematic DOM elements and React components
15-
3. Memory usage statistics and trends
14+
- **Visual overlay**: Highlights detached DOM elements; interactive panel shows counts and the React component stack for the selected element
15+
- **React Fiber analysis**: Scans the fiber tree to attribute elements to components
16+
- **Event listener leak scan (opt-in)**: Groups leaked listeners by component and type
17+
- **Non-intrusive**: Uses a transparent overlay and avoids tracking its own UI
1618

17-
This can help developers identify:
18-
- Components that aren't properly cleaned up
19+
### Browser support
1920

20-
## How to Build?
21+
- Requires browsers with WeakRef/FinalizationRegistry support (e.g. modern Chrome, Edge, Safari, Firefox). In older browsers the tool may not function.
22+
23+
---
24+
25+
### Quick start
26+
27+
#### Option A: Run from the browser console (CDN)
28+
29+
Paste this in your app page:
30+
31+
```js
32+
(() => {
33+
const s = document.createElement('script');
34+
s.src = 'https://unpkg.com/@memlab/lens/dist/memlens.run.bundle.min.js';
35+
s.crossOrigin = 'anonymous';
36+
document.head.appendChild(s);
37+
})();
38+
```
39+
40+
This injects and starts MemLens with the interactive overlay.
41+
42+
#### Option B: Run from the browser console (local build)
43+
44+
Copy the contents of `packages/lens/dist/memlens.run.bundle.min.js` (or `packages/lens/dist/memlens.run.bundle.js`) and paste into the browser's web console. The overlay starts immediately.
45+
46+
#### Option C: Programmatic scanner (UMD global)
47+
48+
Load the library bundle and use the `MemLens` global:
49+
50+
```html
51+
<script src="https://unpkg.com/@memlab/lens/dist/memlens.lib.bundle.min.js"></script>
52+
<script>
53+
// Create a scanner (no overlay by default; use the run bundle for overlay)
54+
const scan = MemLens.createReactMemoryScan({
55+
isDevMode: true,
56+
scanIntervalMs: 1000,
57+
trackEventListenerLeaks: true, // optional
58+
});
59+
60+
const unsubscribe = scan.subscribe((result) => {
61+
console.log('[MemLens]', {
62+
totalElements: result.totalElements,
63+
detached: result.totalDetachedElements,
64+
eventListenerLeaks: result.eventListenerLeaks,
65+
});
66+
});
67+
68+
scan.start();
69+
70+
// Later: scan.stop(); unsubscribe(); scan.dispose();
71+
</script>
72+
```
73+
74+
Note: The visualization overlay is provided by the self-starting "run" bundle (Option A/B/D). The library bundle focuses on scanning APIs.
75+
76+
#### Option D: Node/Puppeteer injection
77+
78+
`@memlab/lens` exposes a helper to retrieve the self-starting bundle as a string for script injection:
79+
80+
```js
81+
// Node
82+
const {getBundleContent} = require('@memlab/lens');
83+
84+
// Puppeteer example
85+
await page.addScriptTag({content: getBundleContent()});
86+
```
87+
88+
---
89+
90+
### Overlay controls and interactions
91+
92+
- **Toggle switch**: Show/hide all overlay rectangles
93+
- **Select/pin**: Click a rectangle to pin/unpin the current selection
94+
- **Hover**: Reveal the selection chain of related detached elements
95+
- **Component stack panel**: Shows the React component stack of the selected element
96+
- **Keyboard**: Press `D` to temporarily ignore the currently selected element in the overlay
97+
- **Widget**: The control widget is draggable
98+
99+
Notes:
100+
- The overlay ignores its own UI elements and won’t count them as part of the page.
101+
- In dev mode, MemLens logs basic timing and scan stats to the console.
102+
103+
---
104+
105+
### Configuration (CreateOptions)
106+
107+
```ts
108+
type CreateOptions = {
109+
isDevMode?: boolean; // enable console logs and dev-only behaviors
110+
subscribers?: Array<(r) => void>; // observers of each scan result
111+
extensions?: Array<BasicExtension>; // e.g., DOMVisualizationExtension
112+
scanIntervalMs?: number; // default ~1000ms
113+
trackEventListenerLeaks?: boolean; // enable listener leak scanning
114+
};
115+
```
116+
117+
Core API (`ReactMemoryScan`):
118+
- `start()`, `pause()`, `stop()`, `dispose()`
119+
- `subscribe(cb) => () => void`
120+
- `registerExtension(ext) => () => void`
121+
122+
---
123+
124+
### Build
21125

22126
```bash
127+
# from packages/lens
128+
npm run build
129+
# or
23130
webpack
24131
```
25132

26-
## How to Test?
133+
### Test
27134

28-
1. Install Playwright
135+
1) Install Playwright dependencies (first time):
29136

30137
```bash
31138
npx playwright install
32139
npx playwright install-deps
33140
```
34141

35-
2. Run the test
142+
2) Run tests:
36143

37144
```bash
38145
npm run test:e2e
39146
```
40147

41-
3. Test manually by copying and pasting the content of `dist/run.bundle.js`
42-
into web console
43-
44-
45-
## TODO List
46-
* Note that document.querySelectorAll('*') only captures DOM elements on the DOM tree
47-
* So the DOM tree scanning and component name analysis must be done in a frequent interval (every 10s or so)
48-
* Extensible framework for tracking additional metadata
49-
* Auto diffing and counting detached Element and unmounted Fiber nodes
50-
* being able to summarize the leaked components that was not reported (this can reduce the report overhead)
51-
* Improve the DOM visualizer - only visualize the common ancestors of the detached DOM elements and unmounted fiber nodes
52-
* Improving the scanning efficiency so that the overhead is minimal in production environment
53-
* Improve the fiber tree traversal efficiency (there are redundant traversals right now)
54-
* Not only keep track of detached DOM elements, but also keep track of unmounted fiber nodes in WeakMap and WeakSet
55-
* DOM visualizer is leaking canvas DOM elements after each scan
56-
* Monitor event listener leaks?
57-
* Real-time memory usage graphs
58-
* Real-time component count and other react memory scan obtained stats graphs
59-
* Component re-render heat maps
60-
* Interactive component tree navigation
61-
* Browser extension integration
62-
* centralized config file
63-
* centralized exception handling
148+
3) Manual test: open `src/tests/manual/todo-list/todo-with-run.bundle.html` in a browser, or copy/paste `dist/memlens.run.bundle.js` to the DevTools console on any React page.
149+
150+
---
151+
152+
### Learn more
153+
154+
Please check out this
155+
[tutorial page](https://facebook.github.io/memlab/docs/guides/visually-debug-memory-leaks-with-memlens)
156+
on how to use MemLens (a debugging utility) to visualize memory leaks in the
157+
browser for easier memory debugging.
158+
159+
### License
160+
161+
MIT © Meta Platforms, Inc.

website/docs/guides/06-visually-debug-leaks-with-memlens.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ id: 'visually-debug-memory-leaks-with-memlens'
55
# Visual Debugging for Memory Leaks
66

77
Memory Lens (MemLens) is a utility tool that helps visually debug memory leaks
8-
in web browsers. It highlights leaking components with an overlay,
8+
in web browsers. It highlights detached DOM elements still retained in memory
9+
and leaking React components with an overlay,
910
allowing you to identify leaked elements right after interactions and
1011
trace their retainer paths in the browser’s DevTools using memory IDs
1112
annotated by MemLens.

0 commit comments

Comments
 (0)