March 3, 2026 · The Pengo Team
Keeping the chat widget under 5KB gzipped
Most chat widgets ship 100-300KB of JavaScript on every page load. Here's how Pengo's facade pattern keeps the initial payload under 5KB - and how to verify it yourself.
#engineering #performance
A chat widget is usually the last third-party script a site owner adds, and often the heaviest. Many popular widgets ship 100–300KB of JavaScript that loads on every page, whether or not the visitor ever opens the chat.
We treated this as a hard constraint rather than a nice-to-have: the snippet a site embeds should be small enough that adding live chat doesn’t visibly hurt Core Web Vitals.
The facade pattern
The embed script (embed.min.js) that a site actually loads is a small facade: it renders the launcher button, listens for the first interaction (click, or a proactive trigger firing), and only then lazy-loads the full widget bundle. Until a visitor actually engages, the page pays almost nothing for having chat installed.
This is the same idea browsers use for things like YouTube embeds - show a lightweight placeholder, defer the expensive part until it’s actually needed.
What “under 5KB” measures
The claim is specifically about the facade/embed script, gzipped, not the full widget bundle that loads after interaction (that one is heavier, because it has to render an entire chat UI). We track this in CI and on a public benchmark page so it’s not just a number in a blog post.
You can verify the current size yourself at app.pengo.chat/performance - a self-triggering test that measures the actual bytes over the network. Competitor widget sizes drift over time, so anything we or anyone else claims is worth re-checking live rather than trusting a static number.
Why this matters more than it seems
Widget weight compounds with everything else on the page - analytics scripts, ad tags, font loaders. A support tool’s job is to help conversion, not quietly tax it with an extra few hundred KB of unused JavaScript sitting on every pageview.