Skip to content

[Hackathon] Benchmark GHA#21222

Open
mnajdova wants to merge 108 commits intomui:masterfrom
mnajdova:hackathon/gh-action-master-performance
Open

[Hackathon] Benchmark GHA#21222
mnajdova wants to merge 108 commits intomui:masterfrom
mnajdova:hackathon/gh-action-master-performance

Conversation

@mnajdova
Copy link
Copy Markdown
Member

@mnajdova mnajdova commented Feb 4, 2026

Based on top of #21220

@mnajdova mnajdova added scope: code-infra Involves the code-infra product (https://www.notion.so/mui-org/5562c14178aa42af97bc1fa5114000cd). type: new feature Expand the scope of the product to solve a new problem. labels Feb 4, 2026
@mui-bot
Copy link
Copy Markdown

mui-bot commented Feb 4, 2026

Deploy preview: https://deploy-preview-21222--material-ui-x.netlify.app/

Bundle size report

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)

Details of bundle changes

Generated by 🚫 dangerJS against c41ee72

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Feb 9, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 9, 2026

This pull request has conflicts, please resolve those before we can evaluate the pull request.

Copy link
Copy Markdown
Contributor

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 pull request adds a comprehensive benchmark tool and GitHub Actions workflows for performance testing of MUI X components. The implementation includes a Next.js-based benchmark application using Playwright for automated testing, along with CI/CD workflows to track and compare performance metrics over time.

Changes:

  • Added benchmark tool infrastructure with Next.js app, Playwright tests, and React Profiler integration
  • Implemented GitHub Actions workflows for running benchmarks on PRs and storing baseline data
  • Created CI scripts for comparing benchmark results and generating performance reports

Reviewed changes

