We Re-Tested 5 Chat Widgets in 2026 — Opening Intercom Downloads 833KB
We re-ran our February benchmark with a rebuilt harness: median-of-5 runs, three scenarios, and a metric nobody publishes — what it costs when a visitor actually clicks the chat bubble. Intercom ends up at 1.1MB. Four other widgets downloaded hundreds of KB and rendered no chat at all.
In February we benchmarked five chat widgets and published the numbers. Six months later we rebuilt the harness from scratch and re-ran it — partly to refresh the data, partly because we found three bugs in the original test.
One of them was ours, and it was embarrassing: the February harness measured GhostChat against our staging server while every competitor used their production CDN.
Every widget below was confirmed to actually render a chat bubble before its numbers were used. That sounds obvious. It is the single hardest part of this, and it is why four widgets aren't in the table.
The rebuilt test also measures something we've never seen anyone publish: what it costs when a visitor actually clicks the chat bubble. That turned out to be where the real story was.
Nobody measures the click
Every chat widget benchmark measures page load. But a chat widget has two costs: what it downloads to show you a bubble, and what it downloads when someone actually opens it. Most widgets lazy-load the entire chat interface on that click.
So we clicked every launcher and kept counting.
| Widget | On load | On open | Total | vs us |
|---|---|---|---|---|
| GhostChat | 17.5 KB | +1.4 KB | 18.9 KB | — |
| LiveChat | 43.5 KB | +0 KB | 43.5 KB | 2.3× |
| Crisp | 127.1 KB | +140 KB | 267 KB | 14× |
| Tawk.to | 462.4 KB | +0 KB | 462.4 KB | 24× |
| Intercom | 271.4 KB | +833.3 KB | 1,104 KB | 58× |
Measured August 2026. Lower is better.
271 KB on load, then +833 KB when opened
127 KB on load, then +140 KB when opened
18 KB on load, then +1 KB when opened
Intercom looks lighter than Tawk.to until someone actually clicks the bubble. Tawk.to and LiveChat front-load everything instead, so opening them is free.
Intercom downloads another 833KB the moment a visitor clicks the bubble — a 1.1MB round trip. On page load alone it looks mid-weight, lighter than Tawk.to. Then it quadruples the instant someone engages.
There are two opposite strategies here, and only the click test reveals them. Tawk.to and LiveChat front-load everything, so opening the panel is free. Intercom defers most of its weight to the click. If you only measure page load, you rank those three completely differently than a real visitor experiences them.
One widget doesn't load when Lighthouse is watching
Crisp measured 3.2KB under Lighthouse and 127KB in an ordinary browser. We assumed our harness was broken. It wasn't. Crisp's loader detects performance auditors two separate ways. The first is a hardcoded list of user agents it refuses to load for, and two of them are performance auditors:
agents: ["Trident","Googlebot","Bingbot","Slurp","DuckDuckBot",
"Baiduspider","YandexBot","GTmetrix","Lighthouse",
"Acunetix","Ahrefs","SemrushBot","SiteAuditBot",
"SplitSignalBot","HeadlessChrome"]That is the live contents of client.crisp.chat/l.js — 7,637 bytes, no minification games. View-source it yourself. This list catches GTmetrix, PageSpeed Insights (which appends Chrome-Lighthouse to the user agent), Lighthouse versions before late 2022, and every headless Puppeteer or Playwright harness.
But our harness ran headful with a clean user agent — the blocklist alone can't explain our 3.2KB measurement. That took some digging, because the second detection is one we haven't seen documented anywhere, for any vendor.Lighthouse removed the “Lighthouse” marker from its default user agent in September 2022, so a UA check no longer catches modern runs. The same loader, however, also does this:
window.__nativePerformance&&window.__nativePromise&&(t=!1)That line sets the “don't load” flag, verbatim from the minified loader. __nativePerformance and __nativePromise are globals that Lighthouse itself injects into every page it audits (core/gather/driver/execution-context.jsstashes native references there for its own use). Crisp's loader checks whether both exist and refuses to initialize if they do. Those globals exist on a page for exactly one reason — Lighthouse put them there — so whatever the intent, the only thing this check can detect is Lighthouse itself, regardless of what the user agent says.
To be fair to Crisp: skipping bots is normal and sensible. Googlebot, Bingbot and Ahrefs have no use for a chat widget, and loading one for them wastes everybody's bandwidth. The timeline from archive.org snapshots of the same file: “GTmetrix” in the blocklist since at least June 2019, “Lighthouse” added between the October and November 2020 snapshots, Lighthouse stops announcing itself in the user agent in September 2022, and the __nativePerformance check appears between the April and May 2023 snapshots.
The consequence is measurable and worth knowing: you cannot audit a Crisp installation with Lighthouse or GTmetrix. Run PageSpeed Insights on a site using Crisp and the widget is simply absent from the result. Every Lighthouse benchmark of Crisp ever published — including ours earlier this year, which scored it 100 with 30ms of blocking time and called it genuinely lightweight — measured a widget that had declined to load. We got that wrong, and this is the correction.
CPU cost
Realistic content page, Slow 4G, Moto G Power emulation — Lighthouse's default mobile preset, median of five runs. Only widgets we confirmed rendered during the audit appear here.
| Widget | Perf | Blocking time | Main thread | Long tasks |
|---|---|---|---|---|
| No widget (baseline) | 100 | 0 ms | 101 ms | 0 |
| GhostChat | 99 | 0 ms | 124 ms | 0 |
| LiveChat | 99 | 0 ms | 243 ms | 0 |
| Intercom | 99 | 82 ms | 348 ms | 2 |
| Tawk.to | 99 | 25 ms | 476 ms | 2 |
Tawk.to defers essentially its whole payload, so Lighthouse's window catches roughly 330KB of the eventual 462KB. The CPU figures are for what loaded inside the audit.
LiveChat loaded 347KB across 20 requests here but only 44KB in our other test environment. We could not determine what triggers the difference, so treat its row as the heavier of two behaviours.
The thing most benchmarks won't tell you: the performance score is nearly useless for comparing chat widgets. Every widget here lands on 99. The score is dominated by LCP, and they all delay LCP by roughly the same amount.
The real differences are in blocking time and main-thread work, which feed INP — a Core Web Vital since 2024. Tawk.to burned 476ms of main-thread time against our 124ms. That is responsiveness budget your own site no longer gets to spend.
We ran two other scenarios and they are not shown here because they separate nobody. On a blank page every widget scores 99–100, which is exactly why blank-page benchmarks are worthless. On a simulated low-end phone everything clusters between 67 and 74, because at that point the page itself is the bottleneck.
Where we lose
A benchmark run by a vendor is worth nothing if it only contains rows the vendor wins. Three we don't:
Crisp is genuinely light. At 127KB it is a fraction of Intercom or Tawk.to, and we cannot compare CPU cost against it at all — its loader will not run under Lighthouse. Our February post scored it a perfect 100 and we now know that number was meaningless.
Two widgets we cannot explain. Zendesk and Tidio downloaded 381KB and 509KB in our environment and never rendered. We could not work out why, and it may be our own account configuration rather than anything wrong with those products. We would rather publish that gap than quietly drop them.
We still cost you something. Our widget adds about 10ms of CPU over an empty page across a 20-second idle window, plus 18.9KB and one extra domain. Smaller than the alternatives, but not nothing. Any vendor claiming literally zero impact is measuring a blank page.
Idle CPU — 20 seconds, nobody interacting
A chat widget doesn't stop working once the page has loaded. Most keep a connection alive so a reply can arrive instantly, which means timers, heartbeats and polling running quietly in the background. We left each page open for 20 seconds, touched nothing, and measured how much CPU the widget burned doing it. On a phone this is battery.
Measured in an ordinary browser rather than through Lighthouse — which is why Crisp appears in this table but not the one above. Outside an audit, it loads normally.
| No widget (baseline) | 3 ms |
| GhostChat | 13 ms |
| LiveChat | 13 ms |
| Crisp | 16 ms |
| Intercom | 22 ms |
| Tawk.to | 30 ms |
A widget can download its whole payload and show no chat
We started with nine widgets and finished with five. The other four downloaded their payload and never painted a bubble — no error, no console warning, nothing. We are not claiming these products are broken; they obviously work for plenty of people. Two we diagnosed, two we couldn't, and we've said which is which.
| Widget | Downloaded | What happened | Cause |
|---|---|---|---|
| HubSpot | 96.4 KB | Cause identified: the tracking script installs and loads happily, but shows no chat until a chatflow is published — and the default URL targeting rule can silently exclude your pages. | identified |
| Chatway | 23.6 KB | Our own account, reclaimed for inactivity. The embed still loads a stub. This one is on us — and it is the scenario worth checking on your own site. | identified |
| Zendesk | 381 KB | Fresh trial, official snippet unedited, messaging enabled. Full bundle downloads, no bubble, no error. | unexplained |
| Tidio | 508.7 KB | Fresh account key, official snippet. Full bundle downloads, no bubble, no error. | unexplained |
For Zendesk and Tidio we tried everything we could think of: headless and headful Chrome, mobile and desktop user agents, HTTP and HTTPS, a real domain instead of localhost, and waits of up to 35 seconds. The bundles always downloaded in full and a widget never appeared, with nothing logged. We cannot rule out our own account configuration, so we are not calling these vendor bugs. If you work at either company and can show us what we got wrong, we will update this section and say so.
The transferable lesson is the HubSpot and Chatway cases, because those we understand. If your chat account lapses, or a targeting rule silently excludes a page, your site keeps paying the bandwidth and nothing tells you. One of our February test properties had been reclaimed, and its embed URL now returns a 404 page serving ~330KB of marketing HTML — which our first Lighthouse run dutifully counted as widget weight. Open your own site in devtools and confirm the bubble is actually there.
How we tested
Identical page template: Every widget gets the same HTML. The only difference between two test pages is the embed snippet.
Transfer sizes are deterministic: Byte counts are stable run to run, unlike timing. Where we ran timing metrics we used the median of five runs with a warm-up discarded — Lighthouse blocking time swings ±15ms, wider than some of the gaps people claim from a single run.
Three scenarios: A blank page, a realistic content page whose own JavaScript competes for the main thread, and that same page on a low-end phone (6× CPU slowdown).
Default configuration: No AI agents, no automations, no add-ons. This is the lightest possible version of each widget.
The vendor’s official snippet, verbatim: Including attributes like defer or async. Changing them changes the result — see below.
Render verified before counting: Every number comes from a page where we confirmed a chat bubble actually painted.
One scenario is labelled "low-end phone" rather than "3G" on purpose. Barely anyone is on 3G any more, but the 6× CPU slowdown models something very real: a cheap Android is genuinely that much slower than the laptop you built your site on.
Three bugs we found in our own test
All three were caught and fixed before these numbers were published. We're listing them because each one silently produces plausible-looking data, and if you ever benchmark a third-party script you will hit at least one of them.
1. February measured us on staging
The original harness pointed GhostChat at our staging server while every competitor used their production CDN. Not a meaningful difference in the numbers, but it invalidates the comparison on principle. Production only now.
2. We dropped defer from our own snippet
The snippet we ship to customers ends in defer. Our test page omitted it, which made the script render-blocking and delayed First Contentful Paint by more than two seconds on a slow connection — turning us into the worst performer in that scenario, entirely because of a typo in the harness. Test the snippet people actually paste, attributes included.
3. Headless Chrome is bot-detected
Tawk.to returns 403 to a HeadlessChrome user-agent, and because a 403 carries no CORS headers Chrome reports it as a CORS error. Crisp and Intercom just silently render nothing. Run this benchmark headless and Intercom measures 3.6KB instead of the 271KB it actually loads. If you've seen a chat widget benchmark with suspiciously small numbers, this is probably why.
The other hidden cost: getting the embed code at all
To run this test we had to sign up for every widget. That process is its own finding.
GhostChat: One script tag. Paste it before the closing body tag. Done.
HubSpot: Signup drops you into a CRM with sample contacts. The tracking script installs happily and loads no chat — you also need a published chatflow, and its default URL targeting rule can silently exclude your pages.
Zendesk: Signup lands in an agent ticket console. The widget key lives behind an admin centre, a channel registry and a brand selector.
Intercom: Workspace setup before the Messenger is enabled; the snippet is straightforward once you find it.
Tawk.to / Crisp / LiveChat: Multi-step onboarding wizards — organisation name, site URL, widget customisation — before the embed code appears.
Most of these products aren't chat widgets. They're support platforms that contain a chat widget. If all you want is to talk to the people on your website, that's a lot of scaffolding to accept.
What this means for your site
Measure the click, not just the load
A widget that looks light on page load can quadruple when a visitor opens it. Intercom goes from 271KB to 1.1MB. Your analytics will never show you this.
Bytes are only half of it
JavaScript has to be parsed and executed, not just downloaded. That work drives INP, a Core Web Vital since 2024 and a ranking signal. Tawk.to spent 476ms of main-thread time against our 124ms for a comparable job.
Check your widget is actually alive
Four of the nine we tried downloaded their payload and rendered nothing, silently. A lapsed account or a stale targeting rule costs you bandwidth and gives you no chat.
Cheap phones, not slow networks
3G is nearly gone; low-end Android is not. A 6× slower CPU is the realistic worst case, and it's where heavy JavaScript really hurts.
Run it yourself
The method is above in full, and the numbers were produced twice by two independently built harnesses that agreed to within about 1KB. If you measure something different, we want to know — the fastest way to find our mistakes is other people re-running this. You can also test your own site and see which widget you're running and what it costs you.
Try GhostChat free
18.9KB including the panel. One script tag, zero cookies, no cookie banner. Free for one site.
More from the Blog
The Best Privacy-First Tools for Your Website in 2026
Replace Google Analytics, Intercom, and Typeform with tools that don't track your visitors. Analytics, chat, forms, email, and hosting — all privacy-first.
I Accidentally Built the Fastest Chat Widget on the Internet
How trying to build something simple turned into a ~15KB chat widget with 5ms CPU time and zero dependencies. The full story behind the fastest widget on the internet.
AI Chatbot vs Live Chat: Which Does Your Website Actually Need?
The "bot or human" choice is a false one for most small sites. An honest breakdown of what AI chatbots are genuinely good at, where live chat wins, and why you probably want both — without paying enterprise prices for it.