Spurlock Studios
Contact
Share LinkedIn X
A scuffed work smartphone with a blank glowing circular button. Thesis: LIGHTHOUSE 90 WITHOUT KILLING DESIGN.

A 90 on mobile Lighthouse and a film-grade fold can live on the same page. They stop living together when you lock the art direction first, then ask engineering to hide the cost. Chrome itself colors 90–100 as good and says a perfect 100 is not expected — moving 99 to 100 takes about as much metric work as moving 90 to 94, per the Lighthouse performance scoring docs. This spoke is the tradeoff map: keep the brand, budget the motion, and stop treating a green circle as the product. Parent pillar: Websites That Feel Like Films.

The short answer

  • Animations are allowed. Unbudgeted animations, late LCP images, and first-load tag soup are not.
  • Optimize the actual LCP node. If the fold is hidden until a JavaScript timeline runs, the plan is wrong.
  • Core Web Vitals are field metrics at the 75th percentile: LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1, as published on web.dev/vitals.
  • Lighthouse is a lab debugger. It cannot measure INP the way the field does; it uses Total Blocking Time as a proxy.
  • Cut accidental weight first. Do not start by deleting the photography that is the brand.

What does a Lighthouse 90 actually mean?

A Lighthouse Performance score is a weighted average of lab metrics, not a ranking certificate and not a taste score. Chrome documents the current published weights under Lighthouse 10 in performance scoring:

Lab metricWeightWhat it is actually scoring
Total Blocking Time (TBT)30%Main-thread long tasks between FCP and TTI
Largest Contentful Paint (LCP)25%When the largest viewport content paints
Cumulative Layout Shift (CLS)25%Unexpected layout movement
First Contentful Paint (FCP)10%First paint of any content
Speed Index10%How quickly visible content fills in

Color bands on that same page: 0–49 poor, 50–89 needs improvement, 90–100 good. That is why this post is titled 90+, not 100. A 92 with a readable cinematic fold beats a 99 that shipped as a sterile brochure because someone deleted the brand to flatten the last orange audit.

Score curves are log-normal against HTTP Archive data. The 8th percentile maps to a metric score of 90. Past ~96 you are in diminishing returns. If a stakeholder wants “100 or we failed,” show them that paragraph from Chrome, then show the filmstrip of what the 100 cost.

Desktop and mobile use different scoring curves. A desktop 96 on an M-series laptop is not a mobile 96. Celebrate the mobile run, or do not celebrate.

Is lab Lighthouse the same as Core Web Vitals?

No. Web Vitals is explicit: Core Web Vitals are field metrics. Lighthouse is a lab tool. Google’s own table says Lighthouse can report LCP and CLS in the lab, and cannot report INP — use TBT instead.

SignalWhere it comes fromWhat it is for
Lighthouse PerformanceSimulated device + throttlingDebug a build before it ships
CrUX / Search Console CWVReal Chrome users, ~28-day windowThe compliance picture
Your RUM (web-vitals library)Your visitors, your pagesDiagnose which template actually fails
PageSpeed InsightsCrUX on top + Lighthouse belowCompare field vs lab on one URL

Optimize LCP says it directly: look at real users first. Lab tools explain why. They do not get to overrule CrUX when the two disagree.

A staging 95 that becomes a field 70 usually means one of these:

  1. Production tags were not in the lab run.
  2. Real phones are slower than the lab CPU throttle you assumed.
  3. Users land cold on the homepage; you tested a warm cache.
  4. The LCP element in the field is not the element you optimized in DevTools.

Test with extensions off. Then test again with the marketing tag soup that will exist in production — and fight to remove the soup. Pair both with a phone in your hand.

Can a brand site stay fast with animations?

Yes, if motion is a budgeted material, not an unlimited overlay. High-performance CSS animations is blunt: keep motion on transform and opacity so work stays on the compositor. Animating top, left, width, height, or filter forces layout or paint. That is how a “subtle” scroll scene melts a mid-range Android after twenty seconds.

