一番簡単なServer Side Renderingの話

最近のフロントエンド界隈ではSPA(Single Page Application)やSSR(Server Side Rendering)といった技術が盛り上がりを見せていました。

これまでSSRの勉強を試みましたが、正直よくわからず何度か勉強を頓挫していました。
しかし、今回、再度チャレンジしてみて最もシンプルな形のSSRを試してなんとか理解できたので、まとめてみます。

Server Side Renderingとは

早速本題に入っていきますが、SSRとは一言で言うと「サーバーサイドでHTMLを生成して描画する」技術です。

と言われても僕は正直何を言っているのかわかりませんでした。

webは従来、クライアントサイド(HTMLやCSS、JavaScript)とサーバーサイド(PHPやRuby、Goなど)と分けられます。

しかし、SSRでは、このクライアントサイドのページを表示する機能もサーバーサイドに持たせてしまおうということなのです。

では、SSRの何が嬉しいのか?ということについて解説します。

Server Side Renderingのメリット

サーバーサイドレンダリングのメリットは大きく2つあります。

  • SPAなどの初期表示が遅い技術の初期表示を高速化できる
  • TwitterやFacebookなどのクローラーに対応できる

SSRのメリット:SPAの初期表示高速化

SPAでは最初の表示時に

「空のHTML表示」+「JavaScriptの表示」

を行います。そのため、従来のweb技術と比較すると「JavaScriptの表示」分だけ初期表示の時間がかかってしまいます。

このJavaScriptの表示にはサーバーからデータを取得するといった作業が含まれているため、初期にロードするデータ量が多いほど表示速度も遅くなります。

サーバーサイドレンダリングでは、最初にページにアクセスした時点で、サーバー側でデータを整形した状態のHTMLを返すため初期ページの表示を高速化できるというわけなのです。

SSRのメリット:TwitterやFacebookのシェアに対応できる

また、従来のSPAではTwitterやFacebookなどでシェアされたときに表示される画像やタイトルの情報を表示することは基本的にはできません。

というのも、SPAでは空のHTMLが初期ロードの時点では返されるためURLをシェアしても中身のHTMLは空っぽになってしまうためです。

SSRでは、初期表示の時点できちんとデータが挿入されたHTMLを返すため、Twitterなどのシェアにも対応できるというわけなのです。

Server Side Renderingのサンプル

ここまでサーバーサイドレンダリングの概要をざっと説明しましたが、実際にコードを見ながらどのような技術なのか見ていきましょう。

今回、用意したのはシンプルなクリックをされるたびに数字がカウントされるというアプリケーションです。

具体的なソースを見てみましょう。

const express = require('express');
const http = require('http');
const _ = require('lodash');
const app = express();

let count = 0;
const countTemplate = `<%= count %>`;
const template = `
<div>
こんにちは、あなたは<span id='count'>${countTemplate}</span>番目のお客様です。
</div>
<button id='button'>count up</button>

<script>
const countCompiled = ${_.template(countTemplate)};
document.getElementById('button').addEventListener('click', () => {
    const req = new XMLHttpRequest();
    req.onload = (e) => {
        const count = document.getElementById('count');
        const result = JSON.parse(e.target.response);
        count.innerHTML = countCompiled(result);
    };
    req.open('GET', '/api/count');
    req.send();
});
</script>
`;

const compiled = _.template(template);

app.use('/api/count', (req, res, next) => {
    res.json({ count: count++ });
});

app.use((req, res, next) => {
    http.get({
        port: 3000,
        path: '/api/count'
    }, (response) => {
        let data = '';
        response.on('readable', () => {
            const chunk = response.read();
            if (chunk) {
                console.log(chunk.toString());
                data += chunk;
                console.log(data);
            }
        });
        response.on('end', () => {
            res.send(compiled(JSON.parse(data)));
        })
    })
});

app.listen(3000);

今回は、サーバーサイドのAPI処理をするためのライブラリとしてexpressというライブラリを使っています。そしてソースを見てみるとHTMLソースをサーバーサイドのapp.jsが管理していることがわかります。

一度目のアクセスの際には、最終的に50行目のようにHTMLソースが書かれたtemplateを表示しています。

また、サーバーサイドレンダリングでHTMLソースを保持することにより、フロントエンドでcountのような変数を持つことも簡単に行えます。

今回のケースでは、ボタンがclickされた際にクライアントサイドでHttpリクエストが行われ、ページの全部ではなく一部だけ更新するといった処理も加えています。

こちらはサーバーサイドレンダリングの直接的な恩恵ではありませんが、こういったメリットもあることは覚えておくといいかもしれません。

まとめ

今回は、サーバーサイドレンダリングについてまとめてみました。

ソースコードを github で公開しているので、必要に応じて見ていただければと思います。

SNSでもご購読できます。

コメントを残す

*