Fixes #30898: enforce frontend performance patterns - #30874
Conversation
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically. Maintainers can bypass this check by adding the |
|
Hi there 👋 Thanks for your contribution! The OpenMetadata team will review the PR shortly! Once it has been labeled as Let us know if you need any help! |
✅ Playwright Results — workflow succeededValidated commit ✅ 680 passed · ❌ 0 failed · 🟡 1 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky PerformanceBlocking targets: ✅ met · Optimization targets: 🟡 in progress Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting. 🕒 Full workflow signal wall (to summary) 50m 51s ⏱️ Max setup 3m 10s · max shard execution 17m 49s · max shard-job elapsed before upload 21m 15s · reporting 5s 🌐 191.08 requests/attempt · 2.37 app boots/UI scenario · 6.64% common-shard skew Optimization targets still in progress:
🟡 1 flaky test(s) (passed on retry)
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
|
|
Confirmed both fixes in the latest push.
No further action needed here. |
Code Review ✅ Approved 5 resolved / 5 findingsEnforces frontend performance patterns by adding blocking ESLint rules for route code-splitting, suspense fallbacks, and bounded caches, while clearing existing violations. Resolved issues include scope-aware suspense boundary checks, causal cache eviction validation, member-expression rendering support, and duplicate license headers. ✅ 5 resolved✅ Quality: require-suspense-fallback exempts whole file on one Suspense
✅ Quality: Cache size-guard and eviction checks are not causally linked
✅ Edge Case: Suspense rule ignores JSX member-expression rendering
✅ Quality: review-sequential-api-calls flags mutually exclusive awaits
✅ Quality: Duplicate Apache license header in new rule file
OptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar | Powered by Gitar — free for open source |
|



Fixes #30898
Describe your changes:
This PR converts the recent frontend performance practices into explicit ESLint policy. It adds three repository-specific, reporting-only rules, clears every existing violation, and enables all three at
errorseverity so regressions block local lint and UI Checkstyle immediately.Enforcement levels
error.warn.Severity is based on measured repository backlog rather than preference. A rule is promoted from
warntoerroronly after its backlog reaches zero and a full-tree scan confirms that it can block without failing unrelated files.Mandatory performance rules added by this PR
1.
openmetadata-performance/no-eager-page-importserror— mandatory and blocking.src/components/AppRouter/**/*.{ts,tsx}only.importwhose source path containspages/.import type ...declarations;lazy();lazy()and expose it throughwithPageSuspenseFallback()or another approved route fallback path.Example rejected pattern:
Example accepted pattern:
2.
openmetadata-performance/require-suspense-fallbackerror— mandatory and blocking.lazyimports fromreact;React.lazythrough a React default or namespace import.lazy()call is passed directly towithSuspenseFallbackorwithPageSuspenseFallbackimported from a module ending in/withSuspenseFallback;<Suspense fallback={...}>boundary.<Suspense>without an explicitfallbackprop;3.
openmetadata-performance/no-unbounded-module-cacheerror— mandatory and blocking.new Map()/new Set()bindings whose identifier containscacheormemo, case-insensitively..sizeusing>,>=, or the equivalent reversed</<=form;MAX_CACHE_SIZE;.delete(...)or.clear()on that same resolved binding inside the matchingifbranch orwhilebody.maxEntries, which does not establish an explicit repository constant.Map/Setinstances and module-level collections without cache-like names, because they are not module-lifetime cache candidates for this heuristic.Advisory performance rules — enabled but not mandatory yet
These existing React rules remain at
warnbecause the repository still has measured violations. This PR documents their current backlog but does not promote them to blocking:react-hooks/exhaustive-depsreact/no-array-index-keyreact/jsx-no-constructed-context-valuesreact/no-unstable-nested-componentsThese warnings are visible in editors and CI output. They become mandatory only after their backlog is fixed and re-measured at zero.
Advisory import architecture and request rules
This PR also adds ten reporting-only OpenMetadata rules at
warn. They are visible on changed filesbut do not fail UI Checkstyle while the measured backlog is reduced. None of them autofix source.
openmetadata-imports/no-impure-pure-utilsopenmetadata-imports/no-lower-layer-page-importsopenmetadata-imports/no-cross-page-importsopenmetadata-imports/no-rest-ui-importsopenmetadata-imports/no-hook-ui-importsopenmetadata-imports/no-circular-importsopenmetadata-imports/no-internal-barrel-importsopenmetadata-imports/no-lodash-default-importopenmetadata-imports/no-api-calls-in-iterationopenmetadata-imports/review-sequential-api-callsif/else,switch, andtry/catchbranches are excluded.Where warnings appear in CI
For pull requests, the
ui-checkstyleworkflow posts or updates a sticky GitHub Actions commenttitled UI Checkstyle passed — lint findings in changed files. It groups findings by rule and
includes the changed file, line, column, and message. The same warnings appear in
Actions → UI Checkstyle → checkstyle → ESLint + Prettier + Organise Imports (src). Warnings do
not fail the check; ESLint errors or formatter-generated diffs still block it.
The deterministic rules can move to
errorafter their full-tree baseline reaches zero. Thesequential-request review rule must be re-evaluated separately because static analysis cannot prove
request independence.
Additional validation
live cycle-cache invalidation, and runtime barrel detection.
make ui-checkstyle-changed; warning output remained non-blocking and the check completedsuccessfully.
Rule intentionally not enabled
react/jsx-no-useless-fragmentremains disabled. The rule auto-fixes source files, while UI Checkstyle runs ESLint with--fixand then rejects any generated diff. It can be enabled only after a dedicated repository-wide autofix commit removes the backlog.Autofix policy
The three new OpenMetadata performance rules intentionally have no autofix. Choosing the correct loading boundary, eviction policy, cache limit, or eager-versus-lazy route dependency requires runtime context. ESLint reports the violation, but the author must make the architectural decision.
Type of change:
High-level design:
Off-the-shelf rules do not understand the repository fallback helpers, router path convention, variable/registry flows, or cache naming and eviction policy. Warning-only rollout was not needed for the three custom rules because their complete existing backlog was cleared before enabling them.
No migration or backward-compatibility action is required.
Tests:
Use cases covered
Unit tests
Backend integration tests
Ingestion integration tests
Playwright (UI) tests
Manual testing performed
Not applicable; this change is covered by AST rule tests, focused UI unit tests, full-tree ESLint, UI Checkstyle, and Playwright planner validation.
UI screen recording / screenshots:
Not applicable; loading indicators and rendered UI remain unchanged.
Checklist: