How to Keep a Perfect Lighthouse Score With Feedback Widgets and Third-Party Scripts

Tomas Boda7 min read

You spent weeks optimising your site to hit a perfect Lighthouse score. Then marketing asks you to add a chat widget, a feedback tool, and an analytics script — and suddenly you're at 72. Sound familiar? Here's how to add third-party widgets without wrecking your performance metrics.

Why third-party scripts tank your score

Lighthouse measures real user-facing performance: Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), and Interaction to Next Paint (INP). Third-party scripts hurt in three ways:

  1. Render blocking — synchronous scripts in the <head> delay first paint.
  2. Main thread contention — heavy JavaScript execution blocks user interactions, increasing INP.
  3. Layout shifts — dynamically injected UI elements (chat bubbles, popups) cause unexpected CLS.

The async-first loading pattern

The single most impactful change: ensure every third-party script uses the async or defer attribute. This prevents render blocking entirely.

<!-- Bad: blocks rendering -->
<script src="https://widget.example.com/script.js"></script>

<!-- Good: non-blocking -->
<script src="https://widget.example.com/script.js" async></script>

For widgets that aren't critical to the initial viewport (feedback bars, chat bubbles), use strategy="lazyOnload" in Next.js or defer loading until after the page is interactive.

Budget your JavaScript

Set a third-party JavaScript budget. A good rule of thumb: total third-party JS should stay under 50KB gzipped. Track it in your CI pipeline using Lighthouse CI or bundlewatch.

Typical sizes:
• Google Analytics (gtag.js): ~28KB
• Intercom Messenger: ~200KB 🚨
• Hotjar: ~150–250KB 🚨
• FeedbackBar widget: ~13KB ✓
• Stripe.js: ~40KB

Reserve space to prevent CLS

Any UI element injected after initial paint can cause layout shifts. Mitigate this by:

  • Using fixed-position elements (floating buttons, bottom bars) that don't affect document flow.
  • Pre-allocating space with CSS if the widget appears inline.
  • Delaying widget visibility until the page is fully painted.

FeedbackBar uses a fixed-position floating bar specifically to avoid CLS — it never pushes content around.

Use resource hints

Speed up third-party connections with dns-prefetch and preconnect:

<link rel="dns-prefetch" href="https://cdn.feedbackbar.io" />
<link rel="preconnect" href="https://cdn.feedbackbar.io" crossorigin />

This shaves 100–300ms off the script download by resolving DNS and establishing the TLS connection early.

Audit regularly

Add Lighthouse CI to your deployment pipeline and set performance budgets. Fail the build if a new script pushes your performance score below a threshold. Prevention is easier than remediation.

Key takeaways

  • Always load third-party scripts with async or defer.
  • Budget total third-party JS at under 50KB gzipped.
  • Use fixed-position widgets to avoid CLS.
  • Add resource hints for critical third-party domains.
  • Automate Lighthouse checks in CI to catch regressions early.

Start collecting feedback — free forever

Add a lightweight feedback widget to your site in under 2 minutes. No credit card required.

Get started free