Why did PageSpeed Insights jump overnight? (Lighthouse 13.6, site unchanged)
Lighthouse 13.6.0 shipped on 27 October 2026. Within about a week, PageSpeed Insights was running that build. The change is not a new weight table for the Performance score. It is a change to Lantern, the model that estimates how a fast capture would look under mobile throttling. Simulated First Contentful Paint and Largest Contentful Paint get closer to reality, and Barry Pollard noted that scores often come out higher, especially on JavaScript-heavy pages.
So a URL can show a different lab Performance score when the HTML, CSS, and scripts are the same as yesterday. That is awkward for anyone who keeps saved PageSpeed Insights screenshots for clients. The useful question is not “did Google make us faster?” It is “are we comparing two Lighthouse versions, or two states of the site?”
What follows is a short path through that question: what Lantern changed, where the Lighthouse version appears on the PageSpeed Insights card, why field CrUX will not move with the lab score, and what usually belongs in the client note. For the longer scoring guide on our monitoring blog, see Google Lighthouse Score Explained: How Scoring Works. For why one-off reports still sit poorly next to a schedule, see PageSpeed Insights vs Automated Monitoring.
What Lighthouse 13.6 changed in the lab simulation
PageSpeed Insights loads the page quickly, then Lantern estimates how that load would behave on a slower mobile profile. Until 13.6, that estimate relied heavily on fetch priority to decide what blocked rendering. Lantern now prefers Chrome’s own render-blocking label for each request, and only falls back to priority when that label is missing.
A second change affects pages whose Largest Contentful Paint is text in the same frame as first content. Lantern now estimates that LCP from the same request and task set it uses for FCP, instead of folding in a wider set of earlier work that could push simulated LCP later. Ivan Akulov’s Framer example showed how the old model could punish useful module and font preloads; the Lighthouse team closed that class of issue in the 13.6 Lantern upgrade.
None of that rewrites CrUX. It rewrites the lab timings that feed the weighted Performance score. When an overnight jump sits on a JavaScript-heavy template or a text-first above-the-fold block, the simulator is usually the first place to look before crediting a release.
How to tell a simulation jump from a real site change
The two PageSpeed Insights reports under discussion each name a Lighthouse version next to the emulated device. When one says 13.5.x and the other says 13.6.0, the runs are not on the same measurement. Part of the Performance difference may be Lantern, not a code change.
Three questions usually settle the case:
1. Did the site change? Same commit, same CDN purge window, same tag-manager container? If nothing moved, simulation is the more likely explanation.
2. Did FCP or LCP move more than Total Blocking Time or CLS? Lantern’s 13.6 notes centre on simulated paint. A swing that is mostly Total Blocking Time still points at main-thread work.
3. Does field data agree? The CrUX block on the same PageSpeed Insights page still covers a rolling window of real Chrome visits. It will not jump overnight because Lantern changed.
If modulepreloads or font preloads were removed earlier to improve a lab colour band, it is worth running the same URL again on 13.6 before leaving them out. A preload that helped real visits may no longer cost as much in the lab. Image LCP is a different story: work that finishes before the image paints can still stretch simulated LCP.
Lab scores and field CrUX after the update
Lab Performance is one controlled navigation under a fixed profile. Field Core Web Vitals are percentiles from eligible Chrome users. Both can mention LCP; only the lab score folds Speed Index and Total Blocking Time into a 0–100 blend with documented weights.
A higher lab Performance score after 13.6 does not mean Search Console’s Core Web Vitals report improved. Google’s field status still comes from CrUX, not from the Lighthouse Performance integer. Claiming “we gained twelve points overnight” without naming the Lighthouse version credits a lab change the field never showed.
Charts that track only the lab Performance score will show a step at the PageSpeed Insights roll-out, so that step belongs as a note on the monitoring board. Metric budgets (LCP, INP, CLS, and lab Total Blocking Time where you use them) on the same URLs still give engineering a clear ticket when the Performance score improves while visitor experience does not.
What to put in the client note
A short, honest note usually beats a celebration deck:
- PageSpeed Insights now runs Lighthouse 13.6.0, which changed how simulated FCP and LCP are estimated.
- Our lab Performance score moved on [URL] between [date A] and [date B]; versions were [x] then [y].
- Field CrUX on the same report [moved / did not move] for LCP, INP, and CLS.
- We keep the same URLs on a short schedule so the next comparison uses one Lighthouse minor and a dated trail.
That is enough for most account threads. When someone wants the weight table and calculator path, the Watcher scoring guide linked above already names the Lighthouse 10 weights and the version footnote, so a second methodology essay in Slack is rarely needed.
FAQ
Can PageSpeed Insights scores rise when the site has not changed?
Yes. When PageSpeed Insights upgrades the Lighthouse build (for example to 13.6.0), Lantern can change simulated FCP and LCP even if HTML and assets are identical. Matching the Lighthouse version on both reports and reading the field block usually comes before attributing the jump to a release.
Is a higher lab score better for SEO ranking?
Not by itself. Lab Performance is a diagnostic blend. Field Core Web Vitals (via CrUX and Search Console when eligible) are the experience signals Google documents for page experience. The Performance score stays useful as engineering context.
Why did my local DevTools Lighthouse disagree with PageSpeed Insights?
Version, throttling preset, and machine noise all differ. Matching Lighthouse versions before comparing, and preferring a short schedule of the same live URLs over two one-off screenshots, usually closes that gap. That is a monitoring problem as much as a scoring problem.
CTA
Before the next client email about an overnight PageSpeed Insights jump, it is usually enough to match the Lighthouse versions, read the field block, and keep the same live URLs on a short schedule so LCP, INP, and CLS still have dates beside the Performance score. The scoring walkthrough lives in Google Lighthouse Score Explained: How Scoring Works. The schedule argument is in PageSpeed Insights vs Automated Monitoring.
References
- Lighthouse 13.6.0 release notes (Lighthouse project)
- PageSpeed Insights Scores May Rise After Lighthouse Update (Search Engine Journal)
- Lighthouse variability (Lighthouse project)
- Lighthouse performance scoring (Chrome for Developers)
- Google Lighthouse Score Explained: How Scoring Works (Apogee Watcher)
- PageSpeed Insights vs Automated Monitoring (Apogee Watcher)
@PhotonHQ @vercel Framer perf engineer here. Some of it is Lighthouse incorrectly giving bad scores (see lighthouse#16539, fixed just last week), but some is great feedback, thank you. We’ll fix
3 likes · 124 views
Find the element causing WordPress layout shift
Originally published at hamzaahmadaslam.com.
How this article was made: drafted with AI assistance from a researched brief, then checked against primary documentation before publishing.
A WordPress layout shift is a moving-page problem, so start by capturing the shift event before changing CSS, fonts, plugins, or cache settings. Reproduce one visible jump, use Chrome to identify the elements that moved, then trace upward to the content or style change that pushed them.
How to trace a WordPress layout shift to the element
Open the affected URL in a clean browser session and reproduce the same path a visitor takes. Test a cold load first, then scroll, open the mobile menu, dismiss banners, and trigger any content that appears after load.
Chrome's Performance panel shows live CLS plus a Layout shifts table. A recorded trace also gives you the Layout shifts track. Since Chrome 131, that track uses purple diamonds, groups nearby shifts into clusters, and shows timings, scores, shifted elements, and possible culprits in the Summary view. The Chrome 131 DevTools notes document that panel change.
Start with the largest cluster you can reproduce. Click an individual shift and inspect the highlighted elements. Treat that list as evidence of what moved, not automatic proof of what caused the movement. An element inserted above a paragraph can push the paragraph down, so the paragraph may be listed even though the inserted element caused the shift.
A trace lets you fix WordPress CLS at the source instead of changing unrelated layout settings.
Capture each shift in the console
For a load-time shift, let the page finish the load you want to inspect, then paste this local diagnostic into DevTools Console. buffered: true gives the observer layout-shift entries that were recorded before the observer started.
For post-load shifts, such as banners, scrolling, or menu changes, paste it before triggering the behavior. Pasting the snippet and then reloading does not preserve it because navigation discards that page's JavaScript context.
const shiftObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.hadRecentInput) continue;
console.group(
`Layout shift at ${entry.startTime.toFixed(1)} ms, value ${entry.value}`
);
for (const source of entry.sources ?? []) {
console.log(source.node, {
previousRect: source.previousRect,
currentRect: source.currentRect,
});
}
console.groupEnd();
}
});
shiftObserver.observe({ type: 'layout-shift', buffered: true });
hadRecentInput lets the diagnostic skip shifts close to qualifying user input. The LayoutShift reference defines that window as less than 500 milliseconds.
This snippet logs individual layout-shift entries. Do not add their values and call the result CLS. CLS uses the largest session window, where shifts are grouped with less than one second between them and a maximum window length of five seconds. Google's CLS optimization guide also warns that a shifted element may be the victim rather than the root cause.
Use attribution when the bad case happens only for visitors
The current web-vitals attribution build can identify the first shifted element, in document order, from the largest individual shift that contributed to CLS. It can also report that shift's time, value, and document load state.
A console version is useful only for local debugging. Its output stays in that browser's console, so it does not collect evidence from visitors. If your WordPress theme or plugin already has an npm build step, the local diagnostic can use the package import:
import { onCLS } from 'web-vitals/attribution';
onCLS(({ value, attribution }) => {
console.log({
cls: value,
target: attribution.largestShiftTarget,
time: attribution.largestShiftTime,
shiftValue: attribution.largestShiftValue,
loadState: attribution.loadState,
});
}, { reportAllChanges: true });
The bare web-vitals/attribution specifier is intended for application code processed by an npm and Node-based build tool. It will not resolve by itself in a typical directly enqueued WordPress script, and that static import is not a DevTools Console snippet.
For a live site without that build process, do not make the CDN example in the README a production dependency. The README says npm with a build process is the recommended route and shows unpkg, jsDelivr, and cdnjs only as examples. It says self-hosting the built files is better for security, reliability, and performance.
Instead, choose and pin the exact web-vitals 5.x release you intend to deploy. Copy its dist/web-vitals.attribution.js file into your theme or plugin and serve it from your own domain. WordPress introduced wp_enqueue_script_module() in version 6.5 for enqueueing script modules, so it can load a local collector module on supported WordPress versions.
The local paths below are illustrative. A collector module can import the self-hosted file rather than a floating @5 CDN URL:
import { onCLS } from './vendor/web-vitals.attribution.js';
onCLS(({ id, value, delta, attribution }) => {
const body = JSON.stringify({
id,
value,
delta,
largestShiftTarget: attribution.largestShiftTarget,
largestShiftTime: attribution.largestShiftTime,
largestShiftValue: attribution.largestShiftValue,
loadState: attribution.loadState,
});
navigator.sendBeacon('/analytics', body);
});
The /analytics path is illustrative. Replace it with an endpoint you control and that is designed to receive these records. If you use a CDN for a temporary diagnostic instead, pin an exact package version rather than the floating @5 range.
This visitor-data version sends the metric instead of writing it to each visitor's console. It leaves reportAllChanges off because the current web-vitals documentation says that option is useful for debugging but is generally unnecessary and not recommended for production measurement.
Leaving that option off does not guarantee one callback per page load. The README says a metric callback can be called more than once. CLS should be reported whenever the page's visibility state changes to hidden, and metrics are reported again after a back/forward cache restore. A restored page gets a new metric id because the library treats that restore as a separate page visit.
Keep the id with every report. If your endpoint stores the full value, keep the latest value for each id instead of counting every callback as a separate metric. If you store delta instead, sum the deltas that share an id. That prevents repeated reports for one metric instance from skewing your visitor data.
Separate late content from font and styling changes
Once the trace gives you a time and a moved element, inspect what changed immediately before it. For this workflow, group WordPress layout shift causes into three buckets: late content, font metrics, or a styling change.
| Evidence in the trace | Likely cause | What to inspect next |
| --- | --- | --- |
| A banner, ad, embed, related-content box, or notice appears above moved content | Late content | Find the theme, plugin, tag, or custom script that inserts it. Check whether its container had space before insertion. |
| Text changes width, line breaks, or block height when a font request completes | Font metrics | Compare the fallback and final font. Check family, weight, line height, and font metric overrides. |
| The same DOM remains, but a header, menu, or content wrapper changes size after a class or stylesheet takes effect | Styling change | Compare computed styles before and after the shift. Check breakpoint rules, sticky-header states, and delayed CSS. |
A web font can change layout because the fallback glyphs have different metrics. A line that fit before the font swap can wrap after it, moving everything below. The web.dev guidance recommends a suitable fallback and, when needed, metric controls such as size-adjust, ascent-override, descent-override, and line-gap-override.
Late content needs a different fix. If an ad, banner, embed, or popup enters normal document flow after paint, give its slot room before the content arrives. If an overlay does not need to push the page, keep it outside normal flow and confirm that it does not move existing visible content.
Use an annotated demo before changing the theme
The following artifact is illustrative. It creates a late banner above text so you can see what the trace is meant to reveal. The timer and dimensions are illustrative values, not measurements from a site.
<style>
.demo-slot { background: #f3f3f3; }
.demo-banner {
min-height: 64px;
display: grid;
place-items: center;
}
</style>
<div class="demo-slot" id="demo-slot"></div>
<p id="demo-copy">
Illustrative paragraph that should move when late content is inserted above it.
</p>
<script>
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.hadRecentInput) continue;
console.log('Illustrative shift', entry.value, entry.sources);
}
}).observe({ type: 'layout-shift', buffered: true });
setTimeout(() => {
document.querySelector('#demo-slot').innerHTML =
'<div class="demo-banner">Illustrative late banner</div>';
}, 1500);
</script>
Expected: the paragraph moves when the banner is inserted. The trace may name #demo-copy because it moved, even though #demo-slot is the cause.
Now fix the symptom by reserving the illustrative banner height before insertion:
.demo-slot {
min-height: 64px;
background: #f3f3f3;
}
Expected after the change: inserting the same illustrative banner no longer pushes the paragraph. On a production site, do not copy 64px blindly. Reserve the space required by that component at each breakpoint.
Reserve space without locking the layout
Use the smallest constraint that keeps the initial layout stable.
For known media or responsive embeds, an aspect ratio can reserve shape without forcing one fixed height:
.embed-slot {
width: 100%;
aspect-ratio: 16 / 9;
}
For content whose height can grow, min-height is often safer than height. It reserves a floor but still lets longer text, translated text, larger user fonts, or a taller ad expand.
For a mobile header, reserve the header's initial closed-state height at the mobile breakpoint. Then inspect the logo, menu button, font swap, and sticky state separately. If the header grows only on mobile, inspect breakpoint-specific styles and content wrapping that the desktop layout does not use.
Do not treat every visible movement as measured CLS. Existing elements that are visible within the viewport and change their start position between two frames create layout-shift entries. Web.dev calls these unstable elements. Movement outside the viewport does not create a layout-shift entry.
A new element appearing does not count by itself unless it moves existing visible content. Shifts within 500 milliseconds of qualifying discrete input can be excluded. Scrolls, drags, and pinch gestures do not get that same recent-input treatment. Transform animations can move pixels without creating layout shifts because they do not run through layout.
There is also a measurement limit around iframes. Page-level Web APIs cannot see layout-shift entries inside an iframe, while CrUX can include iframe movement in the user experience. Keep that gap in mind when an embedded ad or widget looks unstable but your page script cannot attribute it.
Verify mobile and late interactions for regressions
A load-only test is not enough. Field CLS covers the page's full life, while a basic lab run usually focuses on initial load. The lab and field data guide explains why controlled tests and visitor data can disagree.
Use the same procedure before and after the fix. Every row below is illustrative, and each result is written as an expected outcome rather than an observed result.
| Illustrative test | Procedure | Expected result |
| --- | --- | --- |
| Cold mobile load | Start with a fresh cache state, emulate the affected mobile layout, reload, and capture a trace | No unexpected shift cluster from the header, font swap, banner, or reserved slot |
| Cold desktop load | Reload at the desktop layout with the same content | The fix does not add excess blank space or new wrapping |
| Mobile menu | Open and close the menu, then keep the page open | Menu behavior stays usable and no delayed shift appears after the interaction window |
| Scroll to late content | Scroll to ads, embeds, related content, or lazy sections | Reserved containers keep surrounding content in place |
| Font completion | Reload with a fresh browser cache and watch font requests | Final font rendering does not change line breaks enough to move surrounding content |
| Delayed banner or popup | Trigger the same state that inserts the component | The component overlays or fills reserved space without pushing existing content |
If the Lighthouse lab diagnostics in PageSpeed Insights look clean but field CLS from PSI's real-user data, Search Console, or your own RUM data remains high, compare the interaction path, viewport, and field population before making another CSS change. Post-load shifts are one common reason the numbers differ.
Use the next trace to choose the right fix
If the trace points to the main image loading late rather than a moving layout box, continue with WordPress LCP image optimization. If your local trace and visitor data disagree, use why PageSpeed and visitor performance disagree to compare the measurements. If the cause spans theme CSS, plugin JavaScript, fonts, and responsive behavior, WordPress performance optimization is the relevant service path.
@JosepiBuildsIt yea, sadly, that still makes LCP artificially worse: lighthouse#16539
3 likes · 61 views
Sadly, one other improvement I hoped for didn’t make it: lighthouse#16539 t.co
3 likes · 161 views
I wasn't following the history completely, as this all took a while, but IIUC it started with this:
lighthouse#16539
Which led to this (amongst other things):
lighthouse#16782
Which Connor finished off as:
chromium-review.git.corp.google.com
2 likes
Lighthouse 13.6 Can Raise PageSpeed Insights Scores Without a Site Change
PageSpeed Insights scores can change because the testing model changes, not only because a website becomes faster. That distinction matters following Lighthouse 13.6.0, which updates the simulation and tracing work used to produce Lighthouse lab results.
The release can be particularly relevant for JavaScript-heavy pages, where improved navigation handling and estimates for Largest Contentful Paint (LCP) and First Contentful Paint (FCP) may produce different results from earlier Lighthouse versions. A higher Performance score is useful context, but it is not, by itself, evidence that real visitors experienced a faster page.
For SEO teams, agencies, and publishers that use PageSpeed Insights (PSI) in recurring reporting, the immediate task is to identify the Lighthouse version behind a report and separate tool-driven score movement from changes caused by development work.
What changed in Lighthouse 13.6
Lighthouse 13.6.0 was released on October 27, 2026. According to the official Lighthouse 13.6.0 release notes, the release includes updates to Lighthouse's tracing model, improvements to navigation handling, and revised LCP and FCP estimation.
Lighthouse uses a controlled lab environment to load and evaluate a page. Its Lantern model estimates how a page would perform under simulated conditions. Changes to that model can alter timings, opportunities, diagnostics, and the weighted score derived from them, even when the tested URL and its deployed code are unchanged.
Search Engine Journal reported that PSI now runs Lighthouse 13.6.0 and noted that the updated simulation can produce higher lab scores on JavaScript-heavy sites. The release notes indicated that the update was expected to reach Chrome DevTools and PSI within roughly a week, while Chrome 159 stable deployment was scheduled for early December 2026.
The practical point is not that every score will rise. Results can move in either direction depending on a page's loading behavior and the way the revised model interprets it. The update means that direct comparisons with reports generated under earlier Lighthouse versions require more care.
Why lab scores and field data can tell different stories
PageSpeed Insights presents two related but different types of performance evidence:
- Lab data is a single controlled Lighthouse test. It is useful for diagnostics, reproducing issues, and assessing the likely effect of a technical change.
- Field data comes from the Chrome UX Report (CrUX), where available. It reflects aggregated experiences from real Chrome users over time and is the more relevant measure of how users actually encountered the site.
A Lighthouse simulation update affects lab reporting directly. It does not retroactively change how users' devices, networks, and browsers performed in the field. That is why a new PSI score should not automatically be presented as a user-experience improvement.
This does not make lab data unimportant. Lab reports remain valuable because they provide actionable diagnostics that field datasets generally cannot provide for an individual page load. However, lab results are model outputs. They should be interpreted alongside field metrics rather than substituted for them.
For example, a team might see an LCP-related lab improvement after Lighthouse 13.6 and assume its recent code release solved a rendering problem. Before drawing that conclusion, it should check whether the page changed, whether the test used a new Lighthouse version, and whether CrUX data later indicates a corresponding shift in real-user LCP.
A better way to compare PageSpeed Insights reports
Version-aware reporting is the simplest protection against misleading before-and-after comparisons. Record the Lighthouse version whenever an audit is exported, added to a dashboard, or used as the baseline for a performance project.
<table>
<thead>
<tr>
<th scope="col">Question</th>
<th scope="col">What to check</th>
<th scope="col">Why it matters</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Did the site change?</th>
<td>Deployments, templates, scripts, CDN settings, and third-party tags</td>
<td>Confirms whether there is a plausible on-page cause for a result change.</td>
</tr>
<tr>
<th scope="row">Did the test method change?</th>
<td>The Lighthouse version shown in the report</td>
<td>Separates model changes from website changes.</td>
</tr>
<tr>
<th scope="row">Did users see a change?</th>
<td>Available CrUX field metrics and their reporting period</td>
<td>Tests whether the movement is reflected in real-user experience.</td>
</tr>
<tr>
<th scope="row">Is the result repeatable?</th>
<td>Multiple comparable lab runs</td>
<td>Reduces the risk of treating normal test variation as a trend.</td>
</tr>
</tbody>
</table>
When communicating results, it is reasonable to state that a lab score changed after an auditing-model update. It is less accurate to claim a performance win unless the evidence also includes a documented site change and, where available, supporting field-data movement.
This is especially important for agency reporting and executive dashboards. A score increase can be encouraging, but the report should identify whether it reflects implementation work, changed measurement methodology, or both. That level of attribution prevents teams from taking credit for a tooling shift and helps them focus engineering effort on user-facing issues.
ARD changes are separate from the performance score question
Lighthouse 13.6 also updates its Agentic Resource Discovery (ARD) audit to ARD v0.91. The release replaces ai-catalog.json with ard.json and adds discovery sources including Link headers, rel="ard", and /.well-known/ard.json.
ARD concerns how resources can be discovered by agentic systems. It is distinct from the Lighthouse Performance score and should not be treated as a conventional ranking or Core Web Vitals signal. Still, the update is relevant to teams preparing content and technical infrastructure for AI-driven discovery.
The new audit behavior means websites that are evaluating ARD readiness should revisit any prior implementation assumptions based on ai-catalog.json. A current review should account for the discovery methods recognized in ARD v0.91 and document what has actually been implemented. Because this area is evolving, teams should avoid presenting an ARD audit result as proof of visibility or citation in AI search products.
The release also includes changes to Performance Insight audits, which now populate numericValue and numericUnit using estimated time or byte savings. That can make audit outputs more useful for prioritization, but the savings remain estimates produced by the lab environment.
If a Lighthouse update has made it harder to explain why your performance dashboard moved, create a GEO Search Leads account to begin assessing your website's GEO readiness and identify optimization opportunities across the content and technical signals that shape AI-driven discovery. Use the assessment as a structured starting point, then validate performance conclusions with versioned Lighthouse reports and the field data available for your pages.
Frequently Asked Questions
Did Lighthouse 13.6 make every PageSpeed Insights score higher?
No. The updated tracing and simulation model can change results, particularly on JavaScript-heavy pages, but it does not guarantee a higher or lower score for every URL.
Does a higher PSI score after the update prove that a site is faster for users?
No. A lab-score increase may result from the changed Lighthouse model. Check CrUX field data, where available, and confirm whether a site deployment could explain the difference.
What should be recorded in a performance audit?
Record the tested URL, test date, Lighthouse version, relevant deployment history, and the distinction between lab results and available CrUX field data. This makes future comparisons more reliable.
What changed in Lighthouse's ARD audit?
The audit moved to ARD v0.91, replacing ai-catalog.json with ard.json and adding discovery options such as Link headers, rel="ard", and /.well-known/ard.json.
Is the ARD audit a Google ranking factor or proof of AI search visibility?
No. The supplied release information describes an audit for agentic resource discovery. It does not establish that an ARD result is a Google ranking factor or proof that a site will appear in AI-generated answers.
---
Conclusion
Lighthouse 13.6 is a reminder that performance measurement includes both website behavior and the methodology used to measure it. Treat PSI lab-score changes as a prompt to investigate, not as automatic proof of an optimization result. Versioned audits, repeatable testing, and CrUX field data provide a firmer basis for judging real-world performance progress.
1 reaction
How to configure a Web Performance Budget with Lighthouse CI
Hey folks, it's me again! :)
Today, I would like to share with you how you can use Lighthouse CI to audit various software qualities of your project in Continous Integration but also how you can set up a Web Performance Budget strategy to not ship unintentional regressions.
I used this techique in various kinds of projects and I really liked the outcome of it.
Enjoy!
Problem
In Software Development, we always aimed to develop and ship fast. Nowadays with the growing popularity of AI agents that help us ship code even faster, being able to set certain quality guardrails (i.e. in Continous Integration/Continous Deployment) is essential to maintain software quality.
This is especially visible in the area of Web Performance where we can very easily ship performance regressions by adding a third party script, an unoptimized image or multiple custom fonts.
To maintain good performance and exceptional user experience, we need to find a way to warn us early about unexpected regressions. This is where Lighthouse CI can help us.
Solution
Lighthouse CI is a tool that can be used both in local development as well (and primarily) in the CI GitHub Action. The idea is simple:
1. Define a configuration file
2. Add a GitHub action/step
3. See results and react to them before they reach production
The basic example could just be like following:
name: CI
on: [push]
jobs:
lighthouseci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install && npm install -g @lhci/cli@0.15.x
- run: npm run build
- run: lhci autorun
But this will run the test in a basic setup - in our case we want to add some more configuration that will allow us to define our custom budget, and update it on the go to more restrict setup after time.
ci:
collect:
numberOfRuns: 5
startServerCommand: rails server -e production
url:
- http://localhost:3000/
- http://localhost:3000/pricing
- http://localhost:3000/support
assert:
preset: lighthouse:recommended
assertions:
first-contentful-paint:
- error
- maxNumericValue: 2000
aggregationMethod: optimistic
largest-contentful-paint:
- error
- maxNumericValue: 2500
aggregationMethod: optimistic
cumulative-layout-shift:
- error
- maxNumericValue: 100
aggregationMethod: optimistic
upload:
target: lhci
serverBaseUrl: https://lhci.example.com
This configuration can either be in the yaml,js,json or any other supported format. What is important is that with it, you can be warned early about unexpected regressions and update the budget later to match your needs and goals better.
And if you would like to compare one LHCI result to the previous one to show instant improvements/regressions, here is a great example for that adevinta/actions-lighthouseci-compare
Learn more
Here is the recording of my talk at JS Poland conference where I was talking about this topic (and also a bit about Playwright and Accessibility):
{% embed youtube.com %}
1 reaction
Lighthouse v13.6.0 out, including some fixes to make the simulated network throttling calcs better for LCP / FCP (it could get tripped up by good practices like preloading before)
Read more here: github.com/GoogleChrome/lighthouse/releases
Updated on my fetch & render tool here: tamethebots.com
9 likes · 2 reposts
🚀 [Fastest Growing GitHub Repos] lighthouse: The Free Tool Taking Over GitHub! #shorts
Discover GoogleChrome/lighthouse: Automated auditing, performance metrics, and best practices for the web.
💬 Comment "LIGHTHOUSE" below for the direct link, or grab it from the links below:
👉 Interactive Star History & Live Analysis:
githubrepo.cloud
⭐ Embed Live Verified Badges in your README:
githubrepo.cloud
🔗 Direct GitHub Repository:
GoogleChrome/lighthouse
📊 Repository Specs:
⭐ Stars: 30,916
🍴 Forks: 9,771
💻 Language: JavaScript
📜 License: Apache-2.0
#shorts #lighthouse #audit #bestpractices #chromedevtools #developertools #webdev #javascript #typescript
1 like · 72 views
Mentions
Why did PageSpeed Insights jump overnight? (Lighthouse 13.6, site unchanged) Lighthouse 13.6.0 shipped on 27 October 2026. Within about a week, PageSpeed Insights was running that build. The change is not a new weight table for the Performance score. It is a change to Lantern, the model that estimates how a fast capture would look under mobile throttling. Simulated First Contentful Paint and Largest Contentful Paint get closer to reality, and Barry Pollard noted that scores often come out higher, especially on JavaScript-heavy pages. So a URL can show a different lab Performance score when the HTML, CSS, and scripts are the same as yesterday. That is awkward for anyone who keeps saved PageSpeed Insights screenshots for clients. The useful question is not “did Google make us faster?” It is “are we comparing two Lighthouse versions, or two states of the site?” What follows is a short path through that question: what Lantern changed, where the Lighthouse version appears on the PageSpeed Insights card, why field CrUX will not move with the lab score, and what usually belongs in the client note. For the longer scoring guide on our monitoring blog, see Google Lighthouse Score Explained: How Scoring Works. For why one-off reports still sit poorly next to a schedule, see PageSpeed Insights vs Automated Monitoring. What Lighthouse 13.6 changed in the lab simulation PageSpeed Insights loads the page quickly, then Lantern estimates how that load would behave on a slower mobile profile. Until 13.6, that estimate relied heavily on fetch priority to decide what blocked rendering. Lantern now prefers Chrome’s own render-blocking label for each request, and only falls back to priority when that label is missing. A second change affects pages whose Largest Contentful Paint is text in the same frame as first content. Lantern now estimates that LCP from the same request and task set it uses for FCP, instead of folding in a wider set of earlier work that could push simulated LCP later. Ivan Akulov’s Framer example showed how the old model could punish useful module and font preloads; the Lighthouse team closed that class of issue in the 13.6 Lantern upgrade. None of that rewrites CrUX. It rewrites the lab timings that feed the weighted Performance score. When an overnight jump sits on a JavaScript-heavy template or a text-first above-the-fold block, the simulator is usually the first place to look before crediting a release. How to tell a simulation jump from a real site change The two PageSpeed Insights reports under discussion each name a Lighthouse version next to the emulated device. When one says 13.5.x and the other says 13.6.0, the runs are not on the same measurement. Part of the Performance difference may be Lantern, not a code change. Three questions usually settle the case: 1. Did the site change? Same commit, same CDN purge window, same tag-manager container? If nothing moved, simulation is the more likely explanation. 2. Did FCP or LCP move more than Total Blocking Time or CLS? Lantern’s 13.6 notes centre on simulated paint. A swing that is mostly Total Blocking Time still points at main-thread work. 3. Does field data agree? The CrUX block on the same PageSpeed Insights page still covers a rolling window of real Chrome visits. It will not jump overnight because Lantern changed. If modulepreloads or font preloads were removed earlier to improve a lab colour band, it is worth running the same URL again on 13.6 before leaving them out. A preload that helped real visits may no longer cost as much in the lab. Image LCP is a different story: work that finishes before the image paints can still stretch simulated LCP. Lab scores and field CrUX after the update Lab Performance is one controlled navigation under a fixed profile. Field Core Web Vitals are percentiles from eligible Chrome users. Both can mention LCP; only the lab score folds Speed Index and Total Blocking Time into a 0–100 blend with documented weights. A higher lab Performance score after 13.6 does not mean Search Console’s Core Web Vitals report improved. Google’s field status still comes from CrUX, not from the Lighthouse Performance integer. Claiming “we gained twelve points overnight” without naming the Lighthouse version credits a lab change the field never showed. Charts that track only the lab Performance score will show a step at the PageSpeed Insights roll-out, so that step belongs as a note on the monitoring board. Metric budgets (LCP, INP, CLS, and lab Total Blocking Time where you use them) on the same URLs still give engineering a clear ticket when the Performance score improves while visitor experience does not. What to put in the client note A short, honest note usually beats a celebration deck: - PageSpeed Insights now runs Lighthouse 13.6.0, which changed how simulated FCP and LCP are estimated. - Our lab Performance score moved on [URL] between [date A] and [date B]; versions were [x] then [y]. - Field CrUX on the same report [moved / did not move] for LCP, INP, and CLS. - We keep the same URLs on a short schedule so the next comparison uses one Lighthouse minor and a dated trail. That is enough for most account threads. When someone wants the weight table and calculator path, the Watcher scoring guide linked above already names the Lighthouse 10 weights and the version footnote, so a second methodology essay in Slack is rarely needed. FAQ Can PageSpeed Insights scores rise when the site has not changed? Yes. When PageSpeed Insights upgrades the Lighthouse build (for example to 13.6.0), Lantern can change simulated FCP and LCP even if HTML and assets are identical. Matching the Lighthouse version on both reports and reading the field block usually comes before attributing the jump to a release. Is a higher lab score better for SEO ranking? Not by itself. Lab Performance is a diagnostic blend. Field Core Web Vitals (via CrUX and Search Console when eligible) are the experience signals Google documents for page experience. The Performance score stays useful as engineering context. Why did my local DevTools Lighthouse disagree with PageSpeed Insights? Version, throttling preset, and machine noise all differ. Matching Lighthouse versions before comparing, and preferring a short schedule of the same live URLs over two one-off screenshots, usually closes that gap. That is a monitoring problem as much as a scoring problem. CTA Before the next client email about an overnight PageSpeed Insights jump, it is usually enough to match the Lighthouse versions, read the field block, and keep the same live URLs on a short schedule so LCP, INP, and CLS still have dates beside the Performance score. The scoring walkthrough lives in Google Lighthouse Score Explained: How Scoring Works. The schedule argument is in PageSpeed Insights vs Automated Monitoring. References - Lighthouse 13.6.0 release notes (Lighthouse project) - PageSpeed Insights Scores May Rise After Lighthouse Update (Search Engine Journal) - Lighthouse variability (Lighthouse project) - Lighthouse performance scoring (Chrome for Developers) - Google Lighthouse Score Explained: How Scoring Works (Apogee Watcher) - PageSpeed Insights vs Automated Monitoring (Apogee Watcher)
@PhotonHQ @vercel Framer perf engineer here. Some of it is Lighthouse incorrectly giving bad scores (see lighthouse#16539, fixed just last week), but some is great feedback, thank you. We’ll fix
Find the element causing WordPress layout shift Originally published at hamzaahmadaslam.com. How this article was made: drafted with AI assistance from a researched brief, then checked against primary documentation before publishing. A WordPress layout shift is a moving-page problem, so start by capturing the shift event before changing CSS, fonts, plugins, or cache settings. Reproduce one visible jump, use Chrome to identify the elements that moved, then trace upward to the content or style change that pushed them. How to trace a WordPress layout shift to the element Open the affected URL in a clean browser session and reproduce the same path a visitor takes. Test a cold load first, then scroll, open the mobile menu, dismiss banners, and trigger any content that appears after load. Chrome's Performance panel shows live CLS plus a Layout shifts table. A recorded trace also gives you the Layout shifts track. Since Chrome 131, that track uses purple diamonds, groups nearby shifts into clusters, and shows timings, scores, shifted elements, and possible culprits in the Summary view. The Chrome 131 DevTools notes document that panel change. Start with the largest cluster you can reproduce. Click an individual shift and inspect the highlighted elements. Treat that list as evidence of what moved, not automatic proof of what caused the movement. An element inserted above a paragraph can push the paragraph down, so the paragraph may be listed even though the inserted element caused the shift. A trace lets you fix WordPress CLS at the source instead of changing unrelated layout settings. Capture each shift in the console For a load-time shift, let the page finish the load you want to inspect, then paste this local diagnostic into DevTools Console. buffered: true gives the observer layout-shift entries that were recorded before the observer started. For post-load shifts, such as banners, scrolling, or menu changes, paste it before triggering the behavior. Pasting the snippet and then reloading does not preserve it because navigation discards that page's JavaScript context. const shiftObserver = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (entry.hadRecentInput) continue; console.group( `Layout shift at ${entry.startTime.toFixed(1)} ms, value ${entry.value}` ); for (const source of entry.sources ?? []) { console.log(source.node, { previousRect: source.previousRect, currentRect: source.currentRect, }); } console.groupEnd(); } }); shiftObserver.observe({ type: 'layout-shift', buffered: true }); hadRecentInput lets the diagnostic skip shifts close to qualifying user input. The LayoutShift reference defines that window as less than 500 milliseconds. This snippet logs individual layout-shift entries. Do not add their values and call the result CLS. CLS uses the largest session window, where shifts are grouped with less than one second between them and a maximum window length of five seconds. Google's CLS optimization guide also warns that a shifted element may be the victim rather than the root cause. Use attribution when the bad case happens only for visitors The current web-vitals attribution build can identify the first shifted element, in document order, from the largest individual shift that contributed to CLS. It can also report that shift's time, value, and document load state. A console version is useful only for local debugging. Its output stays in that browser's console, so it does not collect evidence from visitors. If your WordPress theme or plugin already has an npm build step, the local diagnostic can use the package import: import { onCLS } from 'web-vitals/attribution'; onCLS(({ value, attribution }) => { console.log({ cls: value, target: attribution.largestShiftTarget, time: attribution.largestShiftTime, shiftValue: attribution.largestShiftValue, loadState: attribution.loadState, }); }, { reportAllChanges: true }); The bare web-vitals/attribution specifier is intended for application code processed by an npm and Node-based build tool. It will not resolve by itself in a typical directly enqueued WordPress script, and that static import is not a DevTools Console snippet. For a live site without that build process, do not make the CDN example in the README a production dependency. The README says npm with a build process is the recommended route and shows unpkg, jsDelivr, and cdnjs only as examples. It says self-hosting the built files is better for security, reliability, and performance. Instead, choose and pin the exact web-vitals 5.x release you intend to deploy. Copy its dist/web-vitals.attribution.js file into your theme or plugin and serve it from your own domain. WordPress introduced wp_enqueue_script_module() in version 6.5 for enqueueing script modules, so it can load a local collector module on supported WordPress versions. The local paths below are illustrative. A collector module can import the self-hosted file rather than a floating @5 CDN URL: import { onCLS } from './vendor/web-vitals.attribution.js'; onCLS(({ id, value, delta, attribution }) => { const body = JSON.stringify({ id, value, delta, largestShiftTarget: attribution.largestShiftTarget, largestShiftTime: attribution.largestShiftTime, largestShiftValue: attribution.largestShiftValue, loadState: attribution.loadState, }); navigator.sendBeacon('/analytics', body); }); The /analytics path is illustrative. Replace it with an endpoint you control and that is designed to receive these records. If you use a CDN for a temporary diagnostic instead, pin an exact package version rather than the floating @5 range. This visitor-data version sends the metric instead of writing it to each visitor's console. It leaves reportAllChanges off because the current web-vitals documentation says that option is useful for debugging but is generally unnecessary and not recommended for production measurement. Leaving that option off does not guarantee one callback per page load. The README says a metric callback can be called more than once. CLS should be reported whenever the page's visibility state changes to hidden, and metrics are reported again after a back/forward cache restore. A restored page gets a new metric id because the library treats that restore as a separate page visit. Keep the id with every report. If your endpoint stores the full value, keep the latest value for each id instead of counting every callback as a separate metric. If you store delta instead, sum the deltas that share an id. That prevents repeated reports for one metric instance from skewing your visitor data. Separate late content from font and styling changes Once the trace gives you a time and a moved element, inspect what changed immediately before it. For this workflow, group WordPress layout shift causes into three buckets: late content, font metrics, or a styling change. | Evidence in the trace | Likely cause | What to inspect next | | --- | --- | --- | | A banner, ad, embed, related-content box, or notice appears above moved content | Late content | Find the theme, plugin, tag, or custom script that inserts it. Check whether its container had space before insertion. | | Text changes width, line breaks, or block height when a font request completes | Font metrics | Compare the fallback and final font. Check family, weight, line height, and font metric overrides. | | The same DOM remains, but a header, menu, or content wrapper changes size after a class or stylesheet takes effect | Styling change | Compare computed styles before and after the shift. Check breakpoint rules, sticky-header states, and delayed CSS. | A web font can change layout because the fallback glyphs have different metrics. A line that fit before the font swap can wrap after it, moving everything below. The web.dev guidance recommends a suitable fallback and, when needed, metric controls such as size-adjust, ascent-override, descent-override, and line-gap-override. Late content needs a different fix. If an ad, banner, embed, or popup enters normal document flow after paint, give its slot room before the content arrives. If an overlay does not need to push the page, keep it outside normal flow and confirm that it does not move existing visible content. Use an annotated demo before changing the theme The following artifact is illustrative. It creates a late banner above text so you can see what the trace is meant to reveal. The timer and dimensions are illustrative values, not measurements from a site. <style> .demo-slot { background: #f3f3f3; } .demo-banner { min-height: 64px; display: grid; place-items: center; } </style> <div class="demo-slot" id="demo-slot"></div> <p id="demo-copy"> Illustrative paragraph that should move when late content is inserted above it. </p> <script> new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (entry.hadRecentInput) continue; console.log('Illustrative shift', entry.value, entry.sources); } }).observe({ type: 'layout-shift', buffered: true }); setTimeout(() => { document.querySelector('#demo-slot').innerHTML = '<div class="demo-banner">Illustrative late banner</div>'; }, 1500); </script> Expected: the paragraph moves when the banner is inserted. The trace may name #demo-copy because it moved, even though #demo-slot is the cause. Now fix the symptom by reserving the illustrative banner height before insertion: .demo-slot { min-height: 64px; background: #f3f3f3; } Expected after the change: inserting the same illustrative banner no longer pushes the paragraph. On a production site, do not copy 64px blindly. Reserve the space required by that component at each breakpoint. Reserve space without locking the layout Use the smallest constraint that keeps the initial layout stable. For known media or responsive embeds, an aspect ratio can reserve shape without forcing one fixed height: .embed-slot { width: 100%; aspect-ratio: 16 / 9; } For content whose height can grow, min-height is often safer than height. It reserves a floor but still lets longer text, translated text, larger user fonts, or a taller ad expand. For a mobile header, reserve the header's initial closed-state height at the mobile breakpoint. Then inspect the logo, menu button, font swap, and sticky state separately. If the header grows only on mobile, inspect breakpoint-specific styles and content wrapping that the desktop layout does not use. Do not treat every visible movement as measured CLS. Existing elements that are visible within the viewport and change their start position between two frames create layout-shift entries. Web.dev calls these unstable elements. Movement outside the viewport does not create a layout-shift entry. A new element appearing does not count by itself unless it moves existing visible content. Shifts within 500 milliseconds of qualifying discrete input can be excluded. Scrolls, drags, and pinch gestures do not get that same recent-input treatment. Transform animations can move pixels without creating layout shifts because they do not run through layout. There is also a measurement limit around iframes. Page-level Web APIs cannot see layout-shift entries inside an iframe, while CrUX can include iframe movement in the user experience. Keep that gap in mind when an embedded ad or widget looks unstable but your page script cannot attribute it. Verify mobile and late interactions for regressions A load-only test is not enough. Field CLS covers the page's full life, while a basic lab run usually focuses on initial load. The lab and field data guide explains why controlled tests and visitor data can disagree. Use the same procedure before and after the fix. Every row below is illustrative, and each result is written as an expected outcome rather than an observed result. | Illustrative test | Procedure | Expected result | | --- | --- | --- | | Cold mobile load | Start with a fresh cache state, emulate the affected mobile layout, reload, and capture a trace | No unexpected shift cluster from the header, font swap, banner, or reserved slot | | Cold desktop load | Reload at the desktop layout with the same content | The fix does not add excess blank space or new wrapping | | Mobile menu | Open and close the menu, then keep the page open | Menu behavior stays usable and no delayed shift appears after the interaction window | | Scroll to late content | Scroll to ads, embeds, related content, or lazy sections | Reserved containers keep surrounding content in place | | Font completion | Reload with a fresh browser cache and watch font requests | Final font rendering does not change line breaks enough to move surrounding content | | Delayed banner or popup | Trigger the same state that inserts the component | The component overlays or fills reserved space without pushing existing content | If the Lighthouse lab diagnostics in PageSpeed Insights look clean but field CLS from PSI's real-user data, Search Console, or your own RUM data remains high, compare the interaction path, viewport, and field population before making another CSS change. Post-load shifts are one common reason the numbers differ. Use the next trace to choose the right fix If the trace points to the main image loading late rather than a moving layout box, continue with WordPress LCP image optimization. If your local trace and visitor data disagree, use why PageSpeed and visitor performance disagree to compare the measurements. If the cause spans theme CSS, plugin JavaScript, fonts, and responsive behavior, WordPress performance optimization is the relevant service path.
@JosepiBuildsIt yea, sadly, that still makes LCP artificially worse: lighthouse#16539
Sadly, one other improvement I hoped for didn’t make it: lighthouse#16539 t.co
I wasn't following the history completely, as this all took a while, but IIUC it started with this: lighthouse#16539 Which led to this (amongst other things): lighthouse#16782 Which Connor finished off as: chromium-review.git.corp.google.com
Lighthouse 13.6 Can Raise PageSpeed Insights Scores Without a Site Change PageSpeed Insights scores can change because the testing model changes, not only because a website becomes faster. That distinction matters following Lighthouse 13.6.0, which updates the simulation and tracing work used to produce Lighthouse lab results. The release can be particularly relevant for JavaScript-heavy pages, where improved navigation handling and estimates for Largest Contentful Paint (LCP) and First Contentful Paint (FCP) may produce different results from earlier Lighthouse versions. A higher Performance score is useful context, but it is not, by itself, evidence that real visitors experienced a faster page. For SEO teams, agencies, and publishers that use PageSpeed Insights (PSI) in recurring reporting, the immediate task is to identify the Lighthouse version behind a report and separate tool-driven score movement from changes caused by development work. What changed in Lighthouse 13.6 Lighthouse 13.6.0 was released on October 27, 2026. According to the official Lighthouse 13.6.0 release notes, the release includes updates to Lighthouse's tracing model, improvements to navigation handling, and revised LCP and FCP estimation. Lighthouse uses a controlled lab environment to load and evaluate a page. Its Lantern model estimates how a page would perform under simulated conditions. Changes to that model can alter timings, opportunities, diagnostics, and the weighted score derived from them, even when the tested URL and its deployed code are unchanged. Search Engine Journal reported that PSI now runs Lighthouse 13.6.0 and noted that the updated simulation can produce higher lab scores on JavaScript-heavy sites. The release notes indicated that the update was expected to reach Chrome DevTools and PSI within roughly a week, while Chrome 159 stable deployment was scheduled for early December 2026. The practical point is not that every score will rise. Results can move in either direction depending on a page's loading behavior and the way the revised model interprets it. The update means that direct comparisons with reports generated under earlier Lighthouse versions require more care. Why lab scores and field data can tell different stories PageSpeed Insights presents two related but different types of performance evidence: - Lab data is a single controlled Lighthouse test. It is useful for diagnostics, reproducing issues, and assessing the likely effect of a technical change. - Field data comes from the Chrome UX Report (CrUX), where available. It reflects aggregated experiences from real Chrome users over time and is the more relevant measure of how users actually encountered the site. A Lighthouse simulation update affects lab reporting directly. It does not retroactively change how users' devices, networks, and browsers performed in the field. That is why a new PSI score should not automatically be presented as a user-experience improvement. This does not make lab data unimportant. Lab reports remain valuable because they provide actionable diagnostics that field datasets generally cannot provide for an individual page load. However, lab results are model outputs. They should be interpreted alongside field metrics rather than substituted for them. For example, a team might see an LCP-related lab improvement after Lighthouse 13.6 and assume its recent code release solved a rendering problem. Before drawing that conclusion, it should check whether the page changed, whether the test used a new Lighthouse version, and whether CrUX data later indicates a corresponding shift in real-user LCP. A better way to compare PageSpeed Insights reports Version-aware reporting is the simplest protection against misleading before-and-after comparisons. Record the Lighthouse version whenever an audit is exported, added to a dashboard, or used as the baseline for a performance project. <table> <thead> <tr> <th scope="col">Question</th> <th scope="col">What to check</th> <th scope="col">Why it matters</th> </tr> </thead> <tbody> <tr> <th scope="row">Did the site change?</th> <td>Deployments, templates, scripts, CDN settings, and third-party tags</td> <td>Confirms whether there is a plausible on-page cause for a result change.</td> </tr> <tr> <th scope="row">Did the test method change?</th> <td>The Lighthouse version shown in the report</td> <td>Separates model changes from website changes.</td> </tr> <tr> <th scope="row">Did users see a change?</th> <td>Available CrUX field metrics and their reporting period</td> <td>Tests whether the movement is reflected in real-user experience.</td> </tr> <tr> <th scope="row">Is the result repeatable?</th> <td>Multiple comparable lab runs</td> <td>Reduces the risk of treating normal test variation as a trend.</td> </tr> </tbody> </table> When communicating results, it is reasonable to state that a lab score changed after an auditing-model update. It is less accurate to claim a performance win unless the evidence also includes a documented site change and, where available, supporting field-data movement. This is especially important for agency reporting and executive dashboards. A score increase can be encouraging, but the report should identify whether it reflects implementation work, changed measurement methodology, or both. That level of attribution prevents teams from taking credit for a tooling shift and helps them focus engineering effort on user-facing issues. ARD changes are separate from the performance score question Lighthouse 13.6 also updates its Agentic Resource Discovery (ARD) audit to ARD v0.91. The release replaces ai-catalog.json with ard.json and adds discovery sources including Link headers, rel="ard", and /.well-known/ard.json. ARD concerns how resources can be discovered by agentic systems. It is distinct from the Lighthouse Performance score and should not be treated as a conventional ranking or Core Web Vitals signal. Still, the update is relevant to teams preparing content and technical infrastructure for AI-driven discovery. The new audit behavior means websites that are evaluating ARD readiness should revisit any prior implementation assumptions based on ai-catalog.json. A current review should account for the discovery methods recognized in ARD v0.91 and document what has actually been implemented. Because this area is evolving, teams should avoid presenting an ARD audit result as proof of visibility or citation in AI search products. The release also includes changes to Performance Insight audits, which now populate numericValue and numericUnit using estimated time or byte savings. That can make audit outputs more useful for prioritization, but the savings remain estimates produced by the lab environment. If a Lighthouse update has made it harder to explain why your performance dashboard moved, create a GEO Search Leads account to begin assessing your website's GEO readiness and identify optimization opportunities across the content and technical signals that shape AI-driven discovery. Use the assessment as a structured starting point, then validate performance conclusions with versioned Lighthouse reports and the field data available for your pages. Frequently Asked Questions Did Lighthouse 13.6 make every PageSpeed Insights score higher? No. The updated tracing and simulation model can change results, particularly on JavaScript-heavy pages, but it does not guarantee a higher or lower score for every URL. Does a higher PSI score after the update prove that a site is faster for users? No. A lab-score increase may result from the changed Lighthouse model. Check CrUX field data, where available, and confirm whether a site deployment could explain the difference. What should be recorded in a performance audit? Record the tested URL, test date, Lighthouse version, relevant deployment history, and the distinction between lab results and available CrUX field data. This makes future comparisons more reliable. What changed in Lighthouse's ARD audit? The audit moved to ARD v0.91, replacing ai-catalog.json with ard.json and adding discovery options such as Link headers, rel="ard", and /.well-known/ard.json. Is the ARD audit a Google ranking factor or proof of AI search visibility? No. The supplied release information describes an audit for agentic resource discovery. It does not establish that an ARD result is a Google ranking factor or proof that a site will appear in AI-generated answers. --- Conclusion Lighthouse 13.6 is a reminder that performance measurement includes both website behavior and the methodology used to measure it. Treat PSI lab-score changes as a prompt to investigate, not as automatic proof of an optimization result. Versioned audits, repeatable testing, and CrUX field data provide a firmer basis for judging real-world performance progress.
How to configure a Web Performance Budget with Lighthouse CI Hey folks, it's me again! :) Today, I would like to share with you how you can use Lighthouse CI to audit various software qualities of your project in Continous Integration but also how you can set up a Web Performance Budget strategy to not ship unintentional regressions. I used this techique in various kinds of projects and I really liked the outcome of it. Enjoy! Problem In Software Development, we always aimed to develop and ship fast. Nowadays with the growing popularity of AI agents that help us ship code even faster, being able to set certain quality guardrails (i.e. in Continous Integration/Continous Deployment) is essential to maintain software quality. This is especially visible in the area of Web Performance where we can very easily ship performance regressions by adding a third party script, an unoptimized image or multiple custom fonts. To maintain good performance and exceptional user experience, we need to find a way to warn us early about unexpected regressions. This is where Lighthouse CI can help us. Solution Lighthouse CI is a tool that can be used both in local development as well (and primarily) in the CI GitHub Action. The idea is simple: 1. Define a configuration file 2. Add a GitHub action/step 3. See results and react to them before they reach production The basic example could just be like following: name: CI on: [push] jobs: lighthouseci: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 - run: npm install && npm install -g @lhci/cli@0.15.x - run: npm run build - run: lhci autorun But this will run the test in a basic setup - in our case we want to add some more configuration that will allow us to define our custom budget, and update it on the go to more restrict setup after time. ci: collect: numberOfRuns: 5 startServerCommand: rails server -e production url: - http://localhost:3000/ - http://localhost:3000/pricing - http://localhost:3000/support assert: preset: lighthouse:recommended assertions: first-contentful-paint: - error - maxNumericValue: 2000 aggregationMethod: optimistic largest-contentful-paint: - error - maxNumericValue: 2500 aggregationMethod: optimistic cumulative-layout-shift: - error - maxNumericValue: 100 aggregationMethod: optimistic upload: target: lhci serverBaseUrl: https://lhci.example.com This configuration can either be in the yaml,js,json or any other supported format. What is important is that with it, you can be warned early about unexpected regressions and update the budget later to match your needs and goals better. And if you would like to compare one LHCI result to the previous one to show instant improvements/regressions, here is a great example for that adevinta/actions-lighthouseci-compare Learn more Here is the recording of my talk at JS Poland conference where I was talking about this topic (and also a bit about Playwright and Accessibility): {% embed youtube.com %}
Lighthouse v13.6.0 out, including some fixes to make the simulated network throttling calcs better for LCP / FCP (it could get tripped up by good practices like preloading before) Read more here: github.com/GoogleChrome/lighthouse/releases Updated on my fetch & render tool here: tamethebots.com
🚀 [Fastest Growing GitHub Repos] lighthouse: The Free Tool Taking Over GitHub! #shorts Discover GoogleChrome/lighthouse: Automated auditing, performance metrics, and best practices for the web. 💬 Comment "LIGHTHOUSE" below for the direct link, or grab it from the links below: 👉 Interactive Star History & Live Analysis: githubrepo.cloud ⭐ Embed Live Verified Badges in your README: githubrepo.cloud 🔗 Direct GitHub Repository: GoogleChrome/lighthouse 📊 Repository Specs: ⭐ Stars: 30,916 🍴 Forks: 9,771 💻 Language: JavaScript 📜 License: Apache-2.0 #shorts #lighthouse #audit #bestpractices #chromedevtools #developertools #webdev #javascript #typescript