The path I use on brand homepages:

  1. Static fold that paints from HTML — type and LCP image visible without JS.
  2. Modern image formats at layout widths, not a 4000px dump.
  3. Fonts loaded with a display strategy you chose on purpose.
  4. JS islands only where interaction needs them.
  5. Motion limited to transform/opacity, with teardown when the scene leaves the viewport.
  6. Measurement on a mid-tier Android, not only on a laptop lab score.
Motion typeUsually fineUsually expensive
One earned hero entrance (opacity + translate)Yes, if LCP text is already visibleHiding the headline until GSAP says go
Hover / focus micro-movesYesHover that triggers layout on every card
One scroll-linked sceneMaybe, if compositor-onlyMultiple scrubbed timelines fighting each other
filter: blur() on scrollAlmost never on mobile—
Decorative WebGL on the homepageRarelyAlways until proven otherwise

If the animation plan requires hiding LCP text until a JS timeline runs, fix the plan. Motion that arrives after the brand is readable is craft. Motion that is the first paint is a metric trap.

Honor prefers-reduced-motion: reduce with a still or a single fade. That is not a performance hack. It is the same craft standard as Accessibility as Craft.

What does LCP want from a cinematic fold?

Largest Contentful Paint is the time from navigation start until the largest image or text block in the viewport is painted. Optimize LCP sets the field target: 2.5 seconds or less for at least 75% of visits.

On brand sites the LCP node is almost always the hero image or the headline block. Optimize that node. Do not optimize a logo that is not LCP while the 2.4MB shoot sits in a CSS background discovered after a stylesheet.

Chrome’s LCP request discovery insight is a three-line brief:

  • Make the LCP image discoverable from the HTML (or preload it).
  • Put fetchpriority="high" on that image or its preload.
  • Do not put loading="lazy" on it.

Fetch Priority explains why: in-viewport images often start at Low priority until layout proves they are visible. That delay is how a “correct” hero still loses 2.5s. An explicit high fetch priority lets the hero start earlier. Do not stamp fetchpriority="high" on three images. Chrome’s own guidance: more than one or two high-priority images makes the hint useless.

Browser-level lazy loading is equally blunt on the fold: lazy-load only what is outside the first viewport. A CMS that auto-applies loading="lazy" to every <img> will punish the hero. Override it.

Fold patternLCP outcomeUse it?
<img> in HTML, sized, AVIF/WebP, fetchpriority="high"Best defaultYes
CSS background-image with <link rel="preload" as="image" fetchpriority="high">WorkableWhen art direction requires a background
Image injected by JS after hydrationLate discoveryNo
Autoplay film as the LCP candidateDecode + bytes taxStill + poster first; see hero video
Headline hidden at opacity: 0 until a timelineText LCP delayed or shifted to a worse nodeNo

TTFB and FCP are diagnostic, not vanity. A large TTFB-to-FCP gap often means render-blocking CSS/JS. A large FCP-to-LCP gap often means the LCP resource was not in the HTML. Read those gaps before you recrop the photograph.

Why does INP punish motion libraries and tag soup?

Interaction to Next Paint measures responsiveness across the page life, not only the first tap. Good is 200ms or less at p75 (web.dev/vitals). Lighthouse cannot click around like a person, so it scores Total Blocking Time instead.

TBT sums the blocking portion of long tasks between FCP and Time to Interactive. A task over 50ms is long. A 70ms task contributes 20ms of blocking. TBT is 30% of the Lighthouse Performance score. That is why a homepage that “looks instant” still lands orange: analytics, chat, A/B, and a motion runtime ate the main thread before anyone tapped.

First-load guestTypical INP / TBT damageDefault policy
Tag manager + four pixelsHighOne container, delayed, owned
Chat widgetHighClick-to-load after the fold is idle
Motion runtime hydrating the whole pageMedium–highIsland the scene; teardown offscreen
Auto-rotating carouselMediumStatic first slide; enhance on view
Consent banner JSMediumReserved space; no layout thrash
Five social embedsHighFacades; one job per page

Chrome’s TBT doc points at the usual culprits: unnecessary JS parse/execute, unused code, and third-party scripts. On a marketing site those are process failures, not requirements of taste. A 900kb homepage bundle is almost never “the design.” It is a stack that hydrated a brochure.

Top CWV fixes put interactivity in the same conversation as LCP: defer non-critical work so the main thread can answer a tap. Yield long tasks. Do not run a scroll listener that forces layout on every frame.

  • Audit third parties like they cost rent.
  • Split the motion bundle from the page shell.
  • Hydrate carousels, forms, and scenes on visibility or interaction.
  • Kill duplicate tags. Two analytics snippets is not “coverage.”
  • Re-check INP in the field after marketing adds “just one pixel.”

How do you stop CLS without flattening the layout?

Cumulative Layout Shift is unexpected movement. Good is 0.1 or less (web.dev/vitals). Brand sites fail CLS in boring ways: webfont swap on a three-line headline, a consent bar that shoves the hero, an embed that opens at 0×0 then becomes 16:9, a sticky announcement injected after paint.

Reserved space is design. It is not a compromise that makes the page “less cinematic.” A fold that jumps under a thumb feels cheap. A fold that holds its geometry while media arrives feels expensive.

CLS sourceFixDo not
Images / video postersWidth + height or aspect-ratio boxesNaked <img> with no box
WebfontsMetric-matched fallback + display strategySwap a condensed display face onto a system sans with no @font-face override
Consent / promo barsReserve a slot or use an overlay that does not shoveInject 72px after first paint
EmbedsSized iframe or facade with the same box“The player will fill in”
Web fonts + late CSSPreload the face that styles the LCP textFour families, eight weights, discovered in a CSS file at the bottom

Top CWV also flags layout-inducing animations as a CLS (and INP) problem. Animate transform. Do not animate properties that reflow the page, especially in response to a tap.

Set sizes. Avoid injecting sticky bars after load without a reserved slot. Coordinate legal and marketing before launch — last-minute banner installs are a classic vitals regression, not a surprise.

What image pipeline can designers live with?

Designers should see weight budgets the way they see color tokens. A “small tweak” that swaps in an uncompressed shoot can erase a week of performance work. The pipeline is the constraint that keeps the photograph.

SlotStarting budget I put in a sprint briefNotes
Hero / LCP stillAgree a cap in the brief (often well under 300KB in AVIF/WebP at 1x/2x)Art-direct the crop; do not ship unused pixels
Below-fold stillsSmaller; lazy-loadSame format rules
Decorative texturesTiny, or CSSNot a 2MB PNG grain overlay
Poster for optional videoOptimized still that is LCPVideo is extra, never the first paint

Rules that survive contact with a brand shoot:

  • Prefer AVIF/WebP with a fallback when the audience needs it.
  • Widths match the layout (1x/2x), not 4000px everywhere.
  • Hero is prioritized. Below-fold is lazy. Never reverse that.
  • Art-direct crops so you are not shipping the unused edges of a horizontal frame into a vertical phone slot.
  • Avoid PNG for photographic heroes. PNG is for sharp UI and type-on-transparent, not a grade of a live set.

If the creative requires a 4K film loop behind type, admit the metric cost or change the creative. I do not publish invented “42 to 99 overnight” stories. The honest pattern: remove accidental weight, protect the LCP path, budget motion, re-check on a phone.

How should brand fonts load without invisible text?

Two families is enough for most marketing sites. Display plus body. Extra weights are how a type system becomes a network problem.

Font best practices maps font-display to block and swap periods. That table is the decision, not a vibe:

