farming-labs/fm-skills · Archived

performance-patterns

Explains web performance patterns including Core Web Vitals, network and JavaScript cost, rendering and hydration work, lazy loading, caching, and performance budgets.

First seen Jun 8, 2026

Installation

$ npx skills add farming-labs/fm-skills --skill performance-patterns

Summary

  • Explains web performance patterns including Core Web Vitals, network and JavaScript cost, rendering and hydration work, lazy loading, caching, and performance budgets.
  • Use when diagnosing slow pages, improving user-perceived speed, or deciding which optimization strategy matters most.

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from farming-labs/fm-skills · top by installs.

npx skills add farming-labs/fm-skills

Browse all from farming-labs/fm-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 35
Default branch main
Open issues 1
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,702 B
  • docs SUMMARY.md 313 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 2 installs

SKILL.md

Performance Patterns

Overview

Web performance is about how quickly users can:

  • see useful content
  • interact without lag
  • move through the application without jank

Performance is not one problem. It is usually a combination of:

  • too much network work
  • too much JavaScript
  • too much rendering work
  • too much data fetching latency
  • too much layout instability

The right optimization depends on which of those is actually dominating.

The Main Performance Buckets

Bucket Typical Problem Typical Fix
Network Large assets, slow server, too many requests Compress, cache, preload, reduce bytes
JavaScript Big bundles, expensive parsing, long tasks Ship less JS, split code, defer work
Rendering Large DOM, expensive layout/paint Simplify UI work, reduce rerenders
Hydration Too much client work before interactivity Hydrate less, hydrate later, use islands
Data Waterfalls, slow APIs, duplicate fetching Parallelize, cache, prefetch, stream

Core Web Vitals

Core Web Vitals are the most useful high-level user-centered performance signals.

Metric Measures Good
LCP How quickly main content becomes visible <= 2.5s
INP How quickly the page responds to interaction <= 200ms
CLS How stable the layout is while loading <= 0.1

Interpreting Them

  • Bad LCP usually means slow server response, large render-blocking assets, or slow hero image/content delivery
  • Bad INP usually means too much JavaScript or long main-thread work
  • Bad CLS usually means space is not reserved for content that appears later

Do not optimize blindly. Start with the metric that is actually failing.

A Practical Performance Model

Think in this order:

Can the browser get the bytes quickly?
Can it understand and execute them cheaply?
Can it render useful content early?
Can the user interact without waiting?
Can the UI stay stable while it updates?

This usually maps to:

TTFB -> LCP -> Hydration / JS cost -> INP -> CLS

Performance Budgets

Budgets prevent performance from degrading gradually over time.

Common budgets:

  • JavaScript bytes per route
  • image weight for above-the-fold content
  • number of blocking requests
  • maximum LCP
  • maximum INP

Example budget mindset:

Home page:
- Initial JS under 180 KB compressed
- Hero image under 120 KB
- LCP under 2.5s on mid-tier mobile

Without budgets, performance work often becomes reactive and late.

Architecture Impacts Performance

Pattern Strength Risk
CSR Simple hosting, rich interactivity Slow first render, high JS cost
SSR Faster first content, better SEO Server latency, hydration cost
SSG Fastest repeatable loading for static content Staleness, rebuild tradeoffs
Streaming Early shell + progressive content More complexity in boundaries
Islands / partial hydration Less JS on page More architecture complexity

Architecture does not guarantee performance, but it changes where the performance risks move.

Pattern 1: Ship Less JavaScript

Large JS bundles hurt:

  • download time
  • parse/compile time
  • hydration cost
  • interaction latency

Common Approaches

  • Remove unused dependencies
  • Prefer smaller libraries or built-in APIs
  • Code split by route and heavy feature
  • Avoid sending server-only logic to the client
  • Render more on the server when appropriate
// Load expensive feature only when needed
const Chart = lazy(() => import('./Chart'));

If you can delete JavaScript entirely, that is often better than optimizing it.

Pattern 2: Prioritize the Critical Path

The browser should receive the most important resources first.

Examples:

  • preload the hero image
  • inline or prioritize critical CSS
  • defer non-essential scripts
  • avoid blocking fonts or third-party scripts above the fold
<link rel="preload" href="/hero.webp" as="image">
<script defer src="/app.js"></script>

Do not preload everything. Preloading too much just moves congestion around.

Pattern 3: Lazy Load Non-Critical Work

Load expensive code and assets when users actually need them.

Good candidates:

  • admin pages
  • charts
  • WYSIWYG editors
  • below-the-fold media
  • modal-only features
const Editor = lazy(() => import('./Editor'));

Lazy loading is useful only when the delayed resource is truly non-critical. If the user always needs it immediately, lazy loading may just add an extra wait.

Pattern 4: Reduce Render and Layout Work

Performance problems are not always network problems.

UI can be slow because:

  • too many nodes update
  • layout recalculates repeatedly
  • animations trigger layout/paint work
  • the app does unnecessary rerenders

