Our Chat is Now 30% Smaller & 2 Times Faster
We got to a point where we had the lightest chatbox on the market, with a compressed size of 232KB (full load), where other chatbox providers would often load up to a megabyte. Discover How!
Since Crisp started in 2015, we designed the Crisp Chatbox to be full-featured, without compromising on lightweights. We iterated on ensuring that our chatbox script, which every one of our user's website visitor load, would not slow down our user's websites, and pop into view as quickly as possible.
With performance in mind, we already reduced at a minimum our dependence on vendored libraries and minified all of our production assets by post-processing them through uglify and cssmin. Later, we even split our font file (Noto Sans) into sub-files for each alphabet, which smashed the typically-loaded font file size from 150KB down to 10KB — if you speak a Latin language, why the hell would you need to load Cyrillic font glyphs?
We got to a point where we had the lightest chatbox on the market, with a compressed size of 232KB (full load), where other chatbox providers would often load up to a megabyte (!!).
Through this quick article, you'll understand which company offers the fastest live chat solution for websites.
Hence, we got comfortable with the fact that we could not optimize it more. That's until this week.
Why Does Speed Matter For Live Chat Software?
In terms of user experience, speed matters because the faster your chat widget loads, the faster the chance to engage with your website visitor or your customer.
It's an insane way to increase your lead generation.
On the other hand, loading speed is a well-known ranking factor for Google and other search engines.
Weights impact the energy required to load your website, having a stronger impact on CO2 generation.
Live Chat Speed & Size Versus Other Chat Providers
Before we dive into the technical explanations of how we optimized our chatbox as to make it lighter and faster, here is a comparison of our chatbox versus other providers (with all the optimizations applied).
That's why we've compared different live chat software vendors to show you how they behave in terms of loading speed.
We have crunched charts for the following measurements: byte size of the chatbox, time to load, number of HTTP requests, DNS hostnames resolved, and latency to CDN servers.
We are performing those comparisons from the EU, over fiber Internet and a good WiFi access point. We assume that other providers run on a CDN, with a point of presence within the European Union as to keep latency to an optimum level for our measurements. The test browser used is Firefox 82, which has support for all the latest optimizations and Web technologies, such as HTTP/3. The browser cache gets purged before every test.
We performed the comparison for the following live chat app:
- Crisp (blue on the charts)
- Intercom (green on the charts)
- Drift (yellow on the charts)
- Zendesk (red on the charts)
- Freshchat (purple on the charts)
- Gorgias (Brown)
Live Chat Software Comparison
#1: Size of live chat in bytes
The larger the size of the chatbox, the longer it will take to load on a slower network. Smaller is better.
How this was measured: this co was acquired from Firefox over a WiFi hotspot in the EU, by summing all loaded assets, after opening the live chat (clicking on the button). We made sure to isolate website-specific assets such as operator avatars, as their size varies quite a bit between websites, and thus are not relevant in this measurement. Also, note that those are compressed sizes, either via Gzip or Brotli depending on the chatbox provider (Brotli is better than Gzip, usually by 10%).
#2: Time to load the live chat bubble
The time to load the chatbox button depends on a number of factors such as chatbox byte size, server latency, and the number of dependencies the chatbox loads before it is ready. Lower is better.
How this was measured: this comparison was acquired from Firefox over a WiFi hotspot in the EU, by summing all sequential loading times for all resources needed for the chatbox button to be first shown on the screen. In the case multiple resources could be loaded in parallel as part of a blocking group, the maximum loading time is taken (in order to reflect reality).
#3: Number of HTTP requests
A number of HTTP requests are made to load all required resources for the chatbox, load its user settings and establish a Real-Time messaging channel. More HTTP requests may result in more time spent waiting for the network, though this measurement has less impact on performance today with modern HTTP/2 and HTTP/3 protocols, which both pipeline requests over the same re-used connection. Lower is (usually) better.
How this was measured: this comparison was acquired from Firefox over a WiFi hotspot in the EU, by counting all HTTP requests sent before the chat button appeared, as well as all HTTP requests sent after the button appeared, necessary for chatbox services such as operator avatars and WebSocket.
#4: DNS hostnames resolved
A chatbox script may require to access resources on different subdomains (hostnames). More hostnames result in more DNS resolution queries, which incur more time spent waiting for an answer. This also prevents pipelining HTTP requests efficiently over a single hostname, and thus requires different secure channels to be negotiated, inducing more CPU time spent on hard cryptographic work (assuming HTTPS is used, which is the norm as of 2020). Lower is better.
How this was measured: this comparison was acquired from Firefox over a WiFi hotspot in the EU, by listing all distinct hostnames resolved so that the chatbox button and avatars could appear on screen, and a WebSocket connection was established.
#5: Latency to CDN servers
The latency to CDN servers is key to loading time. Latency is a basic measurement of the time it takes for a network request to flow to the chatbox servers and then come back with the first answer byte. A high latency, coupled with a lot of HTTP requests, will result in incredibly high loading times (as multiple roundtrips are required). Lower is (much) better.
How this was measured: this comparison was acquired from a wired fiber connection on a server located in France, which has been tested for its low and stable latency to Internet backbones (typically 5ms), hence reflecting the real minimum latency from the EU one can get in ideal conditions.
Important note: this comparison was written as of October 2020. Data shown here might have changed since then, as other chatbox providers may have rolled out updates of their chatbox which could make it lighter, or heavier.
The Nitty Gritty Technical Details
Bad WiFi told us we could do (even) better
Here's the background story behind our motive to optimize even further the chatbox: the Crisp team arrived at its annual remote retreat 2 weeks ago. We landed on a remote island and arrived at a large countryside house. The house is well-equipped, with fast fiber Internet. Unfortunately, the house had poor WiFi reception due to thick walls. Poor WiFi means elevated packet loss, no matter how good the landline connection is.
Under light packet loss, TCP bandwidth gets dramatically reduced, as the TCP algorithm tends to lower its bandwidth window for each lost packet as to adjust to the maximum limiting bandwidth of the transmission channel (here: WiFi). This impacts HTTP and the general Web browsing experience (HTTP runs on TCP).
Worse, a lot of DNS queries were never answered, due to DNS using UDP, which does not guarantee delivery and does not retransmit lost data. Failing DNS means that our Web browsers often fail to resolve hostnames, most often for third-party scripts that websites load, which resolve a lot of hostnames.
To our realization, the Crisp chatbox was also impacted by this poor network. Could we fix that by optimizing certain factors in the way our chatbox runs? Let's see.
This marked the start of the "Crisp on Diet" project.
Investigating what could be optimized
Our technical team spent days investigating for any opening to further live chat optimization, and iterating on testing several ideas at multiple levels, and checking for any impact on bundle size and speed before working on a final implementation.
This is the checklist we laid out:
- SVGs size could be reduced by 50% total, by simplifying their vector paths, using svgo, which also has a nice GUI available (those are inlined as Base64 in the main CSS);
- Sounds played when eg. receiving a message could be re-encoded to a lower bitrate (depending on their codec, namely AAC, MP3 or Vorbis), to get to the lowest limit where the typical human ear would not perceive that much of a quality difference using good-quality headphones. Luckily for us, human ears are quite bad at hearing, so we can trick them lowering sound quality;
- Vendored CSS properties for all legacy browsers (pre-2017) could be disabled in our modern CSS build targeting all modern browsers (they are still included in our legacy stylesheet build);
- WOFF fonts could be removed from our modern CSS build, keeping WOFF2 only (those rules were repeated hundreds of time due to alphabet-specific unicode range rules);
- Some resource hints "dns-prefetch" and "preconnect" could be removed to avoid unnecessary DNS queries and TCP & crypto handshakes, to domains typically used by 1% of the people that see the chatbox when it is closed;
- The settings hostname "settings.crisp.chat" could be merged to the assets hostname "client.crisp.chat" on a sub-path, which would save 1 DNS query, 1 TCP handshake and 1 crypto negotiation, and allowed re-use of the already-open HTTP/2 connection to load the chatbox settings;
- Some CSS rules "visibility: hidden;" could be tuned to "display: none;" to prevent fonts from being loaded when not shown in screen for 99% of chatbox users, saving 20KB of data, and 2 HTTP requests;
- CSS class names could be reduced even more, via our hashing post-processor which takes in our human-readable CSS class names such as ".crisp-client-container", and mangle them to hashed class names such as ".cc-2da1";
- JavaScript properties and function names that are internal could be mangled per-class via uglify, which would transform eg. "this.__long_property_name" to eg. "this.Wr_" (this saved a lot of bytes);
- Vendored libraries should be built with special optimizations as to remove unused code, for instance Socket.IO which we use to establish a RTM messaging connection to our servers contains a legacy HTTP long-polling connection method — that is quite heavy! — though we only need to use the WebSocket connection method with today's modern browsers;
Measuring the impact of our optimizations
Our Content Delivery Network serves all scripts and stylesheets in a compressed format, using the Brotli compression algorithm in priority, and falls back to Gzip in the event the browser does not support it. Brotli is better at reducing resource size than Gzip is, and is becoming the norm nowadays.
We measured the Brotli-compressed size of all core chatbox assets (scripts, stylesheets) before and after our optimization work:
That's a nice total reduction in weight! This does not account for all other smaller resources that get loaded, which all add up to a reduction in size of 30%.
As well, we wanted to make sure that our bundle size would not grow bigger over time due to minor code changes. Thus, we implemented a check at the end of our production build, which compares the resulting build size with pre-configured size baselines. Stepping over a threshold means that the build gets rejected and not deployed to production, erroring out and alerting the developer.
➡️ Yes, that's a Concorde on the article cover picture. It immediately came to our mind when we thought of speed and lightweightness. Too bad it's gone!