Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

Next.jsのサーバーサイドレンダリングで、シングルページアプリケーションの課題を解消

基礎からはじめるReact入門 第14回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2018/11/09 14:00

 シンプルに構成されたシングルページアプリケーションでは、サーバーはファイルを配信するだけで、画面を組み上げるための処理はブラウザ側で行われます。この方式におけるいくつかのデメリットを埋めるために考案されたのが、ある程度の画面構築をサーバー側で行う、サーバーサイドレンダリングです。今回は、サーバーサイドレンダリングの概要と、実際に使う場合のフレームワークの解説を行います。

目次

対象読者

  •  JavaScriptとWeb開発の基礎に理解がある方
  •  Reactに興味/関心があり、これから学び始める方

前提環境

 筆者の検証環境は以下の通りです。

  • macOS High Sierra 10.13.3
  • Node.js v10.4.1/npm 6.1.0
  • React 16.5.1
  • firebase-tools 4.2.1
  • create-next-app 0.5.9
  • Next.js 6.1.2
  • Babel 7.0.0

シングルページアプリケーションが苦手なこと

 前回まで、create-react-appを用いたシングルページアプリケーションの開発手法について解説してきました。ここで、シングルページアプリケーションにおけるサーバーとブラウザの関係を、おさらいしておきましょう。

 前回解説した通り、シングルページアプリケーションにおけるサーバーの役割は、HTMLやJavaScriptなどのファイルを保管し、ブラウザからの要求に応じて配信することです(図1)。

図1:サーバーとブラウザの関係
図1:サーバーとブラウザの関係

 ファイルを受け取ったブラウザは、JavaScriptをひと通り解釈した後、Reactであれば ReactDOM.render() を起点にしてDOMツリーの管理を開始します。この後は、ページ遷移のためにHTMLを読み込み直すこともなく、Virtual DOMで管理できる範囲で画面の書き換えを行っていくため、応答速度が高いアプリケーションを作りやすいと言われています。

 さて、そんなシングルページアプリケーションですが、その性質に由来する弱点もあります。今回は次の2つについて着目します。

  • ファイルサイズが大きくなりがち
  • HTMLだけを取得されるとコンテンツが空になる

 それぞれ、どういった点で問題になるのか、見ていきましょう。

ファイルサイズが大きくなる

 シングルページアプリケーションのような近代的なJavaScriptアプリケーションでは、自分で書いたすべてのJavaScriptファイルと、そこから呼び出されたすべてのライブラリを、1つのJavaScriptファイルに結合しています。これによって require()import XXX from 'xxx' といった、モジュール読み込みの仕組みを実現しています。

 旧来のJavaScriptアプリケーション開発のように、グローバル変数の領域で各ライブラリが名前空間を奪い合うやり方に比べれば、格段に良い方式ではあるのですが、これはこれで新たな問題を抱えました。ファイルサイズが大きくなりがちなのです。

 前回デプロイに使ったサンプルプロジェクトを例に挙げます。create-react-app で作ったプロジェクトをそのままビルドしたので、あの方法で作れる最小のサイズになっているはずです。

 ビルド後のフォルダの中を見てみると、118KBでした(図2)。

図2:ファイルサイズが大きくなりがち
図2:ファイルサイズが大きくなりがち

 118KBと言えば、ちょっとしたJPEG画像に匹敵するファイルサイズです。とはいえ、現代の通信速度であれば、目くじらを立てるようなサイズではないのかもしれません。ただ、これは最小のサイズです。実際の開発の現場で、何の手だても打たずに開発を進めていくと、1MBを超える、ともすると数MBに達するような、巨大なJavaScriptファイルに出会うこともあります。

 数MBともなってくると、速度の速いWi-Fiにつながったパソコンならばともかく、回線の遅いモバイルブラウザでは目に見えて待ち時間が発生します。場合によっては5秒や10秒では済まないかもしれません。

 ダウンロードが終われば速いものの、それまでにかかる時間が長くなってしまうことがある。これがシングルページアプリケーションの弱点の1つです。

コンテンツが空になる

 また別の問題もあります。クローラーなどがWebページを見に来たときに、空のコンテンツを返してしまうのです。

 Googleをはじめとした検索エンジンの類いは、ときどき私たちのWebページを巡回して、情報の取得や更新を行っています。こういったクローラーと呼ばれるアプリケーションと、シングルページアプリケーションは少し相性が悪いです。なぜならば、クローラーの中には、HTMLファイルだけを取得して、その内容だけでコンテンツを判断しようとするものがあるからです。

 例えば、 create-react-app で作ったシングルページアプリケーションの場合、初期設定ではリスト1のHTMLファイルが配信されます。

[リスト1]シングルページアプリケーションのHTMLファイルの例
<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- 略 -->
    <title>React App</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <script
      type="text/javascript"
      src="/static/js/main.a285be49.js">
    </script>
  </body>
</html>

 ブラウザで表示する場合であれば、JavaScriptが実行されて ReactDOM.render() が実行されれば、 <div id="root"></div> の中に相当するDOMツリーにコンテンツが追加されていきます。

 しかし、クローラーの場合はそうはいきません。クローラーはファイルをダウンロードするだけなのです。そこにあるのは空虚な <div id="root"></div> だけで、機械的に「なにもないページ」と判断されるだけです。

 ページの検索順位を上げたいWebサイト管理者からすれば、たまったものではありません。これもシングルページアプリケーションの注意すべき弱点です。

[コラム]クローラーが賢くなってきている

 クローラーにコンテンツが入ったHTMLを返せないことを問題として挙げましたが、少なくともGoogleでは、この問題は解消されています。HTMLを読み込んだ後、JavaScriptによって描画されるコンテンツも、監視対象に含めてくれているのです。同じ検索エンジンを使っている、Yahoo!JAPANも同様です。

 こういったケースもあるため、JavaScriptによって描画されるコンテンツを解釈しないクローラーに読まれることを想定している方だけが、クローラーの問題を考慮する必要があります。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:基礎からはじめるReact入門

もっと読む

All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5