Skip to content

perf: cap markdown image transform width + eager-load blog hero images#1023

Merged
tannerlinsley merged 5 commits into
mainfrom
perf/markdown-img-default-width
Jul 2, 2026
Merged

perf: cap markdown image transform width + eager-load blog hero images#1023
tannerlinsley merged 5 commits into
mainfrom
perf/markdown-img-default-width

Conversation

@LadyBluenotes

@LadyBluenotes LadyBluenotes commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary

Two small, independent perf fixes for markdown-rendered images:

  1. Cap the Cloudflare Images transform width for markdown images without explicit dimensions. MarkdownImg previously passed width=undefined straight through to the image transform URL when a markdown image had no explicit width and no inferrable dimension, letting Cloudflare serve an unbounded/full-resolution transform. Now falls back to DEFAULT_TRANSFORM_WIDTH = 1200 in that case only. Cloudflare Images' default fit=scale-down never upscales, so this only shrinks the upper bound — it cannot make any image blurrier or larger than before.

  2. Eager-load the first image in blog posts instead of lazy-loading it. Blog post hero images were marked loading="lazy" like every other markdown image, so the browser deprioritized fetching the LCP candidate on every blog page. Added an opt-in eagerFirstImage prop (wired only from blog.$.tsx, not any docs route) that walks the parsed markdown AST once, finds the first image reachable through plain paragraphs/headings, and renders just that one image with loading="eager" / fetchPriority="high".

Why this design

  • The AST walk is a pure, single-pass computation inside the existing useMemo — no mutable ref, no per-render side effects. An earlier ref-based version was caught by a critic review as having a concurrency bug (stale ref reads across StrictMode/concurrent re-renders could silently promote the wrong image); this version can't have that bug class because there's no mutable shared state.
  • The walker intentionally stops at the first non-paragraph/heading block (list, table, blockquote, tab panel, etc.) rather than searching arbitrarily deep. Verified against all 56 posts in src/blog/*.md: every post with a body image reaches it through plain paragraphs only, so this is safe today. A new test (tests/blog-hero-image.test.ts) asserts this invariant going forward — if a future post's structure breaks the walker, the test fails loudly instead of the optimization silently degrading to lazy-loading.
  • findFirstImageSrc lives in src/utils/markdown/ (not Markdown.tsx) so it's a pure function importable by the plain Node test runner without pulling in React/JSX/asset imports.

Known limitation (documented, not fixed)

If a single document used the exact same image src twice, both occurrences would be marked eager (value-based comparison, not position-based). Checked all 56 current blog posts — zero duplicate src values exist today. Not fixing proactively since it can't happen with current content and the markdown renderer's component API doesn't expose per-node identity to make a position-based fix straightforward.

Summary by CodeRabbit

  • New Features
    • Blog post Markdown can now render the first inline image eagerly to improve initial visual load.
  • Bug Fixes
    • The detected first Markdown image can be treated as high-priority, switching it to eager loading with higher fetch priority.
    • Improved fallback behavior for image sizing when width information is unclear.
  • Tests
    • Added a regression test to verify each blog post’s first Markdown image remains discoverable for the eager behavior.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
tanstack-com a11730e Commit Preview URL

Branch Preview URL
Jul 02 2026, 06:04 PM

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b300bac3-b11c-424d-839c-2220db49e156

📥 Commits

Reviewing files that changed from the base of the PR and between 237d782 and a11730e.

📒 Files selected for processing (1)
  • src/routes/blog.$.tsx
✅ Files skipped from review due to trivial changes (1)
  • src/routes/blog.$.tsx

📝 Walkthrough

Walkthrough

Adds eagerFirstImage through markdown rendering, first-image detection, and image priority handling, plus a blog regression test for posts with inline images.

Changes

Eager First Image Loading

Layer / File(s) Summary
First image utility and test
src/utils/markdown/findFirstImageSrc.ts, src/utils/markdown/index.ts, tests/blog-hero-image.test.ts
Adds findFirstImageSrc, re-exports it, and verifies blog posts with inline images still yield a first image source.
Markdown component eager-image tracking
src/components/markdown/Markdown.tsx
Adds eagerFirstImage handling, derives the first image source from parsed markdown, and routes img nodes through a wrapper that marks the matching image as priority.
MarkdownImg priority rendering
src/ui/MarkdownImg.tsx
Adds a priority prop, a DEFAULT_TRANSFORM_WIDTH fallback, and conditional loading and fetchPriority attributes.
Prop wiring through MarkdownContent and blog route
src/components/markdown/MarkdownContent.tsx, src/routes/blog.$.tsx
Passes eagerFirstImage from MarkdownContent and the blog route into Markdown.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the two main performance changes: capping markdown image width and eager-loading blog hero images.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/markdown-img-default-width

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@tannerlinsley tannerlinsley merged commit d8b3481 into main Jul 2, 2026
7 checks passed
@tannerlinsley tannerlinsley deleted the perf/markdown-img-default-width branch July 2, 2026 18: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