One of the main benefits of server-side rendering (SSR) is a better experience for users, who receive viewable content faster than they would with a client-side rendered application. In recent years, companies like Walmart and Airbnb have adopted SSR to deliver more performant user experiences with React. However, rendering a large application on the server can quickly become a performance bottleneck, tying up valuable resources.
Over the past couple years, there’s been a flurry of exploration into React SSR optimizations to address this issue. We’ve been following the work of Sasha Aickin, Airbnb, Walmart Labs, Formidable, Zeit, and others to identify areas ripe for improvement and produce lightning-fast server-rendered React applications. We’ve also been tracking new developments in React 16 that make SSR more efficient and versatile.
Today, we’re excited to introduce React Component Caching, a library that brings one of those optimizations to React 16.
Why Component Caching?
Caching comes up frequently in relationship to SSR, and for good reason: it has the potential to dramatically improve rendering speed by cutting down the server’s workload. Caching at the component level allows for flexibility in reaping the benefits of caching across pages that share components or display multiple instances of the same component.
Sasha Aickin introduced and demoed component caching in a 2016 talk on ways to speed up server-side rendering. Soon afterward, Walmart Labs created a component caching library with a profiling feature to time renders. The idea received attention at React Amsterdam last year, and it has surfaced in discussions on Github. A component caching API was also incorporated in Formidable’s React server renderer, Rapscallion.
With the release of React 16 last September, many of these efforts have been due for a reboot. React has improved the speed of its server-side rendering methods and now offers two streaming methods. We were curious if it was possible to harness the power of component caching with these new and improved methods. So we built React Component Caching to give developers the ability to do just that.
Two Types of Caching
Following in the footsteps of prior caching libraries, React Component Caching offers a simple strategy and a template strategy for caching components. With a simple caching strategy, a separate copy of a component is stored in the cache each time a component is rendered with different prop values. In contrast, a template strategy conserves space in the cache by storing a version of the component with opt-in placeholder values in place of actual props. A single cached template can be used to generate many versions of the same component with different prop values, which are restored during the rendering process.
Support for Streaming Methods
Components can be cached with the simple strategy while using either of the two new streaming server-side rendering methods (
renderToStaticNodeStream). These methods render React elements to readable streams that are piped to a caching transform function prior to sending chunks of data back to the client.
Redis and Memcached Support
React Component Caching provides a built-in LRU cache as well as support for Redis and Memcached. Any of these caches can be created on a Node rendering server and passed into the four available rendering methods.
A Few Things We’ve Learned
Cache operations are asynchronous by design.
“Get” and “set” functions are designed to execute asynchronously so as not to block the thread of execution. When server-rendering React components, however, it is necessary for asynchronous calls to the cache to complete before sending a response. To address this issue, we redefined React’s server-rendering methods to return promises so components would render in the correct order before sending a response.
Caching can be high-maintenance.
In exchange for impressive performance gains, caching brings some risks and challenges in code maintainability. For example, using a simple strategy to cache a component with frequently changing props can result in a ballooning cache. A template strategy can fail if the wrong props are specified for templating, and the risks are magnified when dealing with sensitive or user-specific data. These issues may seem trivial at first, but they can make updating components and props difficult to manage. The burden is on the developer to determine when caching is the right tool for the job.
Ready to start caching components in your server-rendered React 16 app? Download React Component Caching on npm today.
npm install react-component-caching