font-displayBlockSwapBrand-site use
swap0msInfiniteDistinctive display faces, if you preload and metric-match the fallback
optional~100msNoneBody text you can live without on the first visit
fallback~100ms~3sCompromise when swap is too jumpy
block2–3sInfiniteRare; FOIT risk. Pair with preload if you insist
autoBrowser-definedBrowser-definedDo not leave this to chance on a headline

Optimize web fonts notes that swap shows text immediately and can shift the layout if fallback metrics differ. optional avoids that shift and may skip the webfont on a slow first visit. Preload + optional is the Chrome-documented path to kill FOIT and much of the swap jump when the face is actually needed.

Preload critical assets is the other half: preload the face that styles LCP text, not every weight in the kit. A preload without crossorigin on a font is ignored. Do not preload six files “just in case.”

  • Preconnect to the font CDN if you do not self-host.
  • Subset when you control the files.
  • Prefer a variable font when it reduces total bytes, not when it is a fashion choice that ships a heavier file than two static cuts.
  • Design the fallback stack so swap is not a layout explosion — size, line-height, and size-adjust / metric overrides belong in the type PR, not in a post-launch hotfix.

Invisible text during font load hurts UX and metrics. If the LCP node is a webfont headline, font-display other than auto/block keeps that text visible so LCP is not blocked on the extra request — optimize LCP calls this out.

How much JavaScript does a marketing homepage actually need?

Ship HTML for the story. Hydrate the pieces that must move.

NeedShipDo not ship on first load
Brand story + offerHTML + CSSA client-rendered shell that paints a blank stage
CarouselFirst slide in HTMLThe whole slider runtime before paint
FormNative form, enhance laterA 200kb forms framework for three fields
Motion sceneCSS or a scoped islandA page-wide timeline that imports the kitchen sink
AnalyticsOne delayed, owned containerFour tags “because the last vendor left them”

Astro and other static-first shells make high scores easier because HTML arrives complete. Framer and Webflow can still perform when you are disciplined with assets and interactions; they punish carelessness faster. Custom React SPAs can hit 90+ but you earn it with islands, code splitting, and ruthless dependency control. None of those stacks is a moral position. They are different places the weight hides.

Preload key requests exists because JS often hides CSS and images behind a download-parse-execute chain. If the LCP image is only known after app.js runs, you already lost. Put the image in the HTML or preload it from the document head.

What should you cut first when scores slip?

Resist random thrashing. Bytes first, third parties second, layout third, motion last.

PriorityCut or fixWhy it is first
1Ambient / autoplay videoDecode + bytes + main thread; see hero video
2Extra webfont weights and unused familiesCheap win; often the CLS and LCP hit you ignored
3Chat and extra pixels on first loadTBT / INP
4Auto-carouselsTimers + images you did not ask for
5Scroll libraries fighting each otherMain-thread + layout
6Decorative WebGLGPU + JS for a texture you could still
7Duplicate analytics tagsFree, and somehow always there

What not to cut first: readable type contrast, real photography that defines the brand, or primary CTA clarity. Performance theater that deletes the brand is not a win. Teams that start by deleting photography to chase a two-point gain usually regret it — and still have a 400kb JS problem they did not look at.

Failure mode I see on cinema-grade marketing sites: the fold is a JS-owned stage. The photograph is fine. The type is fine. Nothing paints until a bundle, a font kit, and a timeline agree. Lab LCP looks “close.” Field LCP is a different element, or a late one. The fix is not “less design.” The fix is HTML for the still + type, then motion as a layer.

A second failure mode is the 100-or-else recap. Someone pastes a desktop 98 into Slack, marketing adds a chat widget the same afternoon, and the phone experience is the one nobody recorded. The score was never the product. The fold that paints, the tap that answers, and the layout that holds are the product. If a two-point lab gain requires deleting the image that is the brand, you are optimizing the PDF.

Do not start a rescue by restyling the logo. Start by naming the LCP node, the long tasks, and the layout jumps. Those three names usually tell you whether the problem is design or residue.

