Skip to content

perf(registry): load related skills in the browser, not in SSR - #306

Merged
harlan-zw merged 1 commit into
mainfrom
perf/skill-related-client-only
Sep 29, 2026
Merged

harlan-zw merged 1 commit into
mainfrom
perf/skill-related-client-only

Conversation

@harlan-zw

Copy link
Copy Markdown
Collaborator

❓ Type of change

  • 👌 Enhancement

📚 Description

The 2026-09-29 D1 overload was a no-JS crawler rendering 392 unique Skill pages in two minutes. Every SSR awaited /api/skill-related, about five D1 reads each, and per-URL caching cannot help when every URL is new. Skill pages now fetch it in the browser once the History or Related skills section nears the viewport. Crawlers that run no JavaScript never trigger it.

SSR log for GET /gh/cursor/plugins/deslop on a local wrangler dev of .output:

before: /api/_auth/session, /api/skills/**:slug, /api/skill-live/**:id, /api/skill-related/**:slug
after:  /api/_auth/session, /api/skills/**:slug, /api/skill-live/**:id

Things a reviewer should know:

  • The same endpoint also carries commits, so the History list and the "signed commits" receipt now load client-side too. That was the only other consumer.
  • Nothing else in SSR reads it. Schema.org, meta, the OG image and the .md output do not use related data, so they are unchanged.
  • No-JS crawlers lose the related-skill links from the HTML. Googlebot renders JS, so it should still see them. If internal linking from long-tail pages matters more than I think, the report suggests rendering "more in this repo" from the repo names list the detail endpoint already reads. That belongs with perf(registry): cut D1 reads and writes per Skill page render #305.
  • Both sections keep their footprint while loading. Each has a scoped retry on error and an empty state, so History and Related skills no longer disappear on skills with no data.
  • The trigger margin is 1200px. At 400px, a fast mobile scroll could land the History list while it was on screen. I am not sure 1200 is right for very long SKILL.md pages, but CLS measured the same as main in my runs.

This touches only SkillDetail.vue and its tests, so it should merge cleanly next to #303 and #305.

🤖 AI disclosure: Harlan Agent Kit modified this description. My AI open-source policy.

No-JS crawlers render unique Skill pages in bursts, and each SSR paid
about five D1 reads for /api/skill-related. The 2026-09-29 overload was
one such burst. Related skills and commit history now load client-side
when either section nears the viewport, with skeletons and a scoped retry.
@harlan-zw

Copy link
Copy Markdown
Collaborator Author

Checked by hand on a local wrangler dev of the production build, since CI cannot cover it:

  • SSR HTML of /gh/cursor/plugins/deslop contains no skill-related reference, and the wrangler log shows no /api/skill-related request during the render.
  • In headless Chromium at 1280x900 the browser requests /api/skill-related about 1.2s after navigation, and 6 related skills render. CLS is 0.0252 on both main and this branch. That shift comes from the hero, not these sections.
  • At 390x844 with scrolled loading, no layout shift comes from History or Related skills. A short page fetches on load, because History sits inside the 1200px margin.
  • With the fetch forced to 500, both sections show their error panel. Retry then loads 6 related skills.
Before (main, SSR) After (loaded in browser)
Before After
Loading (mobile) Error state
Loading Error

@harlan-zw
harlan-zw merged commit 9def2bc into main Sep 29, 2026
5 checks passed
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.

1 participant