CSS Is More Powerful Than You Think! Building React Search in CSS

Rate this content
Bookmark

CSS Is more powerful than we usually give it credit for. Let's see together how we can make use of CSS to build together fully functioning filtering capabilities into an emoji-picker component, improving performance while at it.


We will use some old and new techniques, and combine them in creative ways to turn a slow, laggy experience into a responsive and modern searching capability.


We'll learn about the advancements in CSS, and discover the untapped potential of CSS for building dynamic UIs.

This talk has been presented at React Advanced 2024, check out the latest edition of this React Conference.

FAQ

EmojiPicker React is a popular EmojiPicker component for React with hundreds of thousands of weekly downloads, featuring a full set of emojis, skin tone options, emoji styles, and a search capability.

He wanted to avoid forcing users to install third-party libraries and aimed to solve performance issues using CSS techniques instead.

Evatar Alush focuses on open source development, API design, and building developer tools, with a particular interest in improving web performance through innovative solutions.

Flareup simplifies the integration by placing CSS directly into the DOM, ensuring it works in both server-side and client-side rendering without additional configuration.

Evatar Alush lives in Tel Aviv with his wife.

EmojiPicker React includes a complete emoji set, different skin tones, various emoji styles (Apple, Twitter, Google, Facebook), and a search function.

Flareup is a CSS in JS library created by Evatar Alush, designed for NPM packages and open-source libraries, ensuring compatibility across various environments, including SSR and CSR.

He used CSS techniques to manipulate the DOM for faster rendering and created a local state to handle searches more efficiently without relying on global state updates.

Evatar Alush solved the slow search capability issue in EmojiPicker React by using CSS to improve performance and reduce lag during searches.

Evatar Alush is a software engineer at Meta and the author of several open source packages, passionate about open source, API design, and building tools for developers.

Evyatar Alush
Evyatar Alush
23 min
28 Oct, 2024

Comments

Sign in or register to post your comment.
  • Va Da
    Va Da
    P4
    Emojis for the win!
Video Summary and Transcription
Hello, everybody. Today, I'm going to talk about how I solved actual challenges in React using only CSS. One of the main packages I maintain is EmojiPicker React, with hundreds of thousands of weekly downloads. It has all the features you'd expect from an EmojiPicker, but the search capability was slow. I managed to fix it using CSS. Let me show you how. The search functionality relies on global state and requires updating each emoji individually, resulting in excessive DOM work. Virtualization or virtual scrolling is not a viable solution due to the non-uniform emoji list. By examining the DOM, I discovered that each emoji had an area label with search-related information. This led me to investigate further and implement a solution from scratch. We create a new component called CSS search, which takes a value as a string. If the value is empty, we return null. We remove all emojis from the emoji list if there are search results. Emojis that match the search term are displayed. Performance is instantaneous. Empty categories are removed using the CSS has attribute. The CSS not and has selectors are used to remove empty categories. A counter is used to display the count of emojis found. By using flexbox and order, we can position the after element at the beginning of the list. CSS nesting allows us to nest everything under the emoji list, simplifying the structure. The performance of the search is still very fast. I created the flareup package, a CSS in JS library specifically for NPM packages. Flareup solves compatibility issues and works on SSR and CSR. Emoji-picker-react uses flareup to render emojis without JavaScript. Flareup places a style element on the DOM, making it easy to use.

1. Introduction to CSS in React

Short description:

Hello, everybody. Today, I'm going to talk about how I solved actual challenges in React using only CSS. One of the main packages I maintain is EmojiPicker React, with hundreds of thousands of weekly downloads. It has all the features you'd expect from an EmojiPicker, but the search capability was slow. I managed to fix it using CSS. Let me show you how.

Hello, everybody. My name is Evatar Alush. I'm a software engineer at Meta. I'm the author of several open source packages. Very much passionate about open source, API design, and building tools for other developers. I live in Tel Aviv with my beautiful wife. And I'm also the humble servant of this mighty creature.

Today, I'm going to step just a little bit outside of my comfort zone because while I usually talk about JavaScript, TypeScript, Node, building packages, React, today I'm going to talk about something different. I'm going to talk about CSS. And more specifically about how I solved actual challenges in React using only CSS.

