We like speed because our customers need it — check out what we’ve done to make our Chat Widget load quicker
Tags: webdev, javascript, showdev
Published: 2021-07-27 14:41:26

###Being ahead of the curve requires much effort — even little tweaks are important for delivering a great product. Recently we optimized our Chat Widget to make it faster in terms of page load speed. 🚀

In previous articles, we’ve covered how LiveChat does not slow down websites it's installed on. This time we wanted to optimize the size and loading speed of the widget itself and influence Largest Contentful Paint (LCP), a factor that affects page ranking in Google. Furthermore, our goal was to improve CLS — Cumulative Layout Shift. It's a metric that quantifies how often users experience unexpected layout shifts. The lower the CLS, the more visually stable the page is. Additionally, it helps avoiding unwanted missed interactions from the user perspective, like, for example, a button you want to click which suddenly moves down because something more has loaded and you end up with clicking on another thing.

###What did we do?

In terms of technological development, we introduced a few changes, listed below:

####We split the code.
To make the chat widget appear more quickly, we divided its script into a couple of parts. One part loads automatically with the page and displays the minimized chat widget. The rest of the code loads when the user hovers over the widget.
We got rid of SockJS in favor of a pure WebSocket connection.
Our Chat Widget used to implement SockJS, a wrapper on WebSocket (WS) connections. Ditching it has significantly decreased the Chat Widget loading speed, and its size, as we no longer need to load a third-party library. Consequently, we could cut out the configuration request SockJS used to make to our server, saving additional time.

####We migrated to HTTP/2 from HTTP/1.x.
A small change, but it opened up numerous possibilities for further development. For example, we were finally able to overcome the barrier of making only a single request at a time while having to use multiple TCP connections. With multiple parallel requests and other possibilities to optimize app performance, we look forward to making our chat widget even more swift.

####We’ve been gradually reducing the Chat Widget’s asset size.
In June 2020, our Chat Widget size (measured by Google Lighthouse) was 412KB. Within the first two months, we reduced it to 332KB, but we haven't stopped there. Right now, our chat widget asset size has settled at 256KB. (What a nice number. For now.) Obviously, it has significantly shortened the loading time of the Chat Widget.

![chat widget asset size chart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7e7qv06zp5w4by31hs26.png)

###What was the outcome?

####First marker: FCP/LCP — First/Largest Contentful Paint
FCP, briefly speaking, marks the time the browser needs to display consumable information (text, visuals, etc.). It's much more informative than just First Paint, which measures first render — any render. LCP, on the other hand, measures how long it takes to display the largest element. The less time, the better, and 1.2 seconds is the max. Our LCP result was 252 ms 🔥

####Second marker: CLS — Cumulative Layout Shift
As mentioned before, CLS is a highly user-centric marker that measures the visual stability of the site, an influential factor in terms of user experience. We managed to reduce the CLS impact reported by Google Lighthouse from 0.8 to 0, which translated into lowering the number of CLS issues reported by our customers on the chat.

![chat widget loading time chart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7qymaqjjogcr3hw7ezbq.png)

Right now, we are Grade A when measured by GTmetrix. While code splitting and switching to pure WebSockets turned out to be the most effective technological changes, HTTP/2 migration has set us in the right direction for future optimization.

**What do you think about our process? Can you recommend any other ways of optimization when it comes to the size and load speed of the widget?**