When is hero video or WebGL the wrong spend?

When the still already does the job, or when mobile cannot pay the tax.

Autoplay background video is LCP poison if the video frame becomes the largest element or if the download starves the poster. The spoke that owns that decision is Hero Video Slowing Your Site: poster carries LCP, mobile defaults to still or tap-to-play, loop stays muted and short. This post will not re-litigate encoding. It will say: if you need a 4K loop to “feel premium,” try a graded still plus compositor motion first.

WebGL and heavy canvas are the same conversation with a different GPU bill. A decorative particle field on a homepage is rarely the offer. It is a demo. Demos belong in a lab tab or a campaign microsite with an explicit metric waiver.

SpendEarns its keep whenWrong spend when
Graded still + CSS/GSAPAlways the defaultYou skipped it to jump to video
Short muted loopPoster is LCP; mobile is stillSame file on a phone over LTE
WebGL sceneThe product is the sceneIt is wallpaper behind a CTA
Full music video in the heroThe page’s job is the videoThe page’s job is a booking or a listen

Dark cinematic UIs do not automatically score better or worse. Near-black can hide compression artifacts, which sometimes lets you use a smaller still. That is a craft bonus, not a free pass for a 3MB hero film.

YouTube, Maps, calendars, and social embeds are convenience with a cost. Embed best practices and iframe lazy-loading are the primary docs: facade or lazy-load offscreen iframes, and reserve width/height so CLS does not eat the page when the player arrives.

A brand homepage that loads five embeds is a scrapbook. Cut until the page has one job, then bring embeds back behind facades.

EmbedFirst-load policyCLS / INP note
YouTubeClick-to-load facade with posterSized box; no live player in the fold
MapsStatic image linking out, or lazy iframeMaps JS is not a decoration
CalendarBelow fold, lazy, or a linkBooking widgets are INP landmines
Social feedAlmost never on a homepageInfinite scroll inside an iframe is not a composition
ChatIdle or click-to-openDo not hydrate Intercom-class widgets at DOMContentLoaded

Consent banners are frequent CLS offenders. Reserve space or use an overlay that does not shove the hero. Last-minute legal installs before launch are how a green staging build goes orange on Monday.

Third parties cost rent. If marketing cannot name the decision the tag supports, it does not ship on first load.

Should you prefetch and prerender marketing pages?

Sometimes, for the next step you can name. Not for every thumbnail on the work index.

Top CWV describes Speculation Rules prerender as a way to drive next-page LCP toward zero when you guess right. It also says incorrect speculations waste server and client resources. On a media-heavy brand site, aggressive prerender is how you download a second hero film the user never asked for.

IntentReasonableWasteful
Prefetch Work → ContactHigh odds, light targetPrefetch every case study
Prerender the booking page after idleIf analytics say that is the next clickPrerender five campaign films
Prefetch the next article in a seriesMaybePrefetch the whole blog index

Prefer intentional prefetch for the most likely next step. Measure. Marketing sites with heavy media can punish users who were “helped” by speculation. Prefetch is not a substitute for a fast first page.

What optimization order protects the design?

When a brand site scores poorly, work this order. Do not start in Figma deleting the shoot.

  1. Measure the real LCP element in DevTools and, if you have traffic, in field tools. Optimize that asset and the server path first (optimize LCP).
  2. Kill duplicate tags and defer non-critical third parties. This is often the entire INP story.
  3. Fix CLS from fonts, banners, and embeds with reserved space and metric-matched fallbacks.
  4. Reduce JS on the critical path. Move motion and widgets later. Watch TBT.
  5. Re-encode media. Redesign only if the hero concept requires impossible weight.
  6. Then trim motion complexity — compositor-only, one scene, teardown.