You see, one of the main packages that I maintain is EmojiPicker React, which is one of the most popular EmojiPicker components in React or in general, actually, with hundreds of thousands of weekly downloads. And it has most of the features you would expect from a standard EmojiPicker. So it has the entire set of emojis. It has different skin tones that you can pick from. It has different styles of emojis. So you got Apple, Twitter, Google, and Facebook. And it also has searching capability. And I'll type something and you can pretty easily see that the search is quite snappy. It appears immediately. The search results appear immediately. And, well, that's what you would expect from a search component in an EmojiPicker.

But it wasn't always the case. You see, when I created the EmojiPicker back in 2017, the search capability was quite slow. And the main issue that I would always get in the GitHub page of the project was, search is laggy. We cannot use search. It takes up to two seconds to search anything. And that's not acceptable. And I managed to fix it, mostly using CSS. And before I show you how I did it, I want to show you what it felt like before actually implementing the fix. So I'll go back to the demo component that I created.

2. Challenges with EmojiPicker Search

Short description:

And this is the EmojiPicker without that fix. The search capability is slow and causes a lag when typing. It takes several seconds for the search results to update, making it unacceptable. The search functionality relies on global state and requires updating each emoji individually, resulting in excessive DOM work. Virtualization or virtual scrolling is not a viable solution due to the non-uniform emoji list.

And this is the EmojiPicker without that fix. So just the way it was before. And I'll type something and you'll notice a slight lag. So I'm typing the letter K now. And it took, I don't know, like half a second to re-render. And, well, not that bad, you would say. But if it happens for each of the keystrokes, that's not comfortable.

And I'm using actually a very high-end MacBook Pro, but what about actual users in the wild who do not have high-end machines? Let's see what it feels for them. So let's go to the Performance tab in Chrome DevTools and let's try to slow it down, say at time six. And let's see what this feels like for users in the wild. So I'll let you know when I actually type something so you can time it yourself. So I'm typing the letter K now. And that took almost, I don't know, two seconds to actually see anything updating. And obviously, if I type more characters, you'll see that it gets shorter and shorter because it has less emojis to filter from. But still, that's unacceptable.

And why is that? Well, as you can see here, the search is up here at the header. It's completely distant from the emoji list component. So everything we want to update here has to go through some global state in the picker and then go back down to the emoji list before anything happens. And then it has to update each and every emoji that needs to be removed or re-added. So that's a lot of work to do on the DOM. And that's the most labor-intensive work, actually. So we got global state update. We got state diffing for each of the components. We got DOM diffing for each of the components. And then we have to actually re-render everything. And if I show you what happens is, well, when I go to the components tab in React DevTools, I can actually highlight the state changes and the re-renders. And you'll see here that we re-render everything. And, well, you could say I could use some virtualization or virtual scrolling. But, well, first of all, the emoji list is not uniform. So we got the titles that take full width.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

A Guide to React Rendering Behavior
React Advanced 2022React Advanced 2022
25 min
A Guide to React Rendering Behavior
Top Content
This transcription provides a brief guide to React rendering behavior. It explains the process of rendering, comparing new and old elements, and the importance of pure rendering without side effects. It also covers topics such as batching and double rendering, optimizing rendering and using context and Redux in React. Overall, it offers valuable insights for developers looking to understand and optimize React rendering.
Don't Solve Problems, Eliminate Them
React Advanced 2021React Advanced 2021
39 min
Don't Solve Problems, Eliminate Them
Top Content
Kent C. Dodds discusses the concept of problem elimination rather than just problem-solving. He introduces the idea of a problem tree and the importance of avoiding creating solutions prematurely. Kent uses examples like Tesla's electric engine and Remix framework to illustrate the benefits of problem elimination. He emphasizes the value of trade-offs and taking the easier path, as well as the need to constantly re-evaluate and change approaches to eliminate problems.
Speeding Up Your React App With Less JavaScript
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Top Content
Watch video: Speeding Up Your React App With Less JavaScript
Mishko, the creator of Angular and AngularJS, discusses the challenges of website performance and JavaScript hydration. He explains the differences between client-side and server-side rendering and introduces Quik as a solution for efficient component hydration. Mishko demonstrates examples of state management and intercommunication using Quik. He highlights the performance benefits of using Quik with React and emphasizes the importance of reducing JavaScript size for better performance. Finally, he mentions the use of QUIC in both MPA and SPA applications for improved startup performance.
React Concurrency, Explained
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
Top Content
Watch video: React Concurrency, Explained
React 18's concurrent rendering, specifically the useTransition hook, optimizes app performance by allowing non-urgent updates to be processed without freezing the UI. However, there are drawbacks such as longer processing time for non-urgent updates and increased CPU usage. The useTransition hook works similarly to throttling or bouncing, making it useful for addressing performance issues caused by multiple small components. Libraries like React Query may require the use of alternative APIs to handle urgent and non-urgent updates effectively.
Jotai Atoms Are Just Functions
React Day Berlin 2022React Day Berlin 2022
22 min
Jotai Atoms Are Just Functions
Top Content
State management in React is a highly discussed topic with many libraries and solutions. Jotai is a new library based on atoms, which represent pieces of state. Atoms in Jotai are used to define state without holding values and can be used for global, semi-global, or local states. Jotai atoms are reusable definitions that are independent from React and can be used without React in an experimental library called Jotajsx.
The Future of Performance Tooling
JSNation 2022JSNation 2022
21 min
The Future of Performance Tooling
Top Content
Today's Talk discusses the future of performance tooling, focusing on user-centric, actionable, and contextual approaches. The introduction highlights Adi Osmani's expertise in performance tools and his passion for DevTools features. The Talk explores the integration of user flows into DevTools and Lighthouse, enabling performance measurement and optimization. It also showcases the import/export feature for user flows and the collaboration potential with Lighthouse. The Talk further delves into the use of flows with other tools like web page test and Cypress, offering cross-browser testing capabilities. The actionable aspect emphasizes the importance of metrics like Interaction to Next Paint and Total Blocking Time, as well as the improvements in Lighthouse and performance debugging tools. Lastly, the Talk emphasizes the iterative nature of performance improvement and the user-centric, actionable, and contextual future of performance tooling.

