$30 off During Our Annual Pro Sale. View Details »

React ESI: Blazing Fast SSR

React ESI: Blazing Fast SSR

React ESI is a super powerful cache library for vanilla React and Next.js applications, that can make highly dynamic applications as fast as static sites. It provides a straightforward way to boost your application's performance by storing fragments of server-side rendered pages in edge cache servers. It means that after the first rendering, fragments of your pages will be served in a few milliseconds by servers close to your end users! It's a very efficient way to improve the performance and the SEO of your websites; and to dramatically reduce both your hosting costs and the energy consumption of these applications. Help the planet, use React ESI!

Because it is built on top of the Edge Side Includes (ESI) W3C specification, React ESI natively supports most of the well-known cloud cache providers including Cloudflare Workers, Akamai and Fastly. Of course, React ESI also supports the open source Varnish cache server that you can use in your own infrastructure for free (configuration example).

Also, React ESI allows to specify a different Time To Live (TTL) per React component and to generate the corresponding HTML asynchronously using a secure (signed) URL. The cache server fetches and stores in the cache all the needed fragments (the HTML corresponding to every React component), builds the final page and sends it to the browser. React ESI also allows components to (re-)render client-side without any specific configuration.

Kévin Dunglas

April 23, 2019
Tweet

More Decks by Kévin Dunglas

Other Decks in Programming

