シングルページアプリケーション

シングルページアプリケーション（、SPA）とは、単一のWebページのみから構成することで、デスクトップアプリケーションのようなユーザ体験を提供するWebアプリケーションまたはWebサイトである。必要なコード（HTML、JavaScript、CSS）は最初にまとめて読み込むか、ユーザの操作などに応じて動的にサーバと通信し、必要なものだけ読み込みを行う。
技術.
ページの遷移を伴わずにサーバと通信を行う技術には様々なものがある。
JavaScriptフレームワーク.
AngularJS、Ember.js、Meteor.js、Vue.js、ReactなどのJavaScriptフレームワークはSPAの原則を採用している。
データ転送.
サーバへリクエストすると、通常は生データ（XMLやJSON）かHTMLのどちらかが送られてくる。HTMLであれば、クライアント側はJavaScriptでDOMの一部を更新する。生データであれば、クライアント側ではJavaScriptでテンプレートなどによってHTMLに変換し、その後同様にDOMの更新を行う。
サーバアーキテクチャ.
Thin server architecture.
クライアント側がロジックを持つ方法である。この方法ではサーバは純粋なAPIやWebサービスとなる。複雑さがサーバからクライアントに移動していることから Thin server architecture と呼ばれることがあるが、システム全体としての複雑さが削減されているかどうかは議論がある。
Thick stateful server architecture.
サーバ側でクライアントのページの状態を記憶しておく方法である。リクエストを受けるとサーバは変更を伴う具体的なHTMLやJavaScriptを返し（クライアント側はこれでDOMの一部を更新する）、同時にサーバの状態を更新する。ロジックはほとんどサーバ側で実行され、HTMLも通常サーバ側で生成される。いくつかの方法では、サーバはブラウザをシミュレートし、イベントを受け取ると、シミュレートした状態がクライアントに自動的に伝播するようにして変更を実行する。
この方法はサーバのメモリやプロセッサ資源が多く必要である。しかし、アプリケーションがすべてサーバ側で実装されること、またカスタムの通信をクライアントと持たないためサーバ内のデータや状態が同一のメモリ空間で共有できることから、開発モデルが単純化されるという利点がある。
Thick stateless server architecture.
サーバ側では状態を持たず、クライアントがリクエストの際にページの状態を送る方法である。サーバはこのデータからページを再構築し、JSONやJavaScriptといった必要なデータやコードを生成してクライアントに返す。
この方法はサーバに送るデータが大きく、リクエストのたびにサーバ側でページを再構築するため計算資源が多く必要である。一方でクライアントごとのページデータを持たないことから、セッションの共有なしにAjaxリクエストを別のサーバで処理することが可能であり、スケールしやすいという利点がある。
ローカルでの実行.
一部のSPAはfile URIスキームを使用してローカルファイルから実行できる。これにより、ユーザがサーバからSPAをダウンロードしたあと、サーバとの接続に依存せずにローカルストレージからファイルを実行することが可能である。このようなSPAでデータを保存・更新したい場合は、ブラウザベースのを使用する必要がある。
SPAにおける課題.
SPAはブラウザがもともと考慮していたステートレスなページ遷移モデルとは大きく異なるため、いくつか新たな課題が生じている。しかし、以下のものでそれらに対処することが可能である。
検索エンジン最適化 (SEO).
いくつかの一般的な検索エンジンのクローラではJavaScriptが実行されないため、SPAを採用しようとしているWebサイトにとってSEOはかねての課題である。これはSPAにとって些細な問題ではなく、検索エンジンへのインデックス付けが必須または望ましい状況では一般的にSPAは使用されない。
2009年以降、Googleは「AJAX crawling scheme」を提案・推奨していた。これはクローラが必要なメタデータを抽出できるよう、SPAに特別な動作の実装を要求するものであった。この提案は2015年に非推奨となった。
Webサイトがクロール可能であるかのようにする方法はいくつかある。サーバでHTMLベースのサイトを生成してそれをクローラに渡す方法や、PhantomJSなどのヘッドレスブラウザでJavaScriptアプリケーションを実行してHTMLを出力する方法である。これらはいずれもSPAとは別個にHTMLページを作成しなければならない。かなりの労力が必要であるし、大規模なサイトではメンテナンスに苦労することになる。さらには、SEOの落とし穴も存在する。サーバが生成したHTMLがSPAの内容と大きく異なるとみなされると、サイトにペナルティが課せられる。PhantoｍJSでHTMLを出力した場合は、ページのレスポンスが遅くなる可能性があり、これは検索エンジン、特にGoogleにおいてランクを低下させる要因となる。
ブラウザの履歴保持.
単一のページしか持たないSPAは、ブラウザの「戻る」「進む」ボタンによるページの履歴ナビゲーションと相性が悪い。ユーザがSPA内の前の画面を期待して戻るボタンを押したにもかかわらず、SPAがアンロードされ、ブラウザの履歴における前のページを表示することになり、ユーザビリティの障害となる。
従来のSPAにおける解決策は、ブラウザのURLのフラグメント識別子（ハッシュ）を画面状態に応じて変更することであった。これはJavaScriptによって実現でき、URL履歴イベントをブラウザ内に構築する。SPAがURLハッシュに含まれる情報から同じ画面状態を復元できる限り、期待される戻るボタンの動作は保持される。
この問題へのさらなる対処として、HTML5ではブラウザの履歴操作の機能を提供する HTML5 History API が導入された 。
アナリティクス.
Google Analyticsなどの解析ツールは、最初のロードによって開始されたあと、ブラウザによるページの読み込みに依存して動作する。しかし、SPAではこの方法をとることができないため、リソースの更新時にトラッカーを更新する関数を明示的に呼び出すことによって対処する。呼び出しに失敗すると、解析ツールはサイト上で誰が何をしているのかわからない。
HTML5 History APIを使うとSPAにページの読み込みイベントを追加でき、解析に有用である。また、フレームワークによっては主要なアナリティクスサービスに対応するオープンソースの統合解析ツールを提供している。
最初の読み込みの遅延.
SPAはサーバベースのアプリケーションよりも最初のページの読み込みが遅くなる。これはビューをレンダリングする前にフレームワークとアプリケーションコードを読み込まなければならないためである。サーバベースのアプリケーションであれば必要なHTMLを取得するだけでよいため、通信にかかる時間は短い。
キャッシングや遅延ロードモジュールなど、SPAの最初の読み込みを高速化する方法はいくつかある。しかし依然として、フレームワークとアプリケーションコードの少なくとも一部をダウンロードし、かつ多くの場合においてブラウザ上に何らかの表示をするためにAPIによるデータ取得が必要である、という事実は変わらない。このパフォーマンスと待ち時間の問題は、「いま払うか、あとで払うか」というトレードオフであり、開発者が決定しなければならないものである。