Copilot reviewed 37 out of 38 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
.github/workflows/benchmark-comparison.yml Workflow for comparing PR benchmarks against master baseline
.github/workflows/benchmark-baseline.yml Workflow for storing baseline benchmark data on master branch
test/benchmark-tool/utils/* Utility functions for profiling, reporting, and page navigation
test/benchmark-tool/ci-scripts/* Scripts for fetching, comparing, and reporting benchmark data
test/benchmark-tool/app/**/* Benchmark test pages and tests for various components
test/benchmark-tool/*.{json,ts} Configuration files for Next.js, Playwright, and TypeScript
pnpm-lock.yaml Dependency updates including Playwright version bump
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +12 to +16
pull_request_target:
types:
- opened
- synchronize
- reopened
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The workflow uses pull_request_target which runs in the context of the base repository with write permissions. This is a security risk because it could allow untrusted code from a PR to access secrets and write to the repository. Consider using only pull_request or implement proper security measures.

Suggested change
pull_request_target:
types:
- opened
- synchronize
- reopened

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This worries me. I think we should move to the pull_request + workflow_run pattern. pull_request executes bench and stores artifact, low permissions. Workflow_run gathers artifacts and posts PR comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shouldn't it be pull_request_target if we want it to have write access to a branch in the main repo? Else it will only have access to the users branch, which is not how our contribution model works

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why does it need write access to a branch in the main repo? It should execute the benchmark and stores the results as an artefact.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I got confused, this is for master, then it shouldn't need pull_request nor pull_request_target as it should run on push to master only.

I'm inclined to store master's results in an orphan branch on this repo

This comment wouldn't work when using pull_request only

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's only for pull_requests, master branch is handled by the push action

  • push (only on master): run benchmarks, store in orphan branch
  • pull_request (only onPRs`): run benchmark, store in artefact
  • workflow_run (when PR workflow finishes): download artefact + master result for merge-base, compare, post PR comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah ok, got it

Comment on lines +8 to +9
const contentsResponse = await fetch(
'https://api.github.com/repos/mnajdova/performance-benchmark-data/contents/mui-x',
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The URL is hardcoded to a personal GitHub repository 'mnajdova/performance-benchmark-data'. For production use, this should be configurable via environment variables or point to an official organization repository to avoid dependency on a personal account.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

To avoid external repos and keeping the process self-contained, I'm inclined to store master's results in an orphan branch on this repo. PR results could live as GHA artefacts with 90 day retention.


function onRender(id: string, phase: 'mount' | 'update' | 'nested-update', actualDuration: number) {
const startTime = performance.now() - actualDuration;
(window as any)[CAPTURE_RENDER_FN]?.({
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

Using (window as any) bypasses TypeScript's type safety. Consider defining a proper type for the window object with the custom property, or at least check if the function exists before calling it to avoid potential runtime errors if the function isn't exposed yet.

Copilot uses AI. Check for mistakes.
const pageState = new WeakMap<Page, PageState>();

export function getRouteFromFilename(filename: string): string {
return path.dirname(filename).split('/app').pop()!;
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The non-null assertion operator (!) is used on line 15 with .pop()! which assumes that the split will always produce at least one element. If the filename doesn't contain '/app', this will return undefined and cause a runtime error. Consider adding validation or a more robust path extraction method.

Copilot uses AI. Check for mistakes.
// Enable React profiling in production builds
reactProductionProfiling: true,
productionBrowserSourceMaps: true,
experimental: {
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The configuration disables Turbopack minification with turbopackMinify: false. While this may be intentional for benchmarking purposes to get consistent results, consider adding a comment explaining why minification is disabled, as it's unusual for production configurations.

Suggested change
experimental: {
experimental: {
// Disable Turbopack minification to keep benchmark results consistent and easier to analyze.

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +13
pull_request_target:
types:
- opened
- synchronize
- reopened
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The workflow uses pull_request_target which runs in the context of the base repository with write permissions. This is a security risk because it could allow untrusted code from a PR to access secrets and write to the repository. The workflow should either use only pull_request (which runs in a restricted context) or implement proper security measures to prevent malicious PRs from exploiting the write permissions.

Suggested change
pull_request_target:
types:
- opened
- synchronize
- reopened

Copilot uses AI. Check for mistakes.
Comment on lines +84 to +87
console.warn(
`High coefficient of variation (${(coefficientOfVariation * 100).toFixed(1)}%) for event "${getEventKey(event)}". ` +
`Mean: ${meanDuration.toFixed(2)}ms, StdDev: ${stdDev.toFixed(2)}ms. Results may be unreliable.`,
);
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The warning uses console.warn which will be visible in the output, but on line 19 console.log is disabled via eslint comment while console.warn is not. For consistency, either allow both or suppress both console methods depending on the intended behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +91 to +92
# Extract just the repository name (after the /)
REPO_DIR=$(echo "$REPO_NAME" | cut -d'/' -f2)
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

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

The comment on line 91 says "Extract just the repository name (after the /)" but then uses it to create a directory. This assumes the repository name doesn't contain characters that could cause issues in directory names. Consider sanitizing the repository name to ensure it's safe for use in file paths.

Copilot uses AI. Check for mistakes.
@Janpot Janpot changed the title [Hackaton] Benchmark GHA [Hackathon] Benchmark GHA Feb 16, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Jan Potoms <2109932+Janpot@users.noreply.github.com>

const latestFolder = folders[0];

console.warn(`Using latest benchmark folder: ${latestFolder}`);
Copy link
Copy Markdown
Member

@Janpot Janpot Feb 17, 2026

Choose a reason for hiding this comment

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

Using latest benchmark from master is incorrect. it's a moving target. You may be comparing with different commits at different points in time. Instead you should calculate the merge-base with the master branch and use that commit for comparison.

Therefore you must store data by commit. I'm changing data layout to

# store results by commit
benchmarks/commits/{SHA}.json
# append only, store the same results in jsonl, batched per month
benchmarks/monthly/{YYYY-MM}.jsonl

@JCQuintas
Copy link
Copy Markdown
Member

Just a note that we deliberately cut corners, so this is not really in a review state

@Janpot
Copy link
Copy Markdown
Member

Janpot commented Feb 18, 2026

I was asked to take this to the finish line. Just documenting the changes I'm making.

@JCQuintas
Copy link
Copy Markdown
Member

I was asked to take this to the finish line. Just documenting the changes I'm making.

Nvm then. From what you wrote it seemed you were just reviewing it.

@github-actions
Copy link
Copy Markdown
Contributor

This pull request has been inactive for 30 days. Please remove the stale label or leave a comment to keep it open. Otherwise, it will be closed in 15 days.

@github-actions github-actions bot added the stale Inactive for 7 days (issues) or 30 days (PRs); closed after 5 or 15 more days if no update. label Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: out-of-date The pull request has merge conflicts and can't be merged. scope: code-infra Involves the code-infra product (https://www.notion.so/mui-org/5562c14178aa42af97bc1fa5114000cd). stale Inactive for 7 days (issues) or 30 days (PRs); closed after 5 or 15 more days if no update. type: new feature Expand the scope of the product to solve a new problem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants