Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component-based server-side caching strategy #1210

Closed
ghost opened this issue Feb 19, 2017 · 5 comments
Closed

Component-based server-side caching strategy #1210

ghost opened this issue Feb 19, 2017 · 5 comments
Milestone

Comments

@ghost
Copy link

ghost commented Feb 19, 2017

Internal, opt-in component SSR caching/memoization instead of page caching.

react-dom-stream/lru-render-cache by @aickin

First, you must instantiate a cache object and pass it to either renderToString or renderToStaticMarkup as the cache attribute on the optional options argument. Currently, there is only one implementation of a cache, LRURenderCache, contained in the module react-dom-stream/lru-render-cache. It takes in an options object that has one attribute, max, which specifies the maximum number of characters in the cache. It looks like this:

import ReactDOMStream from "react-dom-stream/server";
import LRURenderCache from "react-dom-stream/lru-render-cache";

// create a cache that stores 64MB of text.
const myCache = LRURenderCache({max: 64 * 1024 * 1024});

app.get('/', (req, res) => {
    ReactDOMStream.renderToStaticMarkup(<Foo prop={value}/>, {cache: myCache}).pipe(res);
});

Second, you need to have your components opt in to caching by implementing a method called componentCacheKey, which returns a single String representing a useable cache key for that component's current state. The String returned by componentCacheKey must include all inputs to rendering so that it can be used as a cache key for the render. If componentCacheKey leaves out some of the inputs to rendering, it's possible that you will get cache collisions, and you will serve up the wrong content to your users. Here's an example of a correct implementation:

import React from "react"

export default class CacheableComponent extends React.Component {
    render() {
        return <span>Hello, ${this.props.name}!</span>;
    }

    componentCacheKey() {
        // the name prop completely specifies what the rendering will look like.
        return this.props.name;
    }
}

So next.js/examples/data-fetch/index.js becomes:

import React from 'react'
import Link from 'next/prefetch'
import 'isomorphic-fetch'

export default class MyPage extends React.Component {
  static async getInitialProps () {
    // eslint-disable-next-line no-undef
    const res = await fetch('https://api.github.com/repos/zeit/next.js')
    const json = await res.json()
    return { stars: json.stargazers_count }
  }

  render () {
    return (
      <div>
        <p>Next.js has {this.props.stars} ⭐️</p>
        <Link href='/preact'><a>How about preact?</a></Link>
      </div>
    )
  }

  componentCacheKey () {
    return this.props.stars;
  }
}
@ghost ghost changed the title Component-based caching strategy Component-based server-side caching strategy Feb 19, 2017
@arunoda
Copy link
Contributor

arunoda commented Feb 20, 2017

I think this one follows some similar ideas.
I think we can do something similar by simply using a current setup we've without doing any core Next.js modifications.

And I'd really like to have some examples with this.

@timneutkens
Copy link
Member

related #1004

@gcpantazis
Copy link
Contributor

I have an example of component-level caching in #2279, using Rapscallion.

@mrtkrcm
Copy link

mrtkrcm commented Mar 31, 2018

Any update on this. Are you guys planning to bring support anytime soon? Currently, I couldn't find any way to implement component-based caching.

like: https://github.com/rookLab/react-component-caching

@ericraio
Copy link

Any updates on this?

@Timer Timer added this to the backlog milestone Jun 3, 2020
@vercel vercel locked and limited conversation to collaborators Apr 12, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants