Dev Log

Project aerial images refreshed and switched to WebP source

· Claude Opus 4.7 · Bot
assetsperformanceimageswebpprojects

What was done

Images refreshed and re-encoded (6 files)

Source files in .tmp/plans/projects/ were renamed card-<slug>-gpt.png; destinations in src/assets/projects/ use slug-only naming. Confirmed 1:1 mapping with user before proceeding, then converted each source PNG to WebP @ quality 80 using Sharp (already in node_modules as an Astro dependency) and wrote the output with the target slug plus a .webp extension:

source (in .tmp/plans/projects/)destination (in src/assets/projects/)PNG inWebP outsavinggate
card-foxcroft-gpt.pngfoxcroft.webp2,191 KB159 KB93%PASS (<200KB)
card-gander-north-gpt.pnggander-creek-north.webp3,411 KB74 KB98%PASS (<200KB)
card-gander-south-gpt.pnggander-creek-south.webp3,821 KB102 KB97%PASS (<200KB)
card-jumpcreek-gpt.pngjump-creek.webp6,620 KB276 KB96%WARN (200–400KB)
card-ledgestone-gpt.pngledgestone-plaza.webp5,130 KB97 KB98%PASS (<200KB)
card-swainson-gpt.pngswainsons-hawk-arbor.webp4,837 KB246 KB95%WARN (200–400KB)

Aggregate source-tree reduction: ~25.5 MB → ~955 KB (96% smaller).

All six files pass the hard 400 KB ceiling. Two (jump-creek, swainsons) sit in the 200–400 KB warn band — these are busier compositions with higher encoded entropy. Not a blocker; tagged for potential re-export later if Lighthouse flags them.

All new sources are under the 1920 px max-width policy (widest is jump-creek at 1871 px) — no resizing was needed.

Originals in .tmp/plans/projects/*.png were left intact per instruction — those are the user’s source-of-truth exports. The old .png files in src/assets/projects/ were removed as part of the extension switch.

Source-extension switch (PNG → WebP)

Replacing bytes in place would have left .png source extensions on WebP-encoded files — a lie the build system would paper over but a confusing one for anyone reading the tree. Switched source files to .webp extensions, which meant updating the imports in every consumer:

  • src/pages/index.astro — 6 imports
  • src/pages/projects/index.astro — 6 imports
  • src/pages/projects/[slug].astro — 6 imports
  • src/pages/home-test.astro — 6 imports
  • src/pages/dev-iq/land-use-intelligence/index.astro — 1 import (jump-creek, used as the Nampa aerial placeholder on the LUI hub)

Astro’s <Image> component accepts WebP (or any raster format) as source and recompresses to the format/width/height each template requests, so the build output at dist/_astro/ is unaffected by the source-side extension change. The change is purely for source-tree hygiene.

Consuming pages confirmed unaffected

Grepped dist/projects/<slug>/index.html for each slug after build: every project detail page correctly references a hashed <slug>.*.webp asset in its hero. No broken references, no 404s in the build output.

Top built image assets (all WebP, listed largest first):

347 KB  dist/_astro/swainsons-hawk-arbor.<hash>.webp  (2400×1000 project hero)
333 KB  dist/_astro/jump-creek.<hash>.webp             (2400×1000 project hero)
288 KB  dist/_astro/hero-home-idaho.<hash>.webp        (/home-test/ hero)
227 KB  dist/_astro/foxcroft.<hash>.webp               (2400×1000 project hero)
146 KB  dist/_astro/gander-creek-south.<hash>.webp
141 KB  dist/_astro/swainsons-hawk-arbor.<hash>.webp   (800×533 card)
135 KB  dist/_astro/ledgestone-plaza.<hash>.webp
125 KB  dist/_astro/jump-creek.<hash>.webp             (800×533 card)
115 KB  dist/_astro/gander-creek-north.<hash>.webp
103 KB  dist/_astro/foxcroft.<hash>.webp               (800×533 card)

Every built asset is under 400 KB. The two 300+ KB entries are full-bleed 2400×1000 project heroes rendered at fetchpriority="high" on individual project pages — a single well-compressed eager hero per page, the intended pattern.

Follow-ups logged

  • Added a post-deploy Lighthouse audit item to TODO.md under a new “Post-deploy audits” section. Targets: LCP < 2.5s on /projects/ and /projects/swainsons-hawk-arbor/, no “Properly size images” or “Efficiently encode images” warnings. If the two 200–400 KB warns show up as Lighthouse flags, the source art can be re-exported tighter.

Verification

  • npm run build → 146 pages, 0 errors.
  • npm run verify → 18/18 passing.
  • Per-slug HTML smoke test → every one of the six project pages carries a resolved WebP hero reference.

Why

User updated the project aerials in .tmp/plans/projects/. Six source files were multi-MB raw PNGs — jump-creek at 6.46 MB alone would have been a 10× bloat against the 400 KB source-side performance budget the site enforces. Converting to WebP @ q80 at the source boundary (rather than only at build time) lets the repo stay light, the git history stay readable, and keeps future diffs of this directory reviewable. Switching extensions makes the source tree honest about what’s on disk.

Net effect: new aerials on every page that displays them, source tree one-tenth its former size, build passes all checks, load-performance audit queued for after deploy.

Files affected

  • Created (assets): src/assets/projects/foxcroft.webp, gander-creek-north.webp, gander-creek-south.webp, jump-creek.webp, ledgestone-plaza.webp, swainsons-hawk-arbor.webp
  • Deleted (assets): src/assets/projects/*.png (6 files — the PNG versions now live only as hashed renders in dist/_astro/ during old build artifacts, which get cleaned on the next build)
  • Modified (imports): src/pages/index.astro, src/pages/projects/index.astro, src/pages/projects/[slug].astro, src/pages/home-test.astro, src/pages/dev-iq/land-use-intelligence/index.astro
  • Modified (backlog): TODO.md — added post-deploy Lighthouse audit item and bumped the “last updated” stamp
  • Preserved (source of truth): .tmp/plans/projects/*.png left intact
  • Created (this entry): src/content/devlog/2026-04-22-project-images-refresh.md
Feedback