真のサーバーレスに一段近づけるフロントエンドアーキテクチャーの話
「真のサーバーレス」の定義について
一般的にサーバーレスとは、サーバーの管理が不要になったフルマネジードサービスのことを指します。クラウドのFaaS(Function as a Service)が代表です。しかし、言葉的には、「サーバーが無い」という意味に受け取ることが第一想起することではないでしょうか?
サーバーが無い状態のよくある形態は、デスクトップアプリケーションです。ローカル環境にインストールして単独で動くソフトウェアです。OSに添付されている電卓アプリなんかが典型です。しかし、わざわざこれを「サーバーが無い」アーキテクチャーと呼ぶのも本末転倒な話です。むしろこっちが基本形で、シングルからマルチへと、高度な用途を実現するためにクライアント・サーバーアーキテクチャーに発展したわけです。この高度な用途はキープしたまま、特定の供給源となるサーバーが不要になっている状態なら、あえてサーバーレスと名付ける意味が出てきそうです。例えば、P2P(Peer to Peer)です。
よって、本記事では、サーバーレスを「サーバーが無い」という意味に戻した上で、第一段階として 「ローカル環境で単独で動けるソフトウェア」、第二段階として 「ネットワーク上に展開しているが特定のサーバーに依存せずに機能するアーキテクチャー」 のことと定義します。
この記事の内容
真のサーバーレスに一段近づけるフロントエンドアーキテクチャーの事例を一つ紹介します。次に、最近のフロントエンドの潮流に位置付けてその意味を考えます。
レシピ
3つの技術にフォーカスして、真のサーバーレスに一段近づけるフロントエンドアーキテクチャーの実現方法を解説します。基本的には、静的ブログサイト構築のユースケースが先鞭となりJAMstackとして発展してきたSPA(シングル・ページ・アプリケーション)とCDN(コンテンツ・デリバリー・ネットワーク)を用いたフロントエンド・セントリックなアーキテクチャーをベースとしつつ、さらにホスティングの分散化を進めた構成になります。
1. Hashルーティング(デスクトップアプリ化)
URLの割り当てに対する遷移をクライアントで完全にコントロールします。通常のSPAでは、ルート以外のURLがサーバ側に来た時にindexファイルを返すようなwebサーバのルーティングを用意しますが、完全なサーバーレスを目指すとそのフォールバック的なルーティングすらしんどいです。なぜなら、そのフォールバック的なルーティングを行うはずのwebサーバすら無くそうとしているのですから。
そのためにhistoryAPIを使ったルーティングではなく、Hashルーティングを用います。ブラウザはHash以下をhttpリクエストとしてサーバへ送らないので、クライアントアプリだけで完結するようになり、ホストはアプリケーションファイルの配布だけで済むようになります。
以下のようなURLを例に取ります。#がHashのことです。
https://hoge.com/#/fuga/1
ネットワークにリクエストするのはhttps://hoge.com/
だけになり、クライアントアプリケーションのindex.htmlを返します。index.htmlからjavascriptファイルを取得して、javascriptの評価実行が終わった後に、Hash以下の/fuga/1
を処理して、対応するコンポーネントで画面を作成します。これなら、ホストはindex.htmlを供給する配布サーバの役目だけで十分になり、かつ、SNSなどで特定ページhttps://hoge.com/#/fuga/1
が直接シェアされても、ちゃんと表示することができます。
2. IPFS(ホスティング)
IPFS(InterPlanetary File System)は、P2Pのファイル共有システムです。ノードクライアントがOSS化されており、乱暴に言えば誰でも建てられるCDNみたいな使い方が可能です。HTTPがどこのホストのどのディレクトリのどのファイルかを指定するロケーション指向型のプロトコルに対して、どこに置いているかは問わずに(P2Pで拡散されていく) コンテンツの内容自体を直接指定するコンテンツ指向型プロトコルとされています。
例えば/ipfs/QmXoypizjW3WknF00000L72vedxjQkDDP1mXWo6uco/index.html
のようにIPFS上のパスを用意して、DNSでhttps://hoge.com/
にリンクしたら、ブラウザなどからアクセスできるようになります。
ここで前項のHashルーティングが活きてきます。Hashルーティングならアプリケーションファイルの供給だけができればいいので、ファイルコンテンツを指定するだけのIPFSで十分に事足りるようになるのです。
3. PWA(パッケージング配布)
近年、HTML5の後継としてPWA(プログレッシブ・ウェブ・アプリケーション)というコンセプトが提唱され、各ブラウザに実装されてきました。その中でも、特にServiceWorkerを用いてhtml/css/js/画像をブラウザにキャッシングする技術があります。これを用いると、いわばアプリストアからソフトウェアをインストールするが如く、ウェブでもネットワークリクエストすることなくオフラインでアプリケーションを利用できるようになります。つまり、初回だけはIPFSにリクエストしてファイルを取得しますが、以後はPWAでキャッシングされたファイルを用いるのでIPFSにアクセスする必要がなくなります。また、スマートフォンならネイティブアプリと同様にホームスクリーンにセットできるし、パソコンでもいくつかの方法でデスクトップアプリ化(chromeアプリ(2022年6月まで)、Web Bundlesなど)することもできます。
以上となりますが、この構成を取ると、一応IPFSでアプリケーションファイルのホスティングしますが、それすら便宜上のために用意しているようなものです。例えば、CD-ROMなどに焼き付けてアプリケーションファイルをローカル経由で配布して、ブラウザでfile://
プロトコルで立ち上げても動作します。(もちろんhttpsが必要なAPI(カメラアクセスなど)の制限は発生します。)
実用例
このような分散アーキテクチャーは、クリプトと呼ばれる分野で発展しています。上記のレシピを用いて、サーバーレスのアプリケーションを実現している例として、暗号資産取引のデファクトポジションになりつつある 「Uniswap」というアプリケーションをピックアップします。
- サブドメイン
app.uniswap.org
でサーブされているもの - クライアントアプリケーション(本リポジトリ)と、ブロックチェーン(ethereum)の2層構造
- create-react-app
- IPFSはCloudFlareのgatewayを利用
- GoogleAnalytics搭載
- OGPの設定は無し
- ServiceWorkerは現在バグのためオフにされている
あくまで個人の所感ですが、訪問者があらかじめ目的を持って利用するタイプでウェブ上での集客が不要だからか、SEOやOGPのようなweb最適化は捨てているように見えます。また、same originのセキュリティ担保もほぼ無用になっています。実際、配布ホストは以下のツイートのように分散化されていて、他のドメインから利用してもアプリの動作に支障ありません。Braveというブラウザなら、httpすら使わずにipfsプロトコルのままブラウザからアクセスすることも可能です。(ただし、利用にあたっては、アプリケーションファイルに改ざんが無いかなどを把握できる強いセキュリティリテラシーが必要になります。また、PWAにはsame originが必要になってきます。)
なお、他にもサブドメインのサイトがいくつもありますが、他は普通のウェブアプリです。例えばランディングページはgatsbyを用いたSSG(静的サイト生成)で作られていますが、クラウド上のサーバールーティングやAPIサーバも普通に用意されています。
フロントエンドの最近の潮流とは異なる方向について
ようやく本題に入れます。ここまで前段でした。私がこういうものを開発していておもしろいなーと思っていることは、モダンフロントエンドの技術をベースにしながら近年のフロントエンドのトレンドとは別の方向に向かっている感を抱くからです。どういうことかと言うと、一見するとフロントエンド・セントリックなアーキテクチャーという点からJAMstackと重なってくると思うのですが、その目的がJAMstackでは高速表示であることに対して、こちらはネットワーク上でのデスクトップアプリケーションの分散配布が主目的になっていると言えます。SSGは行われていません。サーバールーティングをせずにクライアントソフトとして配布しているからです。初回速度が出ないけど、繰り返し利用するならPWAでカバーされる形です。
近年のウェブはとにかくスピード第一にシフトしていると認識しています。Dyamic Import、SSR(Server Side Rendering & hydration)やISR(Incremental Static Regeneration)、性能診断ツールのブラウザ組み込み、CDNの普及、検索ランキングにおけるCore Web VitalsやMobile First Indexといった動きなど。去年電撃的な発表だったReact Server Componentも、その文脈でウェブアプリケーションの構造を変えようとしている野心的な試みだと認識しています。他の人の記事にコメントしたことを引用しますが、ここで書いていることが私個人の考えです。特に強調したいことは「ウェブとスマホアプリの棲み分け」が背景にあるという見方です。
何がそこまで性能にこだわらせるのかという点ですが、ユースケースがコンシューマー系のウェブにひたすらフォーカスしているからだと思っています。blogやcommerceのコンテンツ(それは検索結果やSNSからリクエストされる)をクライアントの端末でどれだけ瞬間的に表示できるかが、アジェンダです。
私の憶測ですが、これらをリードしている人たちの考えの背景として、ウェブとスマホアプリの棲み分けをそこに見出しているからではないかと考えています。未来を描く人は何人もいて、ウェブにネイティブアプリを移植する方向の人もいるし、スマホアプリとの棲み分けを考えている人もいるという状況認識です。
一方で、本記事で取り上げているものは、WebOS(ChromeOSやFirefoxOS)の概念が盛り上がっていた10年前ごろの「Web as Native」の文脈が近いと思います。「Web as Native」とは、今検索すると出てこなくて私の造語だったみたいなので補足すると、Web API → The Extensible Web → PWAと移り変わってきた「ネイティブアプリでできる低レベルAPIもウェブに実装していこう」という一連の動きを指しています。カメラやアドレス帳やGPSやジャイロといった各種センサーなどです。年月が経ち、実装されたものもあれば、萎んだものもあります。
本記事で取り上げた構成の動機は、アプリストアや特定ホスティングに依らずにサービスを自由に提供できるようにするためのプラットフォームです。その目的に適しているのでウェブが選択されて、近年のフロントエンドの技術を活用しつつ近年のフロントエンドの潮流とは別の方向に向かっています。ウェブに期待するものが変わるのは、ひとえにアプリケーションの用途が違うからだと思います。また、背景として、インターネットのセキュリティやプライバシーを巡る大きな地殻変動があると認識しています。これからどうなっていくかわかりませんが、本記事で取り上げたこの先にある未来は、ブラウザも必須でなくなったWebAssemblyによるユニバーサルなアプリケーション実行環境になっていくと個人的には思っています。(とはいえ来年は別の考えになっていそうなくらいの温度感です)
Discussion