Skip to content

Improve docs indexing, accessibility, and initial load performance - #7078

Merged
masenf merged 5 commits into
mainfrom
codex/improve-docs-seo-performance
Sep 10, 2026
Merged

Improve docs indexing, accessibility, and initial load performance#7078
masenf merged 5 commits into
mainfrom
codex/improve-docs-seo-performance

Conversation

@Alek99

@Alek99 Alek99 commented Sep 10, 2026

Copy link
Copy Markdown
Member

Problem and result

Mounted production builds were overwriting prerendered docs with asset directories and the root SPA shell. This left the docs home without indexable content and six articles returning 404. Other pages repeated metadata, exposed legacy URLs as 200/JavaScript redirects, and loaded substantial code and chart work before readers needed it.

This PR repairs the production output, improves shared docs structure and accessibility, and reduces initial work while preserving interactive examples. The complete final production crawl verifies 418/418 canonical pages, and all 94 legacy redirects resolve correctly.

What changed and why

  • Preserve mounted prerenders: recursively merge assets into the route tree and compress only after the final tree is assembled, so routes named assets/components and the docs home survive the build.
  • Make canonical pages distinct and discoverable: contextual titles/descriptions with normalized standalone acronyms, canonical URLs and structured breadcrumbs using the configured deployment origin/mount and real routes (localhost by default; REFLEX_DEPLOY_URL supplied by deployment jobs), the standard sitemap XML namespace, and frontend-prefix-aware sitemap generation. Fix duplicate H1 content, broken fragments, and missing image alt text.
  • Return real redirects when the backend serves the frontend: GET/HEAD middleware issues permanent 301 responses and retains queries. Static-only hosting gets readable destination links, canonical/noindex metadata, and refresh fallback; CDN edge redirects still need deployment configuration.
  • Render readable code immediately: escaped Shiki fallback code is present in SSR. Download/highlight near the viewport during idle time; failed highlighting leaves code readable. Cached HTML matches every highlighting input, so theme/language/transformer changes immediately restore fallback code until replacement highlighting succeeds. Preserve cleanup on unmount.
  • Reduce initial library work: standard React memo initializers can be discarded when unused, while custom wrappers retain side effects. Add the opt-in frontend_lazy_bundled_libraries configuration and enable it for docs; optional dynamic namespaces load once on demand and retry after failures. Core React/context identity is preserved, and the framework default stays eager for compatibility. Preload global CSS explicitly.
  • Defer expensive examples: the documented demo exec defer flag mounts Plotly previews as readers approach them, reserves space, and preserves server-rendered source. Charts now fit their mobile container. Remove docs-wide marketing pixels/session recorders.
  • Improve shared controls/layout: descriptions render once in responsive API tables; copy buttons, card links, clear controls, mobile navigation, and feedback triggers have valid semantics/names. Eliminate nested feedback buttons, keep card focus outlines inside rounded clipping boundaries, and improve code/counter/status contrast.
  • Isolate project configuration: only the requested project can supply rxconfig, avoiding an unrelated editable docs app changing framework tests or another project. Adjust the invalid-event-value fixture to account for the enterprise plugin's legitimate function serializer. Scope version-check mocks to their consumer so lazy dependency imports still read real package versions. The docs link validator uses the standard sitemap namespace and the configured build directory.

Before and after

Check Before After
Docs home Empty 14.8 KiB SPA shell Full prerendered content
Broken articles 6 return 404 All 6 return 200
Canonical crawl Missing home metadata; duplicate titles/descriptions 418 unique titles/descriptions, one H1 each, matching canonicals
Legacy routes 94 return 200 with JS redirects 94 HTTP 301s; all destinations and static fallbacks verified
Sitemap Invalid namespace / wrong mounted root XSD-valid, 418 unique production URLs including docs home
Broken in-page fragments / missing image alt attributes 2 / 4 0 / 0
Structured breadcrumbs None 417 articles
Plotly mobile initial total blocking time 5,965 ms 0 ms

Lighthouse performance scores (out of 100), before → after:

