react-render-profiler 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bogdan
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.
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # React Render Profiler
2
+
3
+ A tiny profiler helper to measure initial render + rerender timings for React components.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm i react-render-profiler
9
+ ```
10
+
11
+ ## Why
12
+
13
+ Use it when you want:
14
+
15
+ - render count and rerender count per component instance
16
+ - approximate commit timing (`render start` -> `useEffect`)
17
+ - delayed aggregated reporting to keep console noise low
18
+
19
+ ## Usage (HOC)
20
+
21
+ ```tsx
22
+ import { withRenderProfiler } from 'react-render-profiler';
23
+ import { ProductCard } from './ProductCard';
24
+
25
+ export default withRenderProfiler(ProductCard, {
26
+ reportAfterMs: 5000,
27
+ logEachRender: false
28
+ });
29
+ ```
30
+
31
+ ## Actual usage patterns
32
+
33
+ ### 1) Wrap component on export (global for all usages)
34
+
35
+ ```tsx
36
+ function MenuItem(props) {
37
+ ...
38
+ }
39
+
40
+ export default withRenderProfiler(MenuItem, {
41
+ componentName: 'MenuItem',
42
+ groupByComponent: true,
43
+ enabled: process.env.NODE_ENV !== 'production',
44
+ reportAfterMs: 5000,
45
+ });
46
+ ```
47
+
48
+ ### 2) Wrap only in one place (recommended for focused profiling)
49
+
50
+ ```tsx
51
+ const FooterProfiled = withRenderProfiler(FooterWidget, {
52
+ componentName: 'HomePage:FooterWidget',
53
+ groupByComponent: true,
54
+ enabled: process.env.NODE_ENV !== 'production',
55
+ reportAfterMs: 5000,
56
+ });
57
+
58
+ // Inside ProductPage:
59
+ <RecommendationsWidgetProfiled productAlias={product.alias} />
60
+ ```
61
+
62
+ ## Measure only specific usage
63
+
64
+ For HOC usage, `enabled` can be a function of component props.
65
+ This lets you measure only specific places/instances and keep others unprofiled.
66
+
67
+ ```tsx
68
+ type CardProps = { alias: string; profileRender?: boolean };
69
+
70
+ const ProductCardProfiled = withRenderProfiler<CardProps>(ProductCard, {
71
+ componentName: 'ProductCard',
72
+ groupByComponent: true,
73
+ enabled: (props) => props.profileRender === true,
74
+ });
75
+
76
+ // Only this usage is measured:
77
+ <ProductCardProfiled alias="a" profileRender />
78
+
79
+ // This usage is ignored by profiler:
80
+ <ProductCardProfiled alias="b" />
81
+ ```
82
+
83
+ ## Usage (Hook)
84
+
85
+ ```tsx
86
+ import { useRenderProfiler } from 'react-render-profiler';
87
+
88
+ export function CheckoutSidebar() {
89
+ useRenderProfiler('CheckoutSidebar', { reportAfterMs: 3000 });
90
+ return <aside>...</aside>;
91
+ }
92
+ ```
93
+
94
+ ## API
95
+
96
+ ### `withRenderProfiler(Component, options?)`
97
+
98
+ Wraps a component and reports stats to console after inactivity timeout.
99
+
100
+ ### `useRenderProfiler(componentName, options?)`
101
+
102
+ Hook variant when you do not want to wrap export.
103
+
104
+ ### `options`
105
+
106
+ - `reportAfterMs` (default `3000`) - report debounce timeout
107
+ - `groupByComponent` (default `false`) - aggregate all instances under one component report
108
+ - `logEachRender` (default `false`) - emit log on every commit
109
+ - `enabled` (default `true`) - disable profiler globally (`boolean`) or for HOC by props (`(props) => boolean`)
110
+ - `logger` - custom logger function for integrating with your telemetry
111
+
112
+ ### Typical presets
113
+
114
+ - **Page/widget profiling**: `{ componentName, groupByComponent: true, enabled: dev, reportAfterMs: 5000 }`
115
+ - **Instance-level profiling**: `{ componentName, enabled: (props) => ..., reportAfterMs: 2000-5000 }`
116
+
117
+ ## Notes
118
+
119
+ - In React StrictMode (development), render/effect invocations can be doubled.
120
+ - This helper measures render-to-effect timing, not full browser paint time.
121
+
122
+ ## Report Fields
123
+
124
+ Each console row includes these fields:
125
+
126
+ - `label` - logger label, usually `[RenderProfiler] <ComponentName>`
127
+ - `component` - component name used for profiling/grouping
128
+ - `renders` - total committed renders counted in this profile bucket
129
+ - `initialRenders` - number of first renders for mounted instances in this bucket
130
+ - `rerenders` - number of subsequent renders (`renders - initialRenders`)
131
+ - `totalMs` - sum of measured render durations in milliseconds
132
+ - `avgMs` - average render duration (`totalMs / renders`)
133
+ - `minMs` - fastest measured render duration in milliseconds
134
+ - `maxMs` - slowest measured render duration in milliseconds
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ type LogPayload = {
3
+ component: string;
4
+ renders: number;
5
+ initialRenders: number;
6
+ rerenders: number;
7
+ totalMs: number;
8
+ avgMs: number;
9
+ minMs: number;
10
+ maxMs: number;
11
+ };
12
+ export type RenderProfilerOptions = {
13
+ componentName?: string;
14
+ groupByComponent?: boolean;
15
+ reportAfterMs?: number;
16
+ logEachRender?: boolean;
17
+ enabled?: boolean;
18
+ logger?: (label: string, payload: LogPayload) => void;
19
+ };
20
+ export type RenderProfilerHOCOptions<P> = Omit<RenderProfilerOptions, 'enabled'> & {
21
+ enabled?: boolean | ((props: P) => boolean);
22
+ };
23
+ export declare const useRenderProfiler: (componentName: string, options?: RenderProfilerOptions) => void;
24
+ export declare const withRenderProfiler: <P extends object>(WrappedComponent: React.ComponentType<P>, options?: RenderProfilerHOCOptions<P>) => React.FC<P>;
25
+ export {};
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAEjD,KAAK,UAAU,GAAG;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,wBAAwB,CAAC,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,GAAG;IACjF,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC;CAC7C,CAAC;AAyDF,eAAO,MAAM,iBAAiB,kBACb,MAAM,YACZ,qBAAqB,KAC7B,IAgEF,CAAC;AAEF,eAAO,MAAM,kBAAkB,oHAe9B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withRenderProfiler = exports.useRenderProfiler = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const defaultLogger = (label, payload) => {
7
+ // Console table keeps output readable when multiple profiled components run.
8
+ // eslint-disable-next-line no-console
9
+ console.table([{ label, ...payload }]);
10
+ };
11
+ const groupedStatsStore = new Map();
12
+ const createEmptyStats = () => ({
13
+ renders: 0,
14
+ initialRenders: 0,
15
+ rerenders: 0,
16
+ totalMs: 0,
17
+ minMs: Number.POSITIVE_INFINITY,
18
+ maxMs: 0,
19
+ timerId: null
20
+ });
21
+ const scheduleReport = (componentName, stats, reportAfterMs, logger) => {
22
+ if (stats.timerId) {
23
+ clearTimeout(stats.timerId);
24
+ }
25
+ stats.timerId = setTimeout(() => {
26
+ const avg = stats.renders > 0 ? stats.totalMs / stats.renders : 0;
27
+ const payload = {
28
+ component: componentName,
29
+ renders: stats.renders,
30
+ initialRenders: stats.initialRenders,
31
+ rerenders: stats.rerenders,
32
+ totalMs: Number(stats.totalMs.toFixed(2)),
33
+ avgMs: Number(avg.toFixed(2)),
34
+ minMs: Number((Number.isFinite(stats.minMs) ? stats.minMs : 0).toFixed(2)),
35
+ maxMs: Number(stats.maxMs.toFixed(2))
36
+ };
37
+ logger(`[RenderProfiler] ${componentName}`, payload);
38
+ }, reportAfterMs);
39
+ };
40
+ const useRenderProfiler = (componentName, options = {}) => {
41
+ const { groupByComponent = false, reportAfterMs = 3000, logEachRender = false, enabled = true, logger = defaultLogger } = options;
42
+ const renderStartRef = (0, react_1.useRef)(0);
43
+ const instanceRenderCountRef = (0, react_1.useRef)(0);
44
+ const statsRef = (0, react_1.useRef)(createEmptyStats());
45
+ if (groupByComponent && !groupedStatsStore.has(componentName)) {
46
+ groupedStatsStore.set(componentName, createEmptyStats());
47
+ }
48
+ const activeStats = groupByComponent ? groupedStatsStore.get(componentName) : statsRef.current;
49
+ if (enabled) {
50
+ const now = performance.now();
51
+ renderStartRef.current = now;
52
+ activeStats.renders += 1;
53
+ instanceRenderCountRef.current += 1;
54
+ if (instanceRenderCountRef.current === 1) {
55
+ activeStats.initialRenders += 1;
56
+ }
57
+ else {
58
+ activeStats.rerenders += 1;
59
+ }
60
+ }
61
+ (0, react_1.useEffect)(() => {
62
+ if (!enabled) {
63
+ return;
64
+ }
65
+ const end = performance.now();
66
+ const renderDuration = end - renderStartRef.current;
67
+ const stats = activeStats;
68
+ stats.totalMs += renderDuration;
69
+ stats.minMs = Math.min(stats.minMs, renderDuration);
70
+ stats.maxMs = Math.max(stats.maxMs, renderDuration);
71
+ if (logEachRender) {
72
+ logger(`[RenderProfiler] ${componentName}#${stats.renders}`, {
73
+ component: componentName,
74
+ renders: stats.renders,
75
+ initialRenders: stats.initialRenders,
76
+ rerenders: stats.rerenders,
77
+ totalMs: Number(stats.totalMs.toFixed(2)),
78
+ avgMs: Number((stats.totalMs / stats.renders).toFixed(2)),
79
+ minMs: Number(stats.minMs.toFixed(2)),
80
+ maxMs: Number(stats.maxMs.toFixed(2))
81
+ });
82
+ }
83
+ scheduleReport(componentName, stats, reportAfterMs, logger);
84
+ return () => {
85
+ if (!groupByComponent && stats.timerId) {
86
+ clearTimeout(stats.timerId);
87
+ stats.timerId = null;
88
+ }
89
+ };
90
+ }, [activeStats, componentName, enabled, groupByComponent, logEachRender, logger, reportAfterMs]);
91
+ };
92
+ exports.useRenderProfiler = useRenderProfiler;
93
+ const withRenderProfiler = (WrappedComponent, options = {}) => {
94
+ const wrappedName = options.componentName || WrappedComponent.displayName || WrappedComponent.name || 'AnonymousComponent';
95
+ const ProfiledComponent = (props) => {
96
+ const { enabled = true, ...restOptions } = options;
97
+ const resolvedEnabled = typeof enabled === 'function' ? enabled(props) : enabled;
98
+ (0, exports.useRenderProfiler)(wrappedName, { ...restOptions, enabled: resolvedEnabled });
99
+ return (0, jsx_runtime_1.jsx)(WrappedComponent, { ...props });
100
+ };
101
+ ProfiledComponent.displayName = `withRenderProfiler(${wrappedName})`;
102
+ return ProfiledComponent;
103
+ };
104
+ exports.withRenderProfiler = withRenderProfiler;
105
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "react-render-profiler",
3
+ "version": "0.1.0",
4
+ "description": "Lightweight React render and rerender profiler",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "build:watch": "tsc -w",
10
+ "test": "jest",
11
+ "prepublishOnly": "npm run build",
12
+ "lint": "eslint --ext .ts --ext .tsx ."
13
+ },
14
+ "author": "Bohdan Surai",
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/bsurai/react-render-profiler.git"
19
+ },
20
+ "homepage": "https://github.com/bsurai/react-render-profiler#readme",
21
+ "bugs": {
22
+ "url": "https://github.com/bsurai/react-render-profiler/issues"
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
29
+ "keywords": [
30
+ "react",
31
+ "performance",
32
+ "profiler",
33
+ "render",
34
+ "rerender"
35
+ ],
36
+ "peerDependencies": {
37
+ "react": ">=16.8.0"
38
+ },
39
+ "devDependencies": {
40
+ "@testing-library/jest-dom": "^6.9.1",
41
+ "@testing-library/react": "^16.3.2",
42
+ "@types/jest": "^30.0.0",
43
+ "@types/node": "^18.19.130",
44
+ "@types/react": "^19.2.2",
45
+ "jest": "^30.3.0",
46
+ "jest-environment-jsdom": "^30.3.0",
47
+ "react-dom": "^19.2.5",
48
+ "ts-jest": "^29.4.9",
49
+ "typescript": "4.9.5"
50
+ }
51
+ }