Summary
Public menu-heavy routes still show a relatively high query count on render even after downstream template duplication is removed.
The most obvious hotspot is packages/core/src/menus/index.ts, where menu item URLs are resolved per item via resolveContentUrl() / resolveTaxonomyUrl().
Context
This was observed while validating AWCMS-Micro against upstream EmDash.
Downstream-only cleanup has already been done:
- removed incorrect public links that used
id instead of slug
- enabled locale-prefixed downstream routing workarounds where needed
- added public link prefetching
- parallelized homepage collection fetches
- removed duplicate homepage menu renders
- removed duplicate footer widget usage on non-detail public pages
Those changes improved correctness and reduced some duplicate downstream work, but they did not materially remove the homepage query-count ceiling.
Evidence
Representative observations from live validation after downstream cleanup:
/ commonly reports db.count=23
/id commonly reports db.count=23
/posts commonly reports db.count=13
/news commonly reports db.count=13
/about commonly reports db.count=4
The remaining gap strongly suggests a core-owned menu/runtime path rather than a downstream template issue.
Suspected Cause
Current menu flow appears to be:
getMenu() fetches the menu row
- it fetches menu items
- it fetches collection URL patterns
buildMenuTree() resolves each item individually
resolveMenuItem() calls resolveContentUrl() / resolveTaxonomyUrl() per item
This means menu-heavy pages can still pay effectively per-item lookup cost, including locale fallback lookups.
Proposed Fix Direction
1. Batch-resolve content references per collection
- collect all referenced content groups by collection first
- fetch requested-locale rows in one query per collection
- fetch fallback rows for unresolved groups in one follow-up query per collection
- build an in-memory lookup map
- make per-item resolution read from the map rather than query again
2. Batch-resolve taxonomy references
- collect referenced taxonomy groups first
- resolve requested-locale rows in one query
- resolve fallback rows for misses in one follow-up query
- build an in-memory taxonomy lookup map
3. Re-profile metadata/fragment collection afterward
EmDashHead.astro already parallelizes site settings, plugin metadata, and fragments, so the menu path looks like the clearest first target.
Acceptance Criteria
- fewer queries on menu-heavy public routes
- no regression in locale-aware menu URLs
- no regression in translation fallback behavior
- no regression for custom URLs, collection items, or taxonomy items
- request-cache behavior remains intact
Suggested Validation
- Add/update a test around
getMenu() with multiple page/post/taxonomy references across locales.
- Measure query count before/after on a menu-heavy public route.
- Confirm locale-specific rows are preferred and deterministic fallback still works when a translation is missing.
Related Context
Summary
Public menu-heavy routes still show a relatively high query count on render even after downstream template duplication is removed.
The most obvious hotspot is
packages/core/src/menus/index.ts, where menu item URLs are resolved per item viaresolveContentUrl()/resolveTaxonomyUrl().Context
This was observed while validating AWCMS-Micro against upstream EmDash.
Downstream-only cleanup has already been done:
idinstead ofslugThose changes improved correctness and reduced some duplicate downstream work, but they did not materially remove the homepage query-count ceiling.
Evidence
Representative observations from live validation after downstream cleanup:
/commonly reportsdb.count=23/idcommonly reportsdb.count=23/postscommonly reportsdb.count=13/newscommonly reportsdb.count=13/aboutcommonly reportsdb.count=4The remaining gap strongly suggests a core-owned menu/runtime path rather than a downstream template issue.
Suspected Cause
Current menu flow appears to be:
getMenu()fetches the menu rowbuildMenuTree()resolves each item individuallyresolveMenuItem()callsresolveContentUrl()/resolveTaxonomyUrl()per itemThis means menu-heavy pages can still pay effectively per-item lookup cost, including locale fallback lookups.
Proposed Fix Direction
1. Batch-resolve content references per collection
2. Batch-resolve taxonomy references
3. Re-profile metadata/fragment collection afterward
EmDashHead.astroalready parallelizes site settings, plugin metadata, and fragments, so the menu path looks like the clearest first target.Acceptance Criteria
Suggested Validation
getMenu()with multiple page/post/taxonomy references across locales.Related Context