Page Mobile Desktop
Docs home 63 → 68 89 → 97
Introduction 53 → 57 81 → 85
Installation 47 → 60 80 → 86
Chat tutorial 55 → 59 87 → 89
Button 55 → 57 75 → 81
Bar chart 42 → 53 78 → 80
AG Grid 44 → 49 85 → 79
App API 54 → 60 81 → 89
Changelog 57 → 61 88 → 92
HTML layout 49 → 57 77 → 83
Plotly 23 → 53 67 → 81

Lighthouse SEO is 100 in all 26 recorded runs. Best practices improved from 54 to 100 except AG Grid (96, due to enterprise trial-license console messages). SEO scores alone missed the original broken/empty pages, so the full raw-HTML crawl is the primary correctness check.

Initial local JavaScript in the HTML/module-preload graph (gzip):

Route Before → after
/docs/getting-started/introduction/ 889 → 798 KiB
/docs/library/forms/button/ 1070 → 960 KiB
/docs/api-reference/app/ 586 → 488 KiB
/docs/library/graphing/other-charts/plotly/ 1076 → 966 KiB

Measurement provenance: the Lighthouse table was recorded on 654132a. The subsequent review fixes change highlighting invalidation, focus outlines, title casing, breadcrumb edge cases, and test fixtures; all 26 performance runs were not repeated after those fixes. The complete 418-page crawl and production browser checks were repeated at fe56d43a. The follow-up in f2a0f434 was checked with the complete docs suite, all four frontend regressions, real app imports under staging URL settings, and separate dev/static frontend redirect checks.

Method: production builds against base bae7294119a8ffa2b3177a0a0f0063d76b616d86, same macOS/Apple M5 Pro machine, Node 26, Chrome 152, Lighthouse 13.4.1 with default simulated throttling and fresh headless Chrome launches. Eleven routes on mobile/desktop; home/introduction mobile scores are medians of three runs, others single runs. All 26 results are included, including regressions. These local measurements are not field Core Web Vitals. The home originally served an empty shell, so its corrected payload is not an equivalent isolated speed comparison.

Validation

  • 8,453 framework unit tests passed, 18 skipped; 76.50% coverage collected from process startup with uv run --no-sync coverage run -m pytest tests/units -q, then coverage report.
  • 449 docs tests passed, 1 skipped, from docs/app.
  • The reflex-docs Python 3.11/3.12 CI jobs now run the frontend suite after the production build, so these checks run on each PR.
  • 4 frontend regressions passed: escaped React SSR, highlight input invalidation/failure/async replacement, Rolldown removal of unused memos/custom-wrapper side effects, and generated lazy-registry execution/concurrency/retry/legacy compatibility.
  • All changed-file pre-commit hooks passed: Ruff formatting/lint, codespell, generated stubs, Pyright, ty, Biome. Full-repository Ruff checks and pyright reflex tests pass; no stub hash changes.
  • Complete production build, 418-page HTML crawl, 94 HTTP/static redirects, sitemap XSD validation, and 26 Lighthouse runs.
  • Browser checks: counter updates, feedback popover with a single submit button, mobile navigation, readable light/dark code, wrapping API rows, and one deferred Plotly chart measuring 308px inside a 308px parent with no page overflow at 390px.

Initial validation coverage detail (654132a): pytest-cov's standard invocation passes all unit tests but reports 71.14% because optional pytest plugins import framework modules before its hook starts. Starting coverage before pytest measures 76.50%; the separate units-plus-docs pytest-cov run measures 72.90%. Earlier CLI failures were resolved by fetching Git history/tags and reinstalling editable packages to replace invalid shallow-clone version metadata. No assertions or coverage thresholds were disabled.

