Application Isomorphique avec React

ReactJS France - 8 Décembre 2014

Yannick Croissant

Senior Software Engineer Front-End chez Deezer

yannickcr

yannickc

yannick.cr

Au tout début...

Site web classique

PHP

Java

Python

Ruby

Serveur

Client

JavaScript

Tout est fait côté serveur

Site web classique

JavaScript est seulement utilisé pour des animations et des interactions simple

La communication avec le serveur se fait via de simple requêtes HTTP (et parfois avec Ajax)

Aujourd'hui

Application Web

API

PHP

Java

Python

Ruby

Serveur

Client

JavaScript

JavaScript est maintenant une part importante de l'application.

Application Web

Le serveur et le client peuvent tous 2 avoir à faire du routing, templating et du formatage de donnée.

  • La duplication du code et de la logique peut rendre la maintenance et le évolutions du projet beaucoup plus complexes.
  • Peut engendrer des inconsistances et des bugs.

Application Web "Moderne"

API

Client

JavaScript

Tout est réalisé sur le client :

Application Web "Moderne"

Le serveur n'est alors seulement utilisé que pour servir les fichiers statiques (CSS, JS, HTML, Fonts).

  • Routing
  • Formatage des données
  • Templating

Pourquoi est-ce une mauvaise solution ?

Beaucoup de choses à faire avant même d'afficher un simple contenu :

Performances

Tout ceci à un impact significatif sur l'utilisation de l'application, en particulier sur mobile.

  • Parser les scripts
  • Demander les données à l'API
  • Recevoir ces données
  • Interpréter ces données
  • Recevoir les scripts
  • Executer les scripts

Tout le contenu est généré par Javascript, et est donc invisible pour les moteurs de recherche *

SEO

Solutions de contournement complexes afin d'éviter le problème :

  • phantom.js + archive statique de votre site web
  • prerender.io

 

Solidité

(Votre application en cas d'erreur JavaScript)

Mais aujourd'hui côté serveur il y a

Application Web Node.js

API

Serveur

Client

JavaScript

JavaScript

Application Isomorphique

API

Serveur

Client

JavaScript

JavaScript

Routing

Templating

Data fetching

Isomorphique ?

Popularisé par AirBnB en 2013 pour décrire une application dont le code est partagé entre le client et le serveur.

Aussi connu comme le "Saint Graal" des application web.

Plus de duplication de code ou de logique

Avantages

Nous pouvons pré-rendre notre application sur le serveur :

  • Rapidité
  • SEO
  • Plus grande tolérance aux erreurs

Cohérence entre le comportement côté client et côté serveur

Fonctionne de la même manière côté client ou côté serveur, seule la commande pour rendre l'application change :

Pourquoi React ?

Nous épargne les problématiques manipulation du DOM côté serveur grâce à son Virtual DOM.

var markup = React.renderToString(Component());
React.render(Component(), document.body);

Architecture Flux

Action

Dispatcher

Store

View

Action

Le plan

1. Recevoir la requête

2. Remplir notre store

3. Générer la vue en fonction des valeurs du store

4. Renvoyer cette vue au client

// Server.js
var React = require('react');
var App = require('./components/App.jsx');
var actionHandler = require('./lib/actionHandler');

var server = express();

server.use(actionHandler); // Handle the action and populate Store

server.use(function (req, res) { // Render the application
  var markup = React.renderToString(App());
  res.send('<!doctype html>' + markup);
});

server.listen(8000);
// App.jsx
var Store = require('../lib/Store');

var App = React.createClass({

  getInitialState: function() {
    return Store.get('app');
  },

  componentDidMount : function(){
    Store.addChangeListener('app', this._onStoreChange);
  },

  componentWillUnmount : function(){
    Store.removeChangeListener('app', this._onStoreChange);
  },

  render: function() {
    return (
      <html lang="en">
        <head>
          <meta charSet="utf-8" />
          <title>Isomorphic example</title>
        </head>
        <body>
          /* ... */
          <script dangerouslySetInnerHTML={{__html: 'window.Store=' + Store.export()}}></script>
          <script src="scripts/app.js"></script>
        </body>
      </html>
    );
  }
});
// Client.jsx
var React = require('react');
var App = require('./components/App.jsx');
var Store = require('./lib/Store');

Store.import(window.Store);

React.render(<App />, document);

Mais peut être n'avez vous pas (encore) JavaScript sur votre serveur.

Si c'est votre cas, React fourni plusieurs solutions pour compiler vos composants: .NET, Python, Rails, PHP

Pas idéal amha, mais peut aider à facilement pré-rendre son application côté serveur sur une stack existante.

Et sans Node.js ?

Notre application est pré-générée côté serveur puis "démarrée" côté client.

Partage des stores et composants React entre le client et le serveur.

Bilan

On pourrait aller encore plus loin :

React-router: Parce que pourquoi se limiter seulement aux stores et aux composants ?

Fluxible App: Conteneur pour construire une application isomorphique à partir d'une architecture Flux

La source des données, l'API, est la clé, le lien entre le client et le serveur.

Trouvez un moyen de générer vos composants côté serveur, nativement avec Node.js ou via des extensions pour les autres languages.

Essayez d'aller au delà des composants (routes)

Par où commencer ?

Merci

Des questions ?

Sources

Isomorphic Application with ReactJS

By Yannick Croissant

Isomorphic Application with ReactJS

  • 2,220