1S1A・1G1A・1P1A・UDAの違い|PWAの設計単位を整理
PWAを作ろうとすると、ManifestやService Worker、アイコン、start_urlなど、どうしても技術設定の話から入りがちです。
でも、その前にひとつ決めておいた方がいいことがあります。
そもそも、何を「1つのApp」として扱うのか。
サイト全体なのか。 特定の機能なのか。 1ページなのか。 それとも、同じページの中にある特定の状態なのか。
ここが曖昧なままManifestを書き始めると、あとからscopeやstart_urlで悩みやすくなります。
OJappでは、この違いを4つの設計単位として整理しています。
- 1S1A: Siteを1つのAppとして扱う
- 1G1A: Groupを1つのAppとして扱う
- 1P1A: Pageを1つのAppとして扱う
- UDA: Stateをユーザー自身がAppの入口として選ぶ
順番にすると、 Site → Group → Page → State です。
まず、この4つは「どれが一番いい」という話ではない
ここは最初にハッキリさせておきます。
1S1Aより1P1Aの方が新しいから優れている、とか、UDAが一番細かいから最強、という話ではありません。
違うのは、設計する単位です。
Amazonのような大きなサービスを全部ページ単位で別Appにしたら、それはそれで使いにくいです。
逆に、小さなタイマーツールがいくつもあるサイトを、全部ひとつの入口にまとめる必要もないかもしれません。
何をひとつの機能として見せたいのか。 ユーザーにどこから入ってほしいのか。
そこから決めるのが自然です。
1S1A|One Site. One App.
1S1Aは、 1つのWebサイト全体を、1つのAppとして扱う設計です。
一般的にイメージされるPWAは、この形に近いです。
たとえば、
- ニュースサイト
- ECサイト
- SNS
- 業務Webアプリ
のように、サイト全体がひとつのサービスとして成立している場合です。
ホーム画面にはそのサービスのアイコンがひとつ置かれます。
そこからサイト内のいろいろなページへ移動して使います。
1S1Aが分かりやすいケース
たとえば、ひとつのECサイトがあるとします。
商品ページ、カート、注文履歴、マイページなど、ページはいくつもあります。
でもユーザーから見れば、全部ひっくるめて「そのショップ」です。
この場合は、ショップ全体をひとつのAppとして扱う方が自然です。
ページごとに別アイコンを作る必要はありません。
1G1A|One Group. One App.
1G1Aは、 サイトの中にある特定のグループや機能単位を、1つのAppとして扱う設計です。
Site全体ではちょっと広すぎる。 でもPage単位では細かすぎる。
その中間です。
たとえば、ひとつのドメインの中に、
/shop//member//tools//timer/
のように、役割の違うディレクトリがあるとします。
その中のひとつを独立したAppとして扱うのが1G1Aです。
1G1Aは「サイト内アプリ」みたいな感覚
ひとつの会社サイトの中に、一般向けページと会員専用ツールがあるケースを考えると分かりやすいです。
会社サイト全体をAppにしたいわけではない。
でも会員ツールは、複数ページを行き来して使う。
この場合は、
/member/
以下をひとつのAppとして扱う設計がしっくりきます。
1P1A|One Page. One App.
1P1Aは、 1ページを1つのAppとして扱う設計です。
ここから、一般的な「サイト全体をひとつのAppにする」というPWAの感覚とは少し変わってきます。
たとえば、同じサイトの中に、
- 画像圧縮ツール
- タイマー
- QRコード生成
- 計算ツール
があるとします。
ユーザーからすると、これらは全部別の道具です。
サイトのトップページを開いて、そこから毎回タイマーを探すより、 タイマーそのものをホーム画面に置いた方が早い。
画像圧縮をよく使うなら、そのページだけ別のアイコンにしておけばいい。
これが1P1Aです。
ページごとに名前とアイコンを持たせる
1P1Aでは、ページごとに、
- 名前
- アイコン
- 起動するURL
を持たせます。
同じドメインにあるページでも、ホーム画面上では別々の入口として扱います。
OJapp FREEでは、この1P1Aを中心的な設計として使っています。
ページ単位の起動では、
start_url: "."
を使い、現在のページを基準に起動する構成を採用しています。
UDA|User Defined App.
UDAは少し考え方が違います。
開発者がAppの入口を全部決めるのではなく、ユーザー自身がURLを使って、自分用の入口を定義するという考え方です。
ここでAppの単位になるのは「ページ」ではなく、そのページが持っている状態です。
同じタイマーページでも、別のAppとして使える
たとえば、こんなURLがあったとします。
/timer?time=3&mode=down
これは3分のカウントダウンタイマーです。
一方、
/timer?time=20&mode=up
なら、同じタイマーページでも20分のカウントアップという別の状態になります。
ページ自体は同じです。
でもユーザーにとっては、
- 3分タイマー
- 20分タイマー
は別の道具です。
なら、その状態をそのままホーム画面に置いてしまえばいい。
これがUDAの考え方です。
Site → Group → Page → Stateで考えると分かりやすい
4つをまとめると、こうなります。
- Site: Webサイト全体
- Group: サイト内の機能やディレクトリ
- Page: ひとつのWebページ
- State: URLで表されたページ内の状態
つまり、
1S1A → 1G1A → 1P1A → UDA
と進むほど、Appとして扱う単位が細かくなっていきます。
ここまで細かくする必要があるかどうかは、サービスによります。
大事なのは、最初から「PWAは1サイト1アプリ」と決めつけないことです。
逆に、全部をページ単位にする必要もありません。
そのWebサービスで、ユーザーが何を「ひとつの道具」と感じるか。
そこから考えると、かなり整理しやすくなります。
たとえば、ひとつのサイトでも設計は混在できる
ここが少し面白いところです。
1S1Aを選んだから、サイト内全部を1S1Aに統一しないといけない、という話ではありません。
サイト全体には1S1Aの入口がある。
その中の便利なツールだけ1P1Aで独立して置く。
さらにタイマーだけは、ユーザーが時間を指定してUDAとして置く。
そんな構成も考えられます。
実際のWebサイトは、全部が同じ粒度で作られているわけではありません。
読み物もあれば、ツールもある。 ショップもあれば、会員ページもある。
だったらホーム画面の入口も、用途に合わせて分けていい。
OJappでは、そういう前提で設計単位を整理しています。
どの設計を選べばいい?
かなりざっくり決めるなら、こう考えると分かりやすいです。
- サイト全体がひとつのサービス: 1S1A
- サイト内に独立した大きな機能がある: 1G1A
- ページ自体がひとつの道具になっている: 1P1A
- ユーザーごとにページの状態を変えて置きたい: UDA
これだけ覚えておけば、かなり整理できます。
あとは実際のサービス構造を見ながら決めれば大丈夫です。
ホーム画面の入口から逆算する
個人的には、Manifestの設定から考えるより、 ホーム画面に何のアイコンを置きたいか から考える方が分かりやすいと思っています。
ホーム画面に「サイト名」のアイコンをひとつ置きたいなら1S1A。
「ショップ」「会員ページ」と分けたいなら1G1A。
「タイマー」「画像ツール」とページ単位で置きたいなら1P1A。
「3分タイマー」「5分タイマー」まで分けたいならUDA。
この順番で考えると、start_urlやscopeを決める理由も見えやすくなります。
技術設定は、その入口を実現するための手段です。
OJappでは、この4つを用途に応じて使い分ける
OJappは「URLをホーム画面の入口にする」という考え方を中心にしています。
そのため、必ず1S1Aにする、必ず1P1Aにする、という決まりはありません。
何を入口にしたいかによって、設計単位を変えます。
サイトでもいい。 グループでもいい。 ページでもいい。 状態でもいい。
URLが表しているものを、ユーザーにとって使いやすい形でホーム画面へ持ってくる。
その考え方を整理したものが、1S1A・1G1A・1P1A・UDAです。
OJapp全体の考え方については、 OJapp でも確認できます。
まとめ
PWAを設計するとき、最初に考えたいのは「何を1つのAppとして扱うか」です。
OJappでは、その単位を次の4つに整理しています。
- 1S1A: Site
- 1G1A: Group
- 1P1A: Page
- UDA: State
どれが優れているという話ではありません。
サイト全体をひとつのAppにした方が自然なサービスもあれば、ページごとに分けた方が使いやすいサービスもあります。
さらに、同じページでもユーザーが選んだ状態をそのまま入口にした方が便利なケースもあります。
Site → Group → Page → State。
PWAの設定に入る前に、この単位を一度考えておく。
それだけでも、Manifestやstart_url、scopeを「なんとなく設定する」状態からかなり抜けやすくなります。