CDN and TTFB sit under step 1. A beautiful frontend on a sleepy origin still feels slow. Cache HTML where the architecture allows. Image CDNs help when defaults are sane. Preview deploys should use comparable compression so you do not discover weight only in production.

Give design the constraints up front, in the brief, not in a week-nine “no”:

  • Max hero weight
  • Max font files
  • Motion budget (scenes, properties, CPU time on mid Android)
  • Embed policy (one player, below fold, facade)

Constraints produce better design than unlimited Figma followed by an engineer saying no. The best brand sites I ship treat performance as part of the aesthetic: snappy feels expensive. That is the same thesis as Websites That Feel Like Films.

Translate vibes into numbers. Example budget I write into a sprint: hero entrance under a stated CPU window on mid Android; motion JS under an agreed cap; no more than one scroll-scrubbed scene on the homepage; image weight caps per slot. When a new idea arrives mid-build, ask which budget line it spends. If the answer is “none, we will just add it,” that is how 90 becomes 70.

When is 90+ the wrong primary KPI?

When the page’s job cannot be a static composition.

A live-event microsite with an unavoidable stream may never match a static brochure. That can be acceptable for a 72-hour campaign if the business goal is the stream. Write the waiver down. Do not pretend the Lighthouse PDF is the product.

Site typePerformance barHonesty check
Evergreen studio / brand / artist siteStrong mobile vitals are part of quality90+ on mobile lab + watch field p75
Campaign with a required live playerPlayer is the job; stills everywhere elseDo not hide a 4MB extra film “for mood”
App-like booking flowINP matters more than a hero scoreDo not ship three chat widgets into checkout
Internal previewLab onlyNever use this screenshot in a recap deck

For evergreen brand and studio sites, strong vitals are part of the product quality bar, not a nice-to-have. For a 72-hour stream, say so. The failure is the team that chases 100 on the stream page by breaking the player, or the team that treats an evergreen homepage like a stream page.

Users judge speed before Lighthouse does. A clear fold that appears quickly feels faster than a blank stage that becomes perfect at 2.5s. Skeleton states help when they are honest. Fake progress bars that stall destroy trust. Optimize for meaningful paint of brand + offer, not only for a green circle in a report PDF.

How do you report the tradeoff to stakeholders?

Show the cost with eyes, not with a single desktop score.

ArtifactWhy it changes the conversation
Mobile Lighthouse before/afterSame form factor they were ignoring
Filmstrip of loadingThey can see the blank stage
Phone recording, one-minute scrollLate jank that a 4s lab run missed
Field CrUX / Search Console, if you have trafficEnds the “but lab is green” argument
Byte table for the hero vs the stillMakes the video tax visible

Stakeholders who approve heavy video need to see the stutter. Often they choose the still + craft move once they watch it. That is not you “winning.” That is the brief getting honest.

Same build, two checklists. Ship only when both pass.

Design

  • Brand readable at the fold
  • Offer / CTA clear without waiting on motion
  • Spacing on the system, not on leftover magic numbers
  • Hover and focus states exist
  • Reduced-motion still exists

Performance

  • LCP node identified and optimized (HTML + priority, no lazy)
  • Lazy boundaries correct below the fold
  • JS partitioned; third parties justified
  • CLS boxes reserved (media, fonts, banners, embeds)
  • Mid-range phone smoke test, full-page scroll, not only the first screen

Mobile CPU is part of the medium. Thermal throttle is real. A page that runs many blur filters will melt frames after twenty seconds even if the first Lighthouse sample looked fine. Scroll the homepage for a minute on device. Jank that appears late still trains users that the brand feels cheap.

Assign an owner after launch. Performance is not a certificate. When marketing adds a pixel, someone re-runs mobile Lighthouse and a phone smoke test. Put it on the monthly checklist beside content updates. Orgs that treat performance as a launch souvenir watch scores decay and then blame “the algorithm” for fewer leads.

