Skip to content

Commit

Permalink
feat(heap-analysis) React component hook memory analysis
Browse files Browse the repository at this point in the history
Summary:
This is the first iteration of a prototypical heap analysis for React components and hooks. The idea and outline of this analysis comes from the awesome tech talk by Giulio Zausa in React Berlin Day 2023.

For more technical details about how the analysis works, please check out the talk here:
https://portal.gitnation.org/contents/how-much-ram-is-your-usememo-using-lets-profile-it

To use this analysis, first take heap snapshot in Chrome DevTool and save the heap snapshot to disk (a `.heapsnapshot` file). Then use the following command to get memory stats of React components and hooks:
```
memlab analyze react-hooks --snapshot <path-to-snapshot-file>
```
This command also works for heap snapshots generated from MemLab run.

Differential Revision: D52858977

fbshipit-source-id: c4f1e072f5e770ea587e0b438a91e9a647307940
  • Loading branch information
JacksonGL authored and facebook-github-bot committed Jan 22, 2024
1 parent 2475ed1 commit ed5557f
Show file tree
Hide file tree
Showing 4 changed files with 494 additions and 4 deletions.
5 changes: 3 additions & 2 deletions packages/core/src/lib/HeapAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,13 +519,14 @@ class MemoryAnalyst {
}

public printHeapInfo(leakInfo: IOveralHeapInfo): void {
info.topLevel('Heap overall statistics:');
Object.entries(leakInfo)
.map(([k, v]) => [
utils.camelCaseToReadableString(k),
utils.camelCaseToReadableString(k, {capitalizeFirstWord: true}),
utils.getReadableBytes(v),
])
.forEach(([name, value]) => {
info.topLevel(`· ${name}: ${value}`);
info.topLevel(` ${name}: ${value}`);
});
}

Expand Down
11 changes: 9 additions & 2 deletions packages/core/src/lib/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1327,17 +1327,24 @@ async function closePuppeteer(
}
}

function camelCaseToReadableString(str: string): string {
function camelCaseToReadableString(
str: string,
options: {capitalizeFirstWord?: boolean} = {},
): string {
let ret = '';
const strToProcess = str.trim();
const isUpperCase = (c: string) => /^[A-Z]$/.test(c);
for (const c of str) {
for (const c of strToProcess) {
if (isUpperCase(c)) {
ret += ret.length > 0 ? ' ' : '';
ret += c.toLowerCase();
} else {
ret += c;
}
}
if (options.capitalizeFirstWord && ret.length > 0) {
ret = ret[0].toUpperCase() + ret.slice(1);
}
return ret;
}

Expand Down
Loading

0 comments on commit ed5557f

Please sign in to comment.