Skip to content

Conversation

Ujaa
Copy link

@Ujaa Ujaa commented Aug 10, 2025

Summary

This change addresses the concerns raised in #89, where it was noted that the min/max values in the performance stats were not particularly meaningful for understanding the overall performance. The issue discussion suggested that using an accumulated average (acc) value would be more useful — this PR implements that idea. Now, each panel shows the accumulated average alongside the current reading.

Additionally, in the original stats.js, the MS metric was computed from the time between begin() and end() calls. However, in our case, these calls wrapped almost no logic, which often resulted in near-zero.
To fix this, I removed the dependency on begin()/end() and updated the system so that stats are driven entirely by external updates in profiler.js. The MS value is now calculated as the average frame delta (msAvg) over the past second, using the elapsed time between animation frames to ensure it reflects actual rendering performance.

Screenshots

before

Screenshot 2025-08-10 at 10 41 14 PM

after

Screenshot 2025-08-10 at 10 43 33 PM
Screen.Recording.2025-08-10.at.10.41.31.PM.mov

Related

Copy link

vercel bot commented Aug 10, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
thorvg-perf-test ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 10, 2025 1:53pm

@Ujaa Ujaa changed the title feat: add enhanced profiler and custom stats with average tracking perf-test: add enhanced profiler and custom stats with average tracking Aug 10, 2025
@tinyjin tinyjin requested review from Copilot and tinyjin August 10, 2025 15:29
@tinyjin tinyjin added the enhancement Improve features label Aug 10, 2025
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements an enhanced performance profiler with accumulated average tracking and external-driven stats, addressing concerns in #89 about the meaningfulness of min/max values in performance statistics. The key improvements focus on providing more useful performance metrics through accumulated averages and proper frame timing calculations.

  • Enhanced stats panels to show accumulated averages alongside current readings
  • Refactored timing measurement to use actual frame deltas instead of begin/end wrapper calls
  • Added collapsible profiler UI with modern styling and positioning

Reviewed Changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
perf-test/public/stats.js Complete rewrite of stats library with accumulated average tracking and enhanced display formatting
perf-test/public/profiler.js New external-driven profiler implementation with collapsible UI and proper frame timing
perf-test/app/page.tsx Code formatting changes and profiler integration updates
Comments suppressed due to low confidence (1)

if (Number.isFinite(value)) {
min = Math.min(min, value);
max = Math.max(max, value);
acc = acc == null ? value : (acc + value) / 2;
Copy link

Copilot AI Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The accumulated average calculation (acc + value) / 2 is incorrect for a true average. This formula gives equal weight to all previous values combined versus the current value, rather than calculating a proper running average. Consider using a running average formula like acc = (acc * count + value) / (count + 1) or an exponentially weighted moving average.

Suggested change
acc = acc == null ? value : (acc + value) / 2;
sum += value;
count += 1;
acc = sum / count;

Copilot uses AI. Check for mistakes.

} = options;

const Stats = await getStatsCtor();
if (!Stats) throw new Error("Stats constructor not found.");
Copy link

Copilot AI Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If getStatsCtor() returns undefined or null, the error message 'Stats constructor not found.' is not very helpful for debugging. Consider providing more specific error information about what was attempted (e.g., 'Failed to load Stats from /stats.js and window.Stats is undefined').

Suggested change
if (!Stats) throw new Error("Stats constructor not found.");
if (!Stats) {
// Try to provide more context for debugging
let statsModule, windowStats;
try {
statsModule = await import("/stats.js");
} catch (e) {
statsModule = undefined;
}
windowStats = typeof window !== "undefined" ? window.Stats : undefined;
throw new Error(
"Failed to load Stats constructor: " +
`/stats.js import result: ${statsModule ? "found" : "not found"}, ` +
`window.Stats: ${windowStats ? "found" : "undefined/null"}`
);
}

Copilot uses AI. Check for mistakes.

}, 150);
};

if (typeof window === "undefined") return <div>1</div>;
Copy link

Copilot AI Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback return value <div>1</div> is a magic value that provides no meaningful information. Consider returning a more descriptive placeholder like <div>Loading...</div> or null for server-side rendering scenarios.

Suggested change
if (typeof window === "undefined") return <div>1</div>;
if (typeof window === "undefined") return <div>Loading...</div>;

Copilot uses AI. Check for mistakes.

@hermet hermet added the perf-test Performance Test label Aug 11, 2025
@hermet
Copy link
Member

hermet commented Aug 11, 2025

@Ujaa Thanks for contribution, one feedback. There is no need to add "acc" additional line, we can just display with like this:

for example:

before:
FPS: CUR (Min - Max)

after:
FPS : CUR (ACC) //where CUR is current fps value and ACC is the average value.

@Ujaa
Copy link
Author

Ujaa commented Aug 11, 2025

Thank you for the feedback
I will apply it and update the code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public is where external scripts/assets are located at. I suggest that the code we maintain remain internal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improve features perf-test Performance Test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants