The new SVG HipChat loading screen – faster without React

Reading Time: 3 minutes

We love gifs on the HipChat team. We love them so much that we were temporarily

misled by their sirens’ call. Here’s how we plugged our ears and continued on to

the fabled land of SVG, optimizing our loading screen and reducing its size by


Fatty the gif and the loading screen

Our original loading screen was a thing of beauty. A pure white screen sporting

an animated, retina HipChat logo rolling over its tail into the future and


A hidden, pre-loader HipChat loading gif

The old HipChat loading gif

Roll over to animate

This retina gif’s size (a chunky 53KB) was the source of its demise. It was

simply too big for a loading screen, often arriving late and missing the party


Size aside, the old loading screen was a part of the greater web app. This meant

it would not appear until React and all of

the other dependencies of the web client were loaded. That sounds

counter-intuitive, but when we first launched the beta, the javascript payload

was smaller. The loading screen was simply used to hide the UI whilst we

fetched the initial HipChat session data. Since then we’ve added countless

features, like inline file previews, increasing the download size.

We’ve gone one better. The loading screen now loads before

React. Infact, the SVG HipChat logo and

animation CSS are inline in the HTML, so there’s no additional requests to make

to show the loading screen.

Captivating new users

New users are precious and first impressions last. If you have to keep them

waiting, captivate them. Quickly.

After our initial web client beta release, we conducted an intense study of the

new user on-boarding flow. It was then that we discovered our gif issue. In

production, new users with an empty cache on a typical internet connection,

often didn’t see our fancy loading gif at all.

Farewell gif. Hello SVG.

Our new web client already uses SVG symbol definitions

for our status icons, so it was a no-brainer to add a HipChat logo along-side


With this HTML and CSS:

<svg height="0" style="display:block;" version="1.1" xmlns="" xmlns:xlink="">

  <symbol id="icon-hipchat-logo" viewBox="0 0 1024 1024">


    <path class="path1" d="M791.552 ..."></path>

    <path class="path2" d="M932.864 ..."></path>



#icon-hipchat-logo .path1, #icon-hipchat-logo .path2 {

  fill: #205081;


It looks a little like this:

Let’s dance!

Advanced CSS animations are tricky. The animation loop needed to account for the

logo’s tail striking the ground. Piecing something intricate like this together

with the provided transition types (ease-in, ease-out, etc) is a great recipe

for a self-induced lobotomy. Instead, thanks to

Joel Unger on the design team, I was

able to create rotation and translation keyframe

rules from the original After Effects timeline.

Original After Effects keyframes

The loop is 49 frames at 29.97fps giving us a total length of 0.6 seconds. From

here we can create percentage-based keyframes.

i.e. At frame 22 (46% through the loop), when the tail hits the ground, we want

to apply a rotation of 20 degrees and translation of 7 pixels up.

* Please note this snippet does not include browser-prefixes currently

required to work in all browsers.**

.loading-message .loading-outer {

  animation: translationFrames linear 0.66s infinite;

  transform-origin: 50% 50%;


.loading-message .loading-inner {

  animation: rotationFrames linear 0.66s infinite;

  transform-origin: 50% 50%;


@keyframes translationFrames {

  42% {

    transform: translate(0, -7px);



@keyframes rotationFrames {

  42% {

    transform: rotate(20deg);



The result

From a 53KB gif to 1.8KB of HTML and CSS (both sizes gzipped).

Roll over to animate

You can find all of the code for this CSS animation by viewing the source of

this blog post (or by signing up for a HipChat account).