Skip to content

fix(perf): reserve dimensions on TaskIcon to eliminate CLS#4697

Open
vfanucci wants to merge 1 commit intomainfrom
fix/cls-task-icon-dimensions
Open

fix(perf): reserve dimensions on TaskIcon to eliminate CLS#4697
vfanucci wants to merge 1 commit intomainfrom
fix/cls-task-icon-dimensions

Conversation

@vfanucci
Copy link
Copy Markdown
Contributor

Summary

  • Adds explicit width="32" height="32", loading="lazy", decoding="async", and an onerror fallback to the <img> rendered by TaskIcon.astro.
  • Adds aspect-ratio: 1 / 1 to both TaskIcon.astro and TaskIcon.vue wrappers as a safety net.

Why

On /blueprints/business-automation the page renders 50 <img> tags, 45 without dimensions. 43 of them are task icons rendered in the blueprint header (Header.astroTaskIcon.astro, looping over page.includedTasks). Each SVG load triggers a cascading layout shift, pushing CLS to 0.44 desktop / 0.238 mobile — Google's "Poor" threshold is 0.25.

Setting explicit width/height HTML attributes lets the browser reserve a 1:1 box per icon before the SVG arrives, eliminating the cascade. CSS aspect-ratio on the wrapper is the safety net if attributes get stripped or overridden.

Impact

TaskIcon.astro and TaskIcon.vue are reused across:

  • /blueprints/* (311 pages)
  • /plugins/* (~1100 pages)
  • /docs/* examples and use-case pages

A single component fix should bring CLS below 0.1 on ~1500+ pages.

Test plan

  • Local: npm run build && npm run preview, open /blueprints/business-automation, run Lighthouse → CLS < 0.1.

  • Visual check: blueprint header still renders icons at the same 30×30 size (40px box minus 5px padding); no flicker on theme toggle.

  • After deploy, run PSI on 5 representative URLs:

    • /blueprints/business-automation
    • /blueprints/data-engineering-pipeline
    • /blueprints/microservices-and-apis
    • /plugins/plugin-aws/s3/io.kestra.plugin.aws.s3.upload
    • /docs/quickstart

    Target: CLS < 0.1 on all five.

Notes

  • The onerror="this.style.visibility='hidden'" handles the one stray <img src=""> observed in the page audit (likely a custom plugin task with no matching icon file).
  • width="32" height="32" is a hint for aspect-ratio reservation only — actual rendered size is still controlled by the parent box (e.g. 40×40 with 5px padding in Header.astro).

🤖 Generated with Claude Code

Add explicit width/height attributes and aspect-ratio CSS to TaskIcon so
the browser reserves layout space before SVGs load. Previously, the
blueprint header rendered up to 43 task icons without dimensions, causing
a cascade of layout shifts (CLS 0.44 desktop / 0.238 mobile on
/blueprints/business-automation).

Also adds loading="lazy", decoding="async" and an onerror handler so
missing icons fail silently instead of breaking the layout.

Impact: this single component is reused across blueprint, plugin, and
use-case pages — fix improves CLS on ~1500+ pages.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

☁️ Cloudflare Worker Preview Deployed!

🔗 https://ks-fix-cls-task-icon-dimensions-docs.kestra-io.workers.dev
🔗 https://dc56d4c3-docs.kestra-io.workers.dev

## 🔦 Lighthouse Benchmark

Tested: https://ks-fix-cls-task-icon-dimensions-docs.kestra-io.workers.dev on 2026-04-30 09:39 UTC
Compared against main baseline from 2026-04-10

Scores (0–100, higher is better)

Page Performance Accessibility Best Practices SEO
Home 76 🟢 +19 82 59 92
Pricing 92 91 59 100
Enterprise 92 82 59 100
Cloud 89 86 59 100
About Us 95 91 59 100
Docs Landing 89 88 59 92
Contribute to Kestra (simple docs) 90 87 59 92
Flow (full featured docs) 82 90 59 92
Blog Index 65 🔻 -16 90 59 100
Blog Post (sample) 85 🔻 -12 87 59 100
VS Page (sample) 95 91 59 100
Plugins Landing 83 80 59 92
Plugin Page (sample) 84 🔻 -11 87 59 100
Plugin Debug Page (sample) 93 87 59 100
Plugin Debug Return Page (sample) 93 87 59 100
Blueprints Landing 87 80 56 92
Blueprint Audit Logs CSV Export 69 86 59 100

Core Web Vitals (lower is better)

Page LCP FCP TBT CLS Speed Index
Home 1.39 s 🟢 0.87 s 🟢 344 ms 🔻 0.002 2.12 s 🟢
Pricing 1.27 s 0.72 s 176 ms 🔻 0.000 1.03 s
Enterprise 1.39 s 🟢 0.73 s 158 ms 🔻 0.012 0.86 s 🟢
Cloud 2.00 s 0.66 s 105 ms 🔻 0.000 0.86 s
About Us 1.45 s 0.70 s 75 ms 0.000 1.02 s
Docs Landing 0.99 s 🟢 0.61 s 🟢 260 ms 🔻 0.000 0.88 s 🟢
Contribute to Kestra (simple docs) 1.25 s 0.64 s 211 ms 🔻 0.003 0.75 s
Flow (full featured docs) 1.61 s 0.69 s 🟢 267 ms 🔻 0.000 1.34 s
Blog Index 8.65 s 🔻 0.68 s 74 ms 🔻 0.000 19.13 s 🔻
Blog Post (sample) 2.53 s 🔻 0.64 s 117 ms 🔻 0.000 0.69 s 🟢
VS Page (sample) 1.18 s 0.72 s 135 ms 🔻 0.000 0.82 s
Plugins Landing 1.21 s 🟢 0.73 s 222 ms 🔻 0.000 2.63 s 🔻
Plugin Page (sample) 1.77 s 🔻 0.68 s 125 ms 🔻 0.051 2.87 s 🔻
Plugin Debug Page (sample) 1.20 s 0.64 s 125 ms 🔻 0.001 1.63 s 🔻
Plugin Debug Return Page (sample) 1.24 s 0.58 s 108 ms 🔻 0.025 1.67 s
Blueprints Landing 1.85 s 0.91 s 62 ms 0.000 2.12 s 🔻
Blueprint Audit Logs CSV Export 1.06 s 🟢 0.70 s 184 ms 0.485 1.86 s
Legend

🟢 improved  ·  🔻 regressed  ·  (blank) no significant change
Score threshold: ±10 pts  ·  Metric threshold: ±30% of baseline

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