Claude Fable 5.1 & GPT-6 Astra packages are live

Performance

Free

Frontend performance — Core Web Vitals, bundle discipline, image and font strategy, rendering cost, and measuring on the devices users actually have.

197 lines8.6 KB Mistral Frontend
targetModels
Mistral Medium 3.5Mistral Large 3Mistral Small 4Mistral FamilyFuture Mistral Models
name
performance
category
Frontend
description
Frontend performance — Core Web Vitals, bundle discipline, image and font strategy, rendering cost, and measuring on the devices users actually have.
license
MIT
author
Agent.md maintainers
last-verified
reviewed-by
unreviewed
<!-- Generated from models/_canonical by scripts/build-model-variants.js. Edit the canonical source, not this file. Behavioural profile for Mistral: scripts/model-profiles.json -->

#How to apply this file

Each section opens with one imperative line; apply every rule in the section it introduces. Do not summarise or skip a section.


#Purpose

Rules for making a web application fast. Performance work is worth doing only against measurements — and against the right ones: field data from real users, not a local build on a fast laptop.

Optimising what you have not measured is how teams ship a 40 KB saving on a page whose problem is a 3-second server response.


#Measure the right things

[INST] Apply every rule in this section: Measure the right things. [/INST]

MetricTargetWhat it reflects
LCP< 2.5sWhen the main content appears
INP< 200msResponsiveness to interaction
CLS< 0.1Visual stability
TTFB< 800msServer and network before anything renders
Total JS< 200 KB compressedThe dominant cost on mobile

Field data (Chrome UX Report, web-vitals in production) beats lab data (Lighthouse). Lab data is reproducible; field data is true.

ts
import { onLCP, onINP, onCLS } from "web-vitals";
onLCP(send); onINP(send); onCLS(send);      // report p75 by route and device class

Track p75, segmented by device class and connection. A p50 on desktop hides the experience of the median mobile user entirely. Test on a mid-range Android device with CPU throttling, not on your development machine.


#JavaScript is the expensive part

[INST] Apply every rule in this section: JavaScript is the expensive part. [/INST]

A byte of JavaScript costs far more than a byte of image: it must be downloaded, parsed, compiled and executed, on the main thread.

  • Measure the bundle in CI and fail the build on a regression (size-limit, bundlesize). Growth is otherwise invisible until it is large.
  • Analyse before optimising (@next/bundle-analyzer, rollup-plugin-visualizer). It is usually one dependency, not a hundred small things.
  • Route-level code splitting first, then component-level for genuinely heavy things — a chart library, a rich text editor, a date picker.
  • Check for duplicate copies of the same library at different versions.
  • Prefer platform APIs: Intl.DateTimeFormat instead of a date library, fetch instead of a client, structuredClone instead of a deep-clone helper.
  • Load third-party scripts with defer or async, from a consent gate, and audit them regularly — analytics and tag managers are frequently the largest script on the page and nobody owns them.
tsx
const Chart = lazy(() => import("./Chart"));   // loaded when rendered, not at boot

Never ship a library for one function. A 70 KB dependency imported for debounce is the most common single avoidable regression.


#Images and fonts

[INST] Apply every rule in this section: Images and fonts. [/INST]

Images are usually the LCP element, and fonts are usually the cause of layout shift.

html
<img src="hero.avif" width="1200" height="630" alt="…"
     fetchpriority="high" decoding="async" />
<img src="below.avif" width="400" height="300" alt="…" loading="lazy" />
  • Always set width and height (or aspect-ratio). Without them the layout shifts when the image loads — the main cause of CLS.
  • loading="lazy" on everything below the fold; never on the LCP image, which needs fetchpriority="high".
  • Serve AVIF or WebP with srcset/sizes so a phone does not download a desktop-sized image.
  • Fonts: font-display: swap, preload the one font used above the fold, subset it, and self-host. @import from a third party costs an extra connection and round trip before any text renders.
  • Declare size-adjust/ascent-override on the fallback font so the swap does not shift the layout.

#Rendering cost

[INST] Apply every rule in this section: Rendering cost. [/INST]

  • Virtualise long lists (@tanstack/virtual). Rendering 10,000 rows is slow no matter how cheap each row is.
  • Keep the main thread free: heavy computation belongs in a web worker.
  • Debounce or throttle high-frequency handlers; use useDeferredValue to keep input responsive while an expensive list catches up.
  • Avoid layout thrash — batch DOM reads and writes rather than interleaving them.
  • Animate transform and opacity only; animating width, top or box-shadow triggers layout or paint on every frame.
  • Prefer CSS to JavaScript for animation, and honour prefers-reduced-motion. → Frontend/react

#Network and delivery

[INST] Apply every rule in this section: Network and delivery. [/INST]

  • Cache static assets immutably with content hashes: Cache-Control: public, max-age=31536000, immutable.
  • HTML is no-cache or short-lived; it is what points at the hashed assets.
  • Serve from a CDN close to users; compress with Brotli.
  • preconnect to critical third-party origins; preload genuinely critical resources only — over-preloading competes with the resources that matter.
  • Prefetch the next likely route on intent (hover, viewport), not everything.
  • Server-render or statically generate content-heavy pages; a client-rendered page cannot have a good LCP because nothing renders until the JavaScript arrives. → Frontend/server-components

#Anti-patterns

[INST] Apply every rule in this section: Anti-patterns. [/INST]

Anti-patternWhy it failsFix
Optimising without measuringEffort on the wrong thingField data first
Lab data onlyHides the real user experienceRUM at p75 by device class
Testing on a development machineUsers are on mid-range phonesThrottled real devices
No bundle budget in CIGrowth is invisible until it hurtssize-limit gate
A library for one utilityTens of KB for a few linesPlatform API or inline it
Everything in one bundleLong time-to-interactiveRoute and component splitting
Images without dimensionsLayout shift; poor CLSwidth/height or aspect-ratio
Lazy-loading the LCP imageDelays the metric it definesfetchpriority="high"
Unoptimised formats and sizesMegabytes over mobile networksAVIF/WebP with srcset
Third-party fonts via @importExtra connection before text rendersSelf-host and preload
No font-displayInvisible text, then a shiftswap plus metric overrides
Rendering huge listsSlow render and interactionVirtualise
Heavy computation on the main threadBlocks interaction; ruins INPWeb worker
Animating layout propertiesLayout and paint every frametransform and opacity
Preloading everythingCompetes with what mattersPreload deliberately
Unaudited third-party scriptsOften the largest script; nobody owns themInventory and review
Client-rendering content pagesLCP cannot be goodServer-render

#Checklist

  • Verify: LCP, INP and CLS are collected from real users and reviewed at p75
  • Verify: Metrics are segmented by device class and route
  • Verify: Testing includes a throttled mid-range mobile device
  • Verify: A bundle-size budget is enforced in CI
  • Verify: The bundle has been analysed and large dependencies justified
  • Verify: Routes are code-split; heavy components load on demand
  • Verify: No dependency is included for a single small utility
  • Verify: Third-party scripts are inventoried, deferred and consent-gated
  • Verify: Every image declares dimensions or an aspect ratio
  • Verify: The LCP image is prioritised and never lazy-loaded
  • Verify: Images are served in modern formats with responsive sizes
  • Verify: Fonts are self-hosted, subset, preloaded, with font-display: swap
  • Verify: Fallback font metrics are adjusted to avoid swap shift
  • Verify: Long lists are virtualised
  • Verify: Expensive computation runs off the main thread
  • Verify: Animations use only transform and opacity, honouring reduced motion
  • Verify: Static assets are content-hashed and cached immutably
  • Verify: Content-heavy pages are server-rendered or statically generated