Common Fixes

  • Keep DOM size reasonable
  • Virtualize long lists
  • Avoid layout thrashing
  • Animate transform/opacity instead of layout-heavy properties when possible
  • Move expensive computations out of render paths
// Bad: expensive work during every render
const sorted = bigArray.sort(compareFn);

// Better: derive once per real input change
const sorted = deriveSortedItems(bigArray);

Pattern 5: Fetch Earlier, in Parallel, and Less Often

Data latency often dominates user experience.

Common mistakes:

  • fetch-on-render waterfalls
  • refetching identical data repeatedly
  • waiting for one request before starting the next when not necessary

Better patterns:

  • start independent requests in parallel
  • prefetch likely-next routes
  • cache stable data
  • stream slower sections separately
const [user, notifications] = await Promise.all([
  getUser(),
  getNotifications(),
]);

Pattern 6: Optimize Images and Media

Images are often the largest payload on a page and are frequent LCP candidates.

Rules of Thumb

  • Use responsive image sizes
  • Compress aggressively
  • Prefer modern formats when supported
  • Preload only the true LCP image
  • Lazy load below-the-fold images
  • Always reserve dimensions
<img
  src="/hero.webp"
  width="1200"
  height="800"
  alt="Product hero"
>

Missing dimensions are a common CLS bug.

Pattern 7: Manage Fonts Carefully

Fonts can block rendering or cause layout shifts.

Good practices:

  • self-host when practical
  • subset font files
  • limit the number of weights and styles
  • use font-display: swap or equivalent strategy
  • preload only critical fonts

Too many custom fonts can erase performance gains elsewhere.

Pattern 8: Control Third-Party Cost

Analytics, ads, chat widgets, A/B testing tools, and tag managers often create disproportionate performance damage.

Third-party scripts can hurt:

  • TTFB
  • main-thread availability
  • INP
  • privacy/compliance posture

Rules of thumb:

  • load them later if possible
  • remove the ones you do not use
  • measure them separately
  • do not assume vendor code is cheap because it is external

Pattern 9: Defer Non-Urgent Work

Not all work must happen immediately after load or interaction.

Examples of deferrable work:

  • analytics initialization
  • non-critical hydration
  • below-the-fold widgets
  • expensive derived UI that is not immediately visible

Split urgent work from non-urgent work whenever the platform or framework supports it.

Pattern 10: Stabilize the Layout

CLS is usually preventable.

Common causes:

  • images without dimensions
  • injected banners or ads
  • font swaps changing text metrics
  • content inserted above existing content

Typical fixes:

  • reserve space
  • keep placeholders the same size as final content
  • avoid inserting UI above the reading position without care

Pattern 11: Cache the Right Things

Caching improves performance only when freshness is handled correctly.

Useful cache layers:

  • browser HTTP cache
  • CDN cache
  • application/server cache
  • client-side query cache

Caching helps performance when:

  • data is reused often
  • assets are immutable or versioned
  • invalidation is understood

Caching hurts when stale data creates correctness bugs or forces wasteful refetch loops.

Pattern 12: Measure Before and After

Performance work without measurement turns into guesswork.

Useful Signal Types

Type Use
Lab tests Repeatable debugging in a controlled environment
Field data Real-user experience in production
Bundle analysis Detect JS growth
Profiler traces Diagnose rendering and main-thread work

Practical Workflow

  1. Identify the failing metric or slow user flow
  2. Find the dominant bottleneck
  3. Apply the narrowest meaningful fix
  4. Re-measure
  5. Add a budget or guardrail so it does not regress

Common Optimization Mistakes

Mistake Why It Fails
Micro-optimizing components before checking bundle size Big wins are often elsewhere
Lazy loading critical UI User still waits, just later
Prefetching too aggressively Wastes bandwidth and device resources
Caching everything Creates correctness and invalidation issues
Measuring only on a fast laptop Hides real user pain
Chasing one benchmark while hurting UX elsewhere Metrics are proxies, not the product

Decision Guide

Use this rough mapping:

  • Slow first paint: look at server response, critical assets, and render-blocking resources
  • Slow first interaction: look at JS size, hydration, and long tasks
  • Janky typing or clicking: inspect main-thread work and rerenders
  • Layout jumps: reserve space and fix dynamic insertion behavior
  • Slow route changes: prefetch, split bundles, cache data, reduce client work on navigation

Rules of Thumb

  • Delete work before optimizing work
  • Optimize the critical path first
  • Measure on realistic devices and networks
  • Prefer broad architectural wins over tiny component tweaks
  • Performance budgets are often more valuable than one-off performance heroics

Related Skills

  • build-pipelines-bundling for bundle size and chunking strategy
  • rendering-patterns for SSR, SSG, CSR, and streaming tradeoffs
  • hydration-patterns for hydration cost and islands architecture
  • data-fetching-patterns for request waterfalls and loading strategies
  • caching-invalidation-patterns for freshness and cache correctness