May 23, 2019
Before I start, we didn’t really want to have to do this. There are a couple of really good projects out there that offer an emoji picker, they just didn’t quite work how we needed them to.
It is surprisingly easy to build out a complex component with React and hooks. However, you have to be careful about accessibility and profile the performance routinely!
As you perhaps already know one of MindLink’s core products is a single page application for accessing chat systems.
We support legacy chat systems from a time where emojis were not a mainstream expectation from users. We bring up to date emoji support to those chat systems via our server-side abstraction layer, which allows us to build modern features on top of existing Enterprise chat systems.
To bring emoji support to our clients we originally we went with emoji-mart by missive. It’s sleek and stylish and has a lot of customisation options. However, we encountered some issues with performance:
Additionally, we really wanted to customise it in other ways:
What we didn’t need:
We knew from performance profiling that the biggest issue is the rendering of the emoji list. 2000+ emojis on screen at once, not a good idea. We need a better way - a virtualised list.
Simply put, a virtualised list only renders what is visible into the DOM on demand and tracks scroll position to trigger loading different parts of the list. This means the complete list is virtual and we render only a window.
A well-established solution in the React world is react-window. It is a great project that handles most of the pain of managing a virtualised list or grid. There is also the possibility to get some vanilla JS to do this using an
IntersectionObserver to trigger rendering “pages”.
We are also fortunate that right now it’s pretty easy to make lightweight components using React hooks.
Combining both react-window and hooks we sought to recreate the minimal feature set we wanted from emoji-mart:
A first draft of this we threw together in about half a day - leveraging the emoji-mart data source so that we didn’t have to worry about compiling that. That is the power of leveraging hooks and react-window.
We took that first draft, liked it and built it out over another couple of days to get it to where we wanted it for production.
The results are impressive considering the short time frame. The picker loads considerable faster and supports all the same use cases we had. We now have the full benefits of owning that:
We want to take this open-source, but before we do we need to figure out a first-class data source and stop piggy-backing off of emoji-mart so we can control the Unicode support.
I’ll take a deep-dive into the implementation in a few follow-up posts.
Written by Luke Terry.
Senior Engineer at MindLink. Enjoys technology, playing games and making things work, blogs at www.indescrible.co.uk.