On Spurlock Studios website sprints I do not treat Lighthouse as a vanity screenshot. We check mobile on a real phone path before calling the fold done. Hundreds of production sites have not made me worship 100. They have made me worship the fold that paints, the tap that answers, and the layout that holds.

FAQ

Can I have a fast website with animations?

Yes. Keep critical content visible without JavaScript, animate transform and opacity, budget scroll scenes, and optimize media first. Animation is rarely the only score killer — images, fonts, and third parties usually lead. If a timeline hides the LCP node, rewrite the timeline, not the brand.

Which Core Web Vitals matter most for brand sites?

All three at p75: LCP for first impression (≤ 2.5s), INP for interaction quality (≤ 200ms), CLS for layout stability (≤ 0.1), per web.dev/vitals. Brand sites often fail LCP via hero media and fail INP via tag managers and chat. Passing two and failing one still fails the assessment.

Is 90+ on desktop enough?

No. Mobile is the honest run. Desktop-only celebrations are how janky phone experiences ship. Chrome uses different scoring curves for desktop and mobile, and field Core Web Vitals are segmented by device. If you only screenshot a laptop, you do not have a performance bar.

Should I remove all motion to hit 90?

No. Remove unbudgeted motion and layout-inducing properties. Keep micro-interactions and one earned entrance if they do not harm LCP or INP. Blind deletion can make a site feel broken without fixing the real byte problems. Chrome does not ask you to ship a dead page for a 100.

Do Framer and Webflow prevent high Lighthouse scores?

They do not prevent them, but they make asset discipline mandatory. Oversized images and heavy interactions show up immediately. Custom static stacks give more control, not automatic virtue. The score follows the bytes and the main thread, not the logo on the invoice.

How often should we re-run performance checks?

At fold lock, after the motion pass, after marketing tags are added, and after launch. Re-run when a campaign pixel lands. Tags added “just for a campaign” are a classic regression. Lab plus a phone smoke test; field tools once you have traffic.

CTA

Want this bar on a site that still looks like the brand, not a Lighthouse hostage?

Explore custom websites or book a sprint at /contact?intent=websites-sprint.

FAQ

What questions does this article answer?

Can I have a fast website with animations?
Yes. Keep critical content visible without JavaScript, animate `transform` and `opacity`, budget scroll scenes, and optimize media first. Animation is rarely the only score killer — images, fonts, and third parties usually lead. If a timeline hides the LCP node, rewrite the timeline, not the brand.
Which Core Web Vitals matter most for brand sites?
All three at p75: LCP for first impression (≤ 2.5s), INP for interaction quality (≤ 200ms), CLS for layout stability (≤ 0.1), per [web.dev/vitals](https://web.dev/articles/vitals). Brand sites often fail LCP via hero media and fail INP via tag managers and chat. Passing two and failing one still fails the assessment.
Is 90+ on desktop enough?
No. Mobile is the honest run. Desktop-only celebrations are how janky phone experiences ship. Chrome uses different scoring curves for desktop and mobile, and field Core Web Vitals are segmented by device. If you only screenshot a laptop, you do not have a performance bar.
Should I remove all motion to hit 90?
No. Remove unbudgeted motion and layout-inducing properties. Keep micro-interactions and one earned entrance if they do not harm LCP or INP. Blind deletion can make a site feel broken without fixing the real byte problems. Chrome does not ask you to ship a dead page for a 100.
Do Framer and Webflow prevent high Lighthouse scores?
They do not prevent them, but they make asset discipline mandatory. Oversized images and heavy interactions show up immediately. Custom static stacks give more control, not automatic virtue. The score follows the bytes and the main thread, not the logo on the invoice.
How often should we re-run performance checks?
At fold lock, after the motion pass, after marketing tags are added, and after launch. Re-run when a campaign pixel lands. Tags added "just for a campaign" are a classic regression. Lab plus a phone smoke test; field tools once you have traffic.
Sources

Last reviewed

More from this lane

Websites

All →
Start a sprint