Hey there, welcome back!
I’ve had my head down for a little while, and for good reason!
I’d like to Introduce Rise of the Robots. 🤖 A Gatsby + Rive + Contentful powered creative, performant and accessible demo.
I’ll be giving a talk about this too, so visit the site and register before 12:00pm PDT on June 1st to see me publicly speaking, for the first time…. ever. 😬
Rise of the Robots – In-person Event
Jamstack Creativity, Performance Optimization and Accessibility
June 1 | 6:00 – 8:00pm PDT
Andreessen Horowitz, 180 Townsend St, San Francisco, CA 94107
Rise of the Robots – Virtual Webinar
Jamstack Creativity, Performance Optimization and Accessibility
June 14 | 8:00 – 9:00 PDT | 11:00am – 12:00pm EDT | 3:00-4:00pm UTC
To explain why I built this site using these technologies requires a journey back in time — ready?
Flashback: My Web Development Past
Performance and creativity are where web development all started for me. Circa 2002 I discovered Flash, and it was the best thing that had happened to me, or anyone else I know. I was lost in a world of Vector illustration, Timeline and ActionScript animation and interactivity.
The Flash IDE also had the Bandwidth Profiler built in so you could see the compiled file weight of your .swf (Small Web File), the frame rate it was running at, and the strain it was putting on your computer’s CPU/GPU.
Performance was super important because back in the day, it really wasn’t a ”nice to have”, it was a necessity! Many offices and households were still using 56k dial up modems and although broadband / wifi was on the rise, it wasn’t as mainstream as it is today.
If your Flash site didn’t load on a 56k dial up connection within a few seconds, no one would ever see it. 🥴
During this time, and for a number of years following, the web started to change from a place where “computer enthusiasts” hung out, to a place where a lot more people were spending their time, and in the latter part of the 2000’s — dare I say — an essential part of everyday life. Even back then, though, the internet was already absolutely massive with Flash websites everywhere and, in my opinion, these are still some of the best examples of digital creativity!
Then Apple released the iPhone and ruined everything. Thanks, Apple!
Around 2012, I switched from Flash Development to HTML, JavaScript and CSS web development, and blimey was it boring. You couldn’t do anything that you could do with Flash and it would be many years before even some of the most common features of Flash would be possible using the browser alone.
Around 2016, following the boredom and in search of something more interesting, I made the switch to React Development, and well, things kinda got worse. I was now working for companies that didn’t care about creativity, performance, accessibility and in one case didn’t believe “mobile-first” was actually a thing. Most of the applications I built were for internal use only and would seldom be seen by the outside world. It. Was. A. Nightmare.
Finding Gatsby, rediscovering Creativity
Then in 2018 I found Gatsby. I could see a path forward (or, back actually) where I could express myself creatively in similar ways as I’d done in my formative web development years.
From day one I was in love with Gatsby. Being able to build using React but now having actual and real indexable pages rather than SPA routes was a breath of fresh air.
The community was inspiring, too! Many innovations came out of camp Gatsby: Gatsby Themes, Gatsby Recipes, MDX, and Theme UI to name just a few. But the biggest overriding factor was that I could now clearly see how I could be creative again.
I’ve experimented with “creative” websites over the past few years. A few that spring to mind are my “winning” entry for Gatsby’s 2020 Silly Site Challenge, BumHub, and more recently the 500 Bottles Giveaway and GatsbyConf 2022. In all cases I tried my damndest to bring back some of that creativity that I lost when Flash died, and with Rise of the Robots I’ve tried to take it a step further.
Introducing Rive
Now, modern web “animation” is a broad church. Does it mean transitions? Is it CSS keyframes? Is it some other JavaScript library, is it all of those things, or is it something else?
For me, animation means: The stuff you could do in Flash, Character Animation. — Thanks to Gatsby Community member Alex Barashkov for bringing this to my attention!
I’d now like to introduce Rive.
— Guido Rosso | Founder/CEO at @rive_app“Rive is the new standard for interactive animation. Create rich interactive content with our collaborative editor and render it anywhere (web, products, apps, and games) with our open-source runtimes”
When I first opened up the Rive app, my first thought was… this is just like Flash! After meeting with the Rive team (who are super nice by the way) and learning a little more about their backgrounds where they explained that they too used to be Flash developers, it all started to fall into place.
My inspiration for this project is the past, and I hope I’ve respectfully resurrected many of the disciplines, techniques, and in some ways awareness of technologies that inspired me all those years ago.
So, without further ado, here’s how we made Rise of the Robots.
The Brief: Gatsby + Rive
The project started as a proposal document explaining what I was hoping to achieve with this demo together with an Art Direction document. The purpose of the Art Direction document was to visually communicate to Rive what I was seeing in my head.
Reason being, Rive and I were to be working in parallel streams on this. I was to tackle the site design and build, and Rive the illustration and animation of the Robots. To ensure that both elements of the project felt cohesive, I’d provided a number of examples for how I’d like the Robots to look and feel. I kept these in mind when I was exploring the design treatment.
A long story short, it worked out great. Rive went away and did their thing, I did mine, and I think we’re all pretty pleased with the result.
Here’s some screenshots from my Art Direction document.
Design Inspiration
Design is always a difficult area for me. It’s been many years since I was a “real designer” but, by drawing inspiration from those who ignited my web design fire, I feel I’ve been able to create something that looks similar to the kinds of sites I used to admire back when I was “surfing the internet”, which by the way, is a phrase I’d also like resurrect 🏄.
Here’s a few things from the past that get my motor running.
2Advanced Studios | 2Advanced Studios v4 flash website in 2003
Art Direction
Not a phrase you often hear in tech, but for me Art Direction is all about creating a vibe.
Can you convey feelings or emotion through visuals alone? Of course you can. My creative inspiration for Rise of the Robots came from something that’s probably on my mind more often than it should be and represents a perfect example of creative vision.
When I pitched this idea to Rive I wasn’t sure how possible it was going to be to create hybrid human robots, but holy s*** did Rive deliver!
What Juan Carlos Cruz and Robert Haynie have produced here is truly mind blowing. Thanks JC and Robert — You’re extremely talented and I absolutely love what you’ve created here!
The CMS: Gatsby + Contentful
The site is built using Gatsby (obviously) and is hooked up to Contentful using gatsby-source-contentful.
Gatsby’s plugin ecosystem is a super power, especially on a build like this where my focus has been on creativity, performance and accessibility, not sourcing data from a CMS.
Using a source plugin on a build like this is kind of a lifesaver because I know the data part at least is fully taken care of leaving me time to concentrate on other areas of the build.
If you’re curious about how to connect a Gatsby site to Contenful using our source plugin here’s a snippet, 6 lines of code. (Not bad, ay!)
There is slightly more to it than that. Here’s a few posts I’ve written about how to use Gatsby + Contentful — Feel free to peruse them at your leisure.
Creativity vs Performance
Having had the creative “battle” many times in my career, I’ve learnt that in order to “get my way” I need to provide some pretty concrete reasons why adding animation to a website is required and moreover, provide proof that it won’t negatively impact a site’s overall performance.
This can be pretty difficult to “argue” to be honest.
Let’s start with the facts. Adding the Rive React Runtime to your site will add approximately 66kb to the site’s main JavaScript bundle – Blast!
66kb doesn’t sound like a lot, and in the grand scheme of things it’s not. For instance, one poorly optimized image on your site could easily be double that size but given that a default Gatsby site which includes React is also approximately 66kb, it does make you think, is the juice worth the squeeze?
I think yes and I think if you are adding Rive animations to your site, you’ll want to consider using similar techniques to the ones I’ve used in the demo. That is, where the React Component that loads the .riv
file and the Rive Runtime utilizes React’s builtin lazy and Suspense methods.
Performance Tip: Lazy-Loading
In the demo site there’s an extra performance method used in addition to lazy-loading. I’ll explain the Acceptance Criteria first, then explain each method.
- Lazy-loading Rive files should only occur if the browser width is greater than 768px
- Lazy-loading Rive files should only occur if
navigator.connection.saveData
isfalse
- The
.riv
file and both Rive hooks;useRive
anduseStateMachineInput
should be lazy-loaded using React’s lazy and Suspense methods
When to lazy-load
The first two points in the Acceptance Criteria deal with, “when to lazy-load”. This was achieved by creating a custom hook. It’s called usePerfLoading
.
You can see the src for this hook here: src/hooks/use-perf-loading.js
And here’s a snippet.
This hook runs “on mount” as denoted by adding an empty dependency array in the useEffect
and returns true
or false
based on both the width of the browser and if a user has saveData
enabled. You can read more about saveData in the MDN docs, Save-Data.
I can now use this hook to form the basis for a ternary condition which determines if/when to lazy-load the Rive animation and all of its accompanying files, or a fallback image that’s been optimized by gatsby-plugin-image.
You can see the src and how it’s implemented in the Hero Section here: src/components/hero-section.js
And here’s a snippet.
Using the boolean returned from the <code”>perfLoader hook I determine if Gatsby’s <StaticImage />
component is returned or the <HeroBot />
component which contains the Rive animation.
How to lazy-load
The general idea behind lazy and Suspense is to delay the downloading of heavy or non-essential JavaScript until after the initial page load is complete. To be clear, this won’t change the total size of JavaScript being downloaded by the browser but it will mean the initial JavaScript bundle is smaller which will result in a faster initial page load. This will be reflected in your Lighthouse scores since Lighthouse is only reporting on the initial page load, not anything that happens after the initial page load, including reporting on anything that’s been lazy-loaded.
Side-stepping Lighthouse for a moment, it’s still a good idea to keep an eye on what’s been lazy-loaded as this can still negatively impact your site’s performance. The bundle chunk size report I referred to earlier in this post is automatically generated by gatsby-plugin-perf-budgets and I’d recommend using this in conjunction with Lighthouse scores.
Making Animations Accessible
Let’s start with why it’s important. Folks with vestibular disorders can experience feelings of dizzines or sickness when viewing animations with high levels of movement or motion. There are of course varying degrees of severity for this condition but the general rule of thumb is to ensure that if a user has prefers-reduced-motion enabled in their browser, your animations should observe their preference.
Myself, and Gatsby as a whole, take this quite seriously and on this build I wanted to demonstrate both how to observe prefers-reduced-motion
and perhaps an interesting use of Rive’s State Machines.
Prefers Reduced Motion
Since I’ve used this functionality in a number of places around the site I abstracted this into a hook. It’s called usePrefersReducedMotion
.
You can see the src for this hook here: src/hooks/use-prefers-reduced-motion.js
And here’s a snippet.
This hook runs “on mount” as denoted by adding an empty dependency array to the useEffect
and adds an event listener that reads the value of prefers-reduced-motion
. It also listens for changes and returns true
or false
accordingly. When the component is “unmounted” the event listener is removed.
I can now use this hook to form the basis for a ternary condition which determines how to control Rive’s State Machines.
Each of the Robot animations has at least two states. Here’s how the Gatsby Bot works.The isLimited
state is triggered by changes in the usePrefersReducedMotion
hook. You can test this in your browser by using Run Command and typing “prefers-reduced-motion”.
I use the returned value of the prefersReducedMotion
hook in another useEffect
where I can set the isLimited.value
to true
. This kicks the State Machine into its Accessible state which has limited motion. There are still some very subtle glowing animations that will be shown but all major movements are stopped.
You can see the src for this here: src/robots/gatsby-bot.js.
And here’s a snippet:
Intersection Observer
Not 100% related to Accessibility but I also used another State Machine and technique to control when to play the Gatsby Bot animation.
The isVisible
state is triggered by an Intersection Observer, and tells Rive to play the animation when the section is within the user’s viewport.
You can see the source for the Gatsby Bot here: src/robots/gatsby-bot.js.
And here’s a snippet.
The Intersection Observer in Gatsby Bot is triggered when the section crosses a threshold of 0.1. When entry.intersecting
is true
I set isVisible.value
to true
. This kicks the Rive animation into its isVisible
state.
When the section is no longer visible in the viewport, I set the isVisible.value
to false
which kicks the Rive animation into its idle state.
You can read more about Intersection Observers in the MDN docs: Intersection Observer.
Wrapping Up
There’s quite a lot that went into this build, perhaps more than a single blog post can explain so myself along with the good folks at Rive will be explaining in more detail how we built Rise of the Robots.
If you’d like to learn more, please join us for either the live in-person event in San Francisco or our upcoming webinar:
Rise of the Robots – In-person Event
Jamstack Creativity, Performance Optimization and Accessibility
June 1 | 6:00 – 8:00pm PDT
Andreessen Horowitz, 180 Townsend St, San Francisco, CA 94107
Rise of the Robots – Virtual Webinar
Jamstack Creativity, Performance Optimization and Accessibility
June 14 | 8:00 – 9:00 PDT | 11:00am – 12:00pm EDT | 3:00-4:00pm UTC
That just about wraps things up! I hope you’ve enjoyed the journey and perhaps picked up one or two tips to help you on your way with adding animations to your next Gatsby project.
I’m always on the lookout for interesting uses of technology for creative purposes so if you have something you’d like to share and / or collaborate with me on, please come find me on Twitter to have a chat: @PaulieScanlon.
Ttfn.
Paul 🕺.