Workshops on related topic

React Performance Debugging Masterclass
React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
Featured WorkshopFree
Ivan Akulov
Ivan Akulov
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React, TypeScript, and TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
Web3 Workshop - Building Your First Dapp
React Advanced 2021React Advanced 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
Nader Dabit
Nader Dabit
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
Remix Fundamentals
React Summit 2022React Summit 2022
136 min
Remix Fundamentals
Top Content
Featured WorkshopFree
Kent C. Dodds
Kent C. Dodds
Building modern web applications is riddled with complexity And that's only if you bother to deal with the problems
Tired of wiring up onSubmit to backend APIs and making sure your client-side cache stays up-to-date? Wouldn't it be cool to be able to use the global nature of CSS to your benefit, rather than find tools or conventions to avoid or work around it? And how would you like nested layouts with intelligent and performance optimized data management that just works™?
Remix solves some of these problems, and completely eliminates the rest. You don't even have to think about server cache management or global CSS namespace clashes. It's not that Remix has APIs to avoid these problems, they simply don't exist when you're using Remix. Oh, and you don't need that huge complex graphql client when you're using Remix. They've got you covered. Ready to build faster apps faster?
At the end of this workshop, you'll know how to:- Create Remix Routes- Style Remix applications- Load data in Remix loaders- Mutate data with forms and actions
Vue3: Modern Frontend App Development
Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Top Content
Featured WorkshopFree
Mikhail Kuznetsov
Mikhail Kuznetsov
The Vue3 has been released in mid-2020. Besides many improvements and optimizations, the main feature of Vue3 brings is the Composition API – a new way to write and reuse reactive code. Let's learn more about how to use Composition API efficiently.

Besides core Vue3 features we'll explain examples of how to use popular libraries with Vue3.

Table of contents:
- Introduction to Vue3
- Composition API
- Core libraries
- Vue3 ecosystem

Prerequisites:
IDE of choice (Inellij or VSC) installed
Nodejs + NPM
Developing Dynamic Blogs with SvelteKit & Storyblok: A Hands-on Workshop
JSNation 2023JSNation 2023
174 min
Developing Dynamic Blogs with SvelteKit & Storyblok: A Hands-on Workshop
Top Content
Featured WorkshopFree
Alba Silvente Fuentes
Roberto Butti
2 authors
This SvelteKit workshop explores the integration of 3rd party services, such as Storyblok, in a SvelteKit project. Participants will learn how to create a SvelteKit project, leverage Svelte components, and connect to external APIs. The workshop covers important concepts including SSR, CSR, static site generation, and deploying the application using adapters. By the end of the workshop, attendees will have a solid understanding of building SvelteKit applications with API integrations and be prepared for deployment.