Review notes and limits

  1. AG Grid desktop is 85 → 79 in the final single-run comparison; mobile is 44 → 49. Shared providers, CSS, and example bundles remain substantial. This PR does not claim every page is maximally fast.
  2. Some demo-specific accessibility/table checks and vendor trial warnings remain. No audit checks or vendor errors are suppressed.
  3. Verify redirects/cache behavior in the real hosting stack. The separate XY docs application is not part of this checkout and remains the one missing local cross-application target.
  4. Broad integration and minimum-dependency matrices were not run locally. Unit/docs coverage and production browser verification are complete; the repository CI matrix remains the release gate.
  5. Related open work: feat(docs): improve a11y and lazy-load Inkeep search widget #6723 and perf(docs): lazy-load search and highlight code at build time #6732 overlap accessible controls and code loading (the latter uses build-time Shiki); Tree-shake bundled libraries while preserving dynamic components #6563 addresses namespace tree-shaking with a different approach; fix(config): keep rxconfig dependencies on same-root reload #7075 changes same-root config dependency eviction. This PR is based on current main and does not include those branches. Coordinate overlapping changes during review.

Submission checklist

  • Reviewed CONTRIBUTING.md and checked related open PRs.
  • Bug fixes and opt-in performance behavior documented.
  • Regression assertions added; tests and pre-commit checks run.
  • News fragments included for each affected package.
  • Adversarial review completed; limitations and overlap recorded above.

Review in cubic

The subsequent a7e412af follow-up removes the hardcoded production origin from docs config, preserves APIs/URLs casing in page titles and sidebar labels, and passes 449 docs tests (1 skipped). The show_built_with_reflex=False setting remains enabled in the docs config to hide the badge.

@Alek99
Alek99 requested a review from a team as a code owner September 10, 2026 20:23
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge; no actionable new failure remains, and the prior highlighting issue was manually resolved after the current implementation added complete input invalidation and fallback behavior.

Summary

  • Preserves mounted prerendered routes when assets and compressed output are assembled.
  • Adds canonical metadata, structured breadcrumbs, compliant sitemap generation, and usable legacy-route redirects.
  • Provides readable server-rendered code fallbacks and defers optional libraries and expensive examples.
  • Improves accessible names, responsive layouts, focus behavior, and documentation quality checks.
  • The follow-up changes make deployment origins environment-configurable and normalize plural acronym labels consistently.

Reviews (5) · Last reviewed commit: "Keep docs deployment URLs environment-dr..."

Comment thread packages/reflex-base/src/reflex_base/.templates/web/components/shiki/code.js Outdated
@codspeed-hq

codspeed-hq Bot commented Sep 10, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 40 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing codex/improve-docs-seo-performance (a7e412a) with main (bae7294)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 73 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/reflex-base/src/reflex_base/.templates/web/components/shiki/code.js Outdated
Comment thread docs/app/reflex_docs/templates/docpage/docpage.py Outdated
Comment thread docs/app/reflex_docs/pages/docs/metadata.py
Comment thread tests/units/components/test_memo.py
Comment thread docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py Outdated
Comment thread docs/app/tests/frontend_quality.test.mjs Outdated
Comment thread docs/app/tests/frontend_quality.test.mjs Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 13 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread docs/app/tests/frontend_quality.test.mjs
Comment thread docs/app/reflex_docs/templates/docpage/docpage.py Outdated
Comment thread docs/app/reflex_docs/reflex_docs.py
Comment thread docs/app/tests/frontend_quality.test.mjs

@masenf masenf left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

not new, but i noticed that the casing for APIs/Apis and URLs/Urls looks a little off on the AI sidebar

Image

Comment thread docs/app/rxconfig.py Outdated
@Alek99

Alek99 commented Sep 10, 2026

Copy link
Copy Markdown
Member Author

Addressed Masen’s AI sidebar casing feedback in a7e412a: the APIs and URLs page titles now preserve their acronyms, and the sidebar normalizer preserves those plural forms too. The group labels and child entries now match (APIs / APIs, URLs / URLs). Both sidebar regressions failed before the fix and now pass. The complete docs suite passes 449 tests (1 skipped), and all applicable pre-commit checks pass.

@masenf
masenf merged commit 074a818 into main Sep 10, 2026
115 checks passed
@masenf
masenf deleted the codex/improve-docs-seo-performance branch September 10, 2026 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants