The short answer
Measure a production build with field data, not a development server with lab data. Development builds ship debugging tooling and unminified bundles that do not exist in production — a score from a dev server is measuring your tooling, not your site.
The three that count
LCP — Largest Contentful Paint
- When the main content appears. Usually fixed by making the hero element real HTML or a prioritised image, not something JavaScript renders later.
INP — Interaction to Next Paint
- How fast the page responds to input. Dominated by main-thread JavaScript, which means bundle size and hydration cost.
CLS — Cumulative Layout Shift
- How much the page jumps. Almost always fixed by reserving space for images, embeds, and late-loading content.
What actually moves them
- Ship less JavaScript. Every other optimisation is downstream of this.
- Code-split heavy libraries so routes that do not need them never download them.
- Reserve dimensions for anything that loads asynchronously.
- Serve real HTML for the content that matters, so it does not wait on hydration.