概要
Node.js, SPA, Universal JSあたりについてまとめた勉強会用メモ。
ざっくり流れを書くと
- Nodeという、サーバ側をJSで書けるプラットフォームがあり、そこでNode.jsが動く
- SPAという、ユーザのUXが向上するWebアプリの形式があり、SSR+CSRで実装をするのが良さげ
- Universal JSでJSを記述すればサーバもクライアントもJSに統一されてSSR + CSRが柔軟に行える
- Universal JSによるSSRは、DOMを抽象化したReactの仮想DOMと相性が良く、素敵なReact + SPAライフが過ごせる
Node.js
「サーバサイドでJavaScriptを動かせるプラットフォーム」であるNodeというものがあり、Node上では動くがブラウザでは動かないJSの関数などがある。それらを総称してNode.jsという。
Nodeにはhttpサーバの役割などもあり、これによりサーバ開発をJSで行うことが出来る。
SPAの仕組み
概念
- ブラウザやブラウザレンダリングエンジン内で動作するWebアプリケーションであり
- ブラウザで最初に開いたURLを起点にして、さまざまな画面遷移が提供されるが、基本的には最初に返されたページ内でユーザーインターフェースが完結し
- URLは、ページ内のユーザーインターフェースの遷移でも逐次変化し、ブラウザの履歴で前の画面にさかのぼることが可能で
- ページに必要なデータはサーバーからAPIなどの形を通じて、必要時に断片的に提供される
というようなスタイルがよくある定義ですが、Webブラウザ上でデスクトップアプリケーションやネイティブアプリケーションのような使い勝手を提供した上で、既存のWebアプリケーションの良いところを併せ持つ形として、上記のようなアプローチになっているというほうが正しいのかもしれません。
メリット
- いちいちページを再描画しないためUXが向上する(高速化はもちろん、Facebookでいえば、チャットを開いたままコンテンツを切り替えたり)
- PWA(後述)にすればネイティブアプリのように扱える
デメリット
- SSR(実装コスト大)をしない場合、JSの読み込みと描画を待つため初期表示まで時間がかかる
- SSR(実装コスト大)をしない場合(クローラによっては)SEOに問題が出る
利用シーン
ページ遷移やコンテンツ操作といった、ユーザからのアクションによる表示内容の更新をブラウザ側で行えるのがSPAのメリットであるため、SNS、データ可視化サービス、チケットの座席指定サービスなどには導入する価値がある(具体例はFacebookやGoogle Mapsなど)。
一方、最初の描画で情報が完結するブログのような、直帰率の高いサービスはSPAに向かない。
シングルページアプリケーション(SPA)の導入メリット&デメリット
ルーティング
ユーザのアクションに応じてURLを逐次変化させること。
ブラウザの履歴で前の画面に戻ることも可能にする。
ハッシュによるルーティング
URLの末尾にハッシュ #
で識別子をつけてURLを変更する。ブラウザの履歴にも残る。
http://example.com#hoge
location.hash
で取得でき、ハッシュが変更されると hashchange
イベントが発火する。
実装は容易なものの、Hashより前のURLの要素(パスとか)は変化しない。
また、HTTPリクエストにハッシュは含まれないため、ハッシュによる遷移を起点にサーバへリクエストを送るといったことは出来ない(SSRできない)。
HistoryAPIによるルーティング
HTML5で追加されたHistoryAPIは以下の特徴を持つため、SPAと相性が良い。
- 状態をオブジェクトで保持できる
- パスも変更できるため、サーバにパスの情報を渡せる
history.pushState(state, title, '/hoge')
で遷移を行い history.state
で状態が取得できる。ブラウザの戻る・進むイベントで popstate
イベントが発火する。
レンダリング
「いつ、どこで、どこまでレンダリングするか」
- リクエスト時にクライアント側ですべてレンダリングする(CSR)
- リクエスト時にサーバ側で最低限(ファーストビューやSEO用の部分)レンダリングし、それ以降をクライアント側でレンダリングする(SSRとCSR)
- JSのビルド時にサーバ側で最低限レンダリングをして静的ファイルを生成しておき、リクエスト時はその静的ファイルとその後の動作に必要なJSを返してクライアント側でレンダリングする(プリレンダリングとCSR)
手法 | 実装の容易さ | 初期表示 | 柔軟性 | 備考 |
---|---|---|---|---|
CSR | ◯ | ◯ | 初期表示が遅い | |
SSRとCSR | ◯ | ◯ | 実装コストが高い | |
プリレンダリングとCSR | ◯ | ◯ | ユーザごとに表示内容が異なるページには適用不可 |
正確にはプリレンダリングは色々な手法があるらしいものの、割愛。
Code Split
実行するJSをクライアント側に丸々渡すと重くなるので、ユーザのアクションに応じて必要なコードを取得するようにすること。
PWA(Progressive Web Apps)
ネイティブアプリライクなUIを提供するWebアプリ。Googleが推進。
- W3Cで策定されているWeb App Manifestで、端末のホーム画面にアイコン付きで追加させたりスプラッシュ画面を出したりする
- Service Workerを使ってpush通知を送ったりオフラインで動作させたりする
開発者側のメリット
- クロスプラットフォーム
- 審査不要
- SEO
ユーザ側メリット
- オフラインで閲覧可能
- 読み込みが早い
デメリット
- ブラウザにより対応状況が異なる
Universal JS
前述の通り、SPAにはSEOや初期ローディングの問題がある。その問題を解決するためのアプローチとしてSSRを行うために、クライアントとサーバで同じコードを実行する必要がある。
サーバでもクライアントでも動作するJSのことをUniversal JSという。
ただ「UXを最適化するにはプラットフォームごとにアプリケーションを構築するのが最善」という批判もあるらしい。
Reactの仮想DOM
Reactの仮想DOMでは、DOMをただのオブジェクトに抽象化している。
その結果、差分を検知してレンダリングするのはもちろんのこと、DOM APIが存在しない世界(サーバ側)でもDOMを弄くり回せる。
つまり、Universal JSでReactを書けば
- クライアント側で差分レンダリングをする
- NodeでSSRをして、クライアントでCSRをするSPAが実装可能
という良いことづくしでとても嬉しい。
余談:Isomorphic? Universal?
もともとはIsomorphic JSと呼ばれていたものの、この記事を発端にUniversal JSという名称へ変わっていったらしい。
と思ったら、この記事のようにUniversalとIsomorphicを明確に使い分けることもあるらしい
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
0件のコメント