Transcript

  1. React ESI

    Blazing Fast SSR

    View Slide

  2. React ESI @dunglas
    Kévin Dunglas
    ❏ Les-Tilleuls.coop’s Founder
    ❏ Symfony Core Team (PHP )
    ❏ API Platform and Mercure creator
    @dunglas

    View Slide

  3. React ESI @dunglas
    ✍ Self-managed since 2011
    ‐ 36 people, 1,000% in 6 years
    [email protected]

    View Slide

  4. React ESI @dunglas
    Single Page Apps

    View Slide

  5. React ESI @dunglas
    Server-Side (PHP) vs Client-Side (JS) Rendering
    © Microsoft

    View Slide

  6. React ESI @dunglas
    Single Page Apps are So Cool
    ❏ Update only what is needed (web components)
    ❏ No full page reload
    ❏ No « white flash »
    ❏ Smaller network payloads (JSON vs HTML)
    ❏ Rich UX

    View Slide

  7. React ESI @dunglas
    SPAs is the 1st step for Progressive Web Apps
    © Google

    View Slide

  8. React ESI @dunglas
    PWA are Powered by Service Workers

    View Slide

  9. React ESI @dunglas
    Creating Fast SPAs/PWAs is Now Easy

    View Slide

  10. React ESI @dunglas
    But SPAs Have Major Drawbacks: SEO
    « Currently, it's difficult to process JavaScript and not all search engine
    crawlers are able to process it successfully or immediately.

    In the future, we hope that this problem can be fixed, but in the meantime
    […]. »

    View Slide

  11. React ESI @dunglas
    But SPAs Do Have Drawbacks: Initial Load Time

    View Slide

  12. React ESI @dunglas
    Server-Side Rendering

    View Slide

  13. React ESI @dunglas
    © Wallmart Labs

    View Slide

  14. React ESI @dunglas
    © Wallmart Labs
    © Wallmart Labs

    View Slide

  15. React ESI @dunglas
    SSR Benefits
    ❏ Typical SEO (like in PHP)
    ❏ Fast Initial Display (theoretically)
    ❏ SPA/PWA when fully loaded
    ❏ One code base, client-side/server-side
    (theoretically… again)

    View Slide

  16. React ESI @dunglas
    SSR with React
    import React from "react";
    import ReactDOMServer from "react-dom/server";
    const Index = () => (

    Hello

    );
    const pageContent = ReactDOMServer.renderToString();

    View Slide

  17. React ESI @dunglas
    SSR With React

    View Slide

  18. React ESI @dunglas
    SSR Drawbacks: Performance
    ❏ All the page must be computed, every time,
    before sending it to the client
    ❏ The server must wait for all data needed to
    display the page
    ❏ The cache can be set only per full page, not per
    component

    View Slide

  19. React ESI @dunglas
    What You Really Want
    © Akabia.fr

    View Slide

  20. React ESI @dunglas
    How to Implement That With React/Vue/…?

    View Slide

  21. React ESI @dunglas
    Edge Side Includes
    Here Come ESI

    View Slide

  22. React ESI @dunglas
    ESI at a Glance
    © merge.nl weblog

    View Slide

  23. React ESI @dunglas
    Edge Side Includes
    ❏ Kind of server-side iframe
    ❏ Page composition is usually handled by a cache
    server (edge server)
    ❏ Every fragment can have a different TTL
    ❏ Use standard HTTP cache headers

    View Slide

  24. React ESI @dunglas
    Edge Side Includes
    ❏ Created by Akamai
    ❏ Supported by Varnish (open source), Squid,
    CloudFlare, Fastly, Akamai…
    ❏ Open format, submitted to the W3C in 2001 (not
    accepted)
    ❏ Implemented in Symfony since 2011

    View Slide

  25. React ESI @dunglas

    Just Add the Tag, the Cache Server Will
    Handle Everything Else
    Could be implemented directly using Node, or CloudFlare Workers

    View Slide

  26. React ESI @dunglas
    Blazing-fast Server-Side Rendering for React and Next.js
    React ESI

    View Slide

  27. React ESI @dunglas
    React ESI
    ❏ Server-side, replace React components you want
    by an ESI tag
    ❏ Specify a different TTL per component
    ❏ The corresponding HTML is generated
    asynchronously
    ❏ The cache server fetches and stores in its cache
    all the needed fragments

    View Slide

  28. React ESI @dunglas
    React ESI
    © The Varnish book

    View Slide

  29. React ESI @dunglas
    React ESI: the Higher Order Component
    import React from 'react';
    import withESI from 'react-esi';
    import MyFragment from 'components/MyFragment';
    const MyFragmentESI = withESI(MyFragment, 'MyFragment');
    // The second parameter is an unique ID identifying this fragment.
    // If you use different instances of the same component, use a different ID per instance.
    const Index = () => (

    React ESI demo app


    );

    View Slide

  30. React ESI @dunglas
    A Fragment
    export default class MyFragment extends React.Component {
    render() {
    return (

    A fragment {this.props.greeting /* access to the props as usual */}

    );
    }
    }

    View Slide

  31. React ESI @dunglas
    Setting a TTL
    export default class MyFragment extends React.Component {
    render() {
    return (

    );
    }
    static async getInitialProps({ props, req, res }) {
    return new Promise(resolve => {
    // Set a TTL for this fragment
    if (res) res.set('Cache-Control', 's-maxage=60, max-age=30');
    });
    }
    }

    View Slide

  32. React ESI @dunglas
    Computing initial props
    export default class MyFragment extends React.Component {
    render() {/*..*/}
    static async getInitialProps({ props, req, res }) {
    return new Promise(resolve => {
    setTimeout( // Simulate a delay (call to a remote service such as a web API)
    () =>
    resolve({
    ...props, // Props coming from the parent, passed through the internal URL
    dataFromAnAPI: 'Hello there’
    }),
    2000
    );
    });
    }
    }

    View Slide

  33. React ESI @dunglas
    Serving The Fragments (internal URL)
    import express from 'express';
    import { path, serveFragment } from 'react-esi/lib/server';
    const server = express();
    server.get(path, (req, res) =>
    // "path" default to /_fragment, change it using the REACT_ESI_PATH env var
    serveFragment(
    req,
    res,
    // "fragmentID" is the second parameter passed to the "WithESI" HOC, the root component used
    for this fragment must be returned
    fragmentID => require(`./components/${fragmentID}`).default)
    );

    View Slide

  34. React ESI @dunglas
    State
    Reconciliation

    View Slide

  35. React ESI @dunglas
    State Reconciliation
    ❏ Prevent fetching data clients-side and server-side
    ❏ During the 1st request (server-side), data are
    fetched and initial props are computed
    ❏ The initial props are serialized and injected in the
    server-side HTML (in a tag)<br/>❏ Client-side, React ESI automatically finds and<br/>reuses these props when initializing the<br/>components<br/>

    View Slide

  36. React ESI @dunglas
    Next.js Integration

    View Slide

  37. React ESI @dunglas

    View Slide

  38. React ESI @dunglas
    Thanks!
    Any questions?

    View Slide