段階的向上で堅牢なフロントエンドを構築する
(gov.uk)- GOV.UKのサービスは、ブラウザ・デバイス・接続状態が異なっても、ユーザーが中核となる作業を完了できるよう、HTML優先で動作すべきであり、すべての政府サービスに段階的向上が求められる
- HTMLには、未知のマークアップを無視して解析を続けるフォールトトレランスがあり、古いブラウザや一部にエラーのあるページでも、基本的なナビゲーションと機能を維持できる可能性が高い
- CSSとJavaScriptはより脆弱な層である。CSSでは未知のセレクタによりルールセット全体が無視されることがあり、JavaScriptでは未対応の構文やAPIエラーによって残りのコード実行が停止する可能性がある
- JavaScriptは中核機能を置き換えるのではなく、HTML・CSSを強化するために使うべきであり、オートコンプリートも
<select>のような基本要素の上に重ね、失敗してもユーザーが作業を続けられるようにすべきである - クライアントサイドJavaScriptフレームワークやSPAは、パフォーマンス・アクセシビリティ・保守の負担を生む可能性があり、複雑なUIではない GOV.UK Design System 中心のサービスには不要である
段階的向上の基本原則
- 品質の高いサービスは堅牢な方法で作られるべきであり、段階的向上はWebサイトやアプリケーションをHTMLから動作させるためのアプローチである
- まずHTMLで基本動作を作り、その後にCSSやJavaScriptのような層を追加する
- すべての政府サービスは段階的向上に従うべきであり、サービスの一部または上位サービスがJavaScriptを必要とする場合でも、この原則は維持される
- 段階的向上によって得られる効果は次のとおり
- サービスがより堅牢で高品質になる
- ブラウザやデバイスに関係なく動作する可能性が高くなる
- 最も基本的な機能が動作し、ユーザーの中核的な要求を満たせる
- セマンティックマークアップ のようなベストプラクティスを促進し、アクセシビリティを改善できる
- デバイスや接続に制約のあるユーザーでもサービスを利用しやすくなる
- COTSソリューションを使う場合や、外部ベンダーにサービスを委託する場合は、購買戦略 の要件に段階的向上を含めることを検討すべきである
HTMLから始める
- 政府サービスはHTMLだけでも機能すべきである
- HTMLだけで機能すべきサービスの例は次のとおり
- ユーザーが政府に情報を提供するフォームのようなトランザクションサービス
- smart answers 形式のサービス。たとえば Registering a birth abroad
- GOV.UKの foreign travel advice のようなコンテンツ中心のWebサイト
- HTML層には設計上のフォールトトレランスがある
- ブラウザは理解できないマークアップを無視し、可能な限り解析を続ける
- HTMLにバグがあったり、最新ブラウザにしかない機能を使っていたりしても、古いブラウザがサービスを読み込める可能性は高い
- ユーザーはHTMLだけでもサービスをナビゲートできるべきである
- 適切なセマンティックマークアップを使い、ソース順序と文書構造 を論理的に構成すべきである
CSSの使い方
- CSSは、サービスをGOV.UKのように見せるためのスタイリングに使える
- CSS層は比較的フォールトトレラントである
- ブラウザは理解できない個々の宣言を無視する
- 最新ブラウザにしかないプロパティを使った場合、その宣言だけが無視されることがある
- ただし、ブラウザが理解できないセレクタに出会うと、ルールセット全体が無視されることがある
- CSSはいくつもの理由で読み込まれない可能性がある
- JavaScriptが読み込まれなくてもサイトが正しく表示されるようにするには、CSS-in-JS のような手法は避けるべきである
JavaScriptの使い方
- JavaScriptは、サービスにインタラクティブ要素を追加するために使える
- JavaScript層にはフォールトトレランスがない
- ユーザーのブラウザがサポートしていない構文を使ったり、未対応のAPIを呼び出したりするとエラーが発生する
- エラーが発生すると、残りのJavaScriptは実行されない
- この可能性を考慮せずにサービスを設計すると、ユーザーがサービスを利用できなくなる可能性がある
- 複数のブラウザでJavaScriptが正しく動作する可能性を高める方法は次のとおり
- トランスパイルやポリフィルはJavaScriptのサイズを大きく増やす可能性がある
- 関連するトレードオフを考慮すべきである
- ブラウザ利用状況は変化するため、判断は定期的に見直す必要がある
- 可能であれば、JavaScriptは同じ中核機能を提供するHTMLとCSSを強化する形にすべきである
- オートコンプリートは
<select>要素や類似の基本要素を強化する形で実装できる - JavaScriptが失敗しても、ユーザーは必要な作業を続けられる
- オートコンプリートは
JavaScriptの代替手段と補完チャネル
- サービスがJavaScriptでしか作れないと判断した場合でも、まずHTMLとCSSで作るより単純な解決策でユーザーの要求を満たせるかを検討すべきである
- 対話型グラフをJavaScriptで提供したい場合は、次の代替案を検討できる
- データを表で表示する
- 別のアプリケーションで分析できるようにデータのエクスポートを許可する
- グラフを画像として事前レンダリングする
- サービスの中核機能をJavaScriptなしで提供できない場合は、ユーザーが別のチャネルでサービスを利用できる方法を用意しなければならない
- 電話
- 窓口訪問
クライアントサイドJavaScriptフレームワーク
- サービスの大半が GOV.UK Design System コンポーネントで構成され、複雑なUIがないのであれば、クライアントサイドJavaScriptフレームワークは不要である
- GOV.UK Design System コンポーネントには、フレームワークなしでサービスにJavaScriptを取り込む 方法 が含まれている
- クライアントサイドの JavaScriptフレームワーク は複雑なUIの構築に役立つことがある一方で、複数の問題を持ち込む可能性もある
- フレームワーク使用によって起こりうる問題は次のとおり
- コードベース全体のサイズを増やし、処理をクライアント側へ押し出すことで、低速なネットワークや低性能デバイスのユーザーにパフォーマンス上の問題を生じさせる可能性がある
- 開発者が制御できないサードパーティコードに依存することになり、フレームワークの変更に追従するためにサービスへ大きな変更が必要になる場合がある
- 時間の経過とともにフレームワークの人気が低下すると、保守に必要なスキルを持つ人材を見つけにくくなる可能性がある
- JavaScriptフレームワークを使うなら、次の条件を満たすべきである
- JavaScript利用がユーザーにどのような利益をもたらすのかを、根拠をもって正当化できること
- 負の影響を理解し、緩和できること
- 利点が潜在的な問題を上回るかを検討すること
- HTMLとCSSだけでは作れないUI部分にのみフレームワークを使うこと
- UIの各部分を独立したコンポーネントとして設計すること
- コンポーネントを分離すれば、JavaScriptの読み込みに失敗しても、その単一コンポーネントだけが失敗し、ページの残りは正常に読み込まれる
- JavaScriptはHTMLとCSSを強化する用途にのみ使うべきであり、失敗してもユーザーがサービスを利用できなければならない
CSSとJavaScriptが失敗する可能性がある理由
- CSSとJavaScriptは、さまざまな理由で読み込まれない、または実行されないことがある
- 一時的なネットワーク障害
- 広告ブロッカーのようなサードパーティのブラウザ拡張
- コンテンツ配信ネットワークを利用している場合のサードパーティベンダーのダウンタイム
- DNSルックアップの失敗
- ブラウザ更新によって発生したバグ
- 同じページ上で意図的に実行されるサードパーティJavaScriptのバグ
- 銀行や政府省庁のような大規模組織で使われる企業ファイアウォールがコンテンツをブロック・削除・変更する場合
- モバイルネットワーク事業者が読み込み時間や帯域幅使用量を減らすためにコンテンツを変更する場合
- 個人用ファイアウォールやアンチウイルスソフトがコンテンツを変更またはブロックする場合
- 安全でない接続においてインターネットプロバイダがページに独自コードを挿入し、そのコードがサービスコードと競合する場合
- 一部のユーザーはブラウザ機能を意図的に無効にしていることがある
- サービスはユーザーの選択を尊重し、そのようなユーザーでも継続して利用できるべきである
シングルページアプリケーション(SPA)を避けるべき理由
- サービスを**シングルページアプリケーション(SPA)**として作るべきではない
- SPAは、サービス内のページ読み込みをブラウザではなくJavaScriptが処理する方式である
- SPAは利点がほとんどなく、アクセシビリティを損なう可能性がある
- 支援技術の利用者が、新しいページへ移動した際に同じ文脈変化が起きたことを認識できない可能性がある
- ページ遷移時のフォーカスを適切に処理できない可能性がある
- ユーザーがブラウザの戻る・進むボタンで移動できなくなる可能性がある
- ネットワーク接続の中断のようなエラーからユーザーが回復できない可能性がある
テスト基準
- サービスの一部コンポーネントがJavaScriptまたはJavaScriptフレームワークに大きく依存している場合は、次の点を確認すべきである
- さまざまなブラウザとデバイスで動作すること
- 支援技術 と併用して動作すること
- 良好なパフォーマンスを保証するテスト を経ていること
- 可能であれば、そのコンポーネントがサービス内で適切に動作することを アクセシビリティテスト で確認すべきである
1件のコメント
Hacker Newsの意見
「JavaScriptフレームワークを使うなら、JavaScriptの利用がユーザーにどんな利益をもたらすのかを根拠をもって正当化できるべきだ」だなんて、みんな少し落ち着こう
良い基準は、アプリがデスクトップアプリのようにオフラインファーストで動作できるなら、シングルページアプリケーションとして作ってもよい、というもの
Photopea、Google Docs/Sheets、tldrawなどが例で、こういう場合は複数ページのブラウザーアプリよりも機敏で優れていることがある
こうすれば最大の欠点であるページ間移動とインターネット接続の必要性がなくなる
だがアプリにインターネット接続と複数ページが必要なら、ブラウザーに障害に強い方法でナビゲーションを処理させるほうがよい
オフラインや複数OSでデスクトップGUIのようなものが必要ならシングルページアプリケーションが有利で、単にWebサイトを作りたいだけならシングルページアプリケーションは最適ではないかもしれない
シングルページアプリケーションそのものと、それを作るための複雑さは別物だ
90年代に子どもの頃Webを始めた。CSSやJSが何なのかも知らず、JSは何かを点滅させる魔法のスクリプトをコピー&ペーストする程度のものだと思っていた
後には地元企業向けの動的サイトをPHPで作るようになり、その時にJSとCSSもある程度学んだ
その後、IE6のような最悪のブラウザーで動くようにするのに時間を使いすぎるのが嫌で、Web開発をやめた
ほぼ6年離れてから2015年頃に戻ってきたが、やっていた仕事にWebサーバーが有用だと気づいたからだ
ところが世の中がHTMLとCSSについて昔知っていた多くのことを忘れてしまっているのを見て衝撃を受けた
昔はサイトに複数のスタイルシートを用意し、まずJSなしで動くようにしてから、JSを追加の改善要素として足していたのに、そのやり方が忘れられていた
Web開発者がフォーム検証をすべてJSだけで行い、サーバー側では何もしないのも見たし、驚くことにこれは今でもよくある
サーバーが検証し、JSはその結果を表示するだけという一般的なパターンは、あまり知られていないようだ。みんな重複実装するか、サーバー検証をそもそもしないように見える
こういうものを見てからは、Webで人々がやっていることにもう感心しなくなった。自分の知っていたWebではなく、JSで作った「アプリケーション」にすぎず、Webファーストを主張するのは負け戦だった
子どもの頃にHTML 3.2/XHTMLとCSSから始め、数年後にDjango + jQueryの仕事をしてからインフラ側に惹かれた
1年ほど前にWeb開発チームと一緒に働き、彼らの仕事をのぞいてみたが、もはや何も理解できなかった
複雑さが圧倒的で、ほとんどの時間をビルド時間の短縮、依存関係の問題解決、奇妙なTypeScript問題への対応、複数コンポーネントのエラー処理といった複雑さの管理に費やしているように見えた
Django+jQueryの時代には、まだユーザーが見て使えるものに焦点があった
もちろんクライアントは絶対に信用できないので、後でサーバー側でも再度検証しなければならない
サーバー負荷を減らすのは有用だ
良い助言ではあるが、「支援技術のユーザーが新しいページへ移動したときに同じ文脈変化を知ることができない」「ページ移動時にフォーカスを処理できない」「ブラウザーの戻る/進むボタンで移動できない」「ネットワーク接続が切れるとエラーから回復できない」というのは、厳密には事実ではないのでは
多くの、あるいは大半のシングルページアプリケーションが気にしていないだけで、シングルページアプリケーションでもこうしたことは実装できる
シングルページアプリケーションの領域に入った瞬間、同等の水準に戻るために多くの車輪を再発明するか、ネイティブ機能をJSの代替物に置き換えることになる
複数ページのフォームを考えてみれば、どれほど多くのシングルページアプリケーションが全部をメモリに保存して、最後にリクエストを1つだけ送っているだろうか
JSがなければ、バックエンドは各段階の状態を保存し、後からフォームに戻ったり再読み込みしたりしても失われないようにしていただろう
基本的なHTML Webサイトがデフォルトだけでうまく動くのに、なぜそんなゴミを強要しなければならないのか
ユーザーがナビゲーション履歴を後からいじることを許可しないなら、残る選択肢は1つだけだ
履歴が使われる時点でブラウザー履歴を正しく作ることだ
インターネット全体がこの助言に従ってくれたらいいのに
古いものがまた新しくなる
今日流行しているものより、可能な限り単純な解決策を優先すべきではないか
業界の残りがJSに酔っていたからといって、全員がそうだったわけではない
なぜこのリストには Linux がないのか?
https://www.gov.uk/service-manual/technology/designing-for-d...
もう少し真面目で、かつ同じ文脈の答えとしては、ディストリビューションが何十もあり、その中に Mozilla 系のフォークまで含めるとブラウザも10個くらいあるから
公認のディストリビューション/ブラウザを1つ選ぶことはできるだろうが、そうして選んだ1つのユーザーベースは非常に小さくなる
Ubuntu でさえ、補助指標から算出できる数字ベースではデスクトップ OS のシェアが約1%程度に見える
真面目な質問だが、コメントを見るとこういうアプローチが好まれているように見える
だとすると、なぜ全体的な流れは React のようなフレームワークや JavaScript を、ときには不要に使う方向へ進むのだろうか
軽量で、レイアウトがすっきりしていて、アクセシビリティが高く、たいていは JavaScript を最小限に使うか、まったくなくても動く
一方で、ほとんどのシングルページアプリケーションは嫌いだ。期待されるブラウザ機能をたくさん壊し、JavaScript なしでは役に立たず、複数のサードパーティサイトからさまざまな重い依存関係を読み込むことが多い
しかし、ユーザーが好むものと、開発者が好み、素早く作れるものは、しばしば大きく異なる
あるものが業界標準として受け入れられると、その流れに従う判断は安全になる
そのうえ、HTML/CSS/素の JS のために開発者向け広報活動をする人は誰もいない
何かのやり方を検索すると、ほとんどすべてがフレームワーク関連の内容ばかり出てくる
自分のコンピューターで動くプログラムを作れば、そのコストを自分で払わなければならず、少なくともクラウド費用が5%増えた理由を財務チームに説明しなければならない
しかしフロントエンド開発者のように、他人のデバイス上でソフトウェアを動かすなら、コストはほとんどない
ネガティブなシグナルは、ユーザーからの報告、サポートチケット、あるいは Twitter の投稿のような経路を経て入ってくる必要があり、その過程には選択バイアスが多いため、全体像を見られない可能性が高い
結局、すべてはインセンティブの問題だ
Web は従来のリッチクライアントを置き換えつつあり、そうしたクライアントもかなり安定したネットワーク接続とプラットフォーム仕様を前提としていた
政府システムは、一般的ではないとしても最小公倍数で動作しなければならない
テック系スタートアップは、最初は顧客が1人だけでも存在でき、規模が大きくなれば自分たちの要件はおおむね一般的になると信じることができる
実際には、フロントエンド開発者だからこそこういうアプローチを嫌うのだと思う。そうでなければ開発するフロントエンドがほとんどなくなるから
私が従おうとしているやり方もこちらだ。サーバーで事前に取得したデータとともに HTML を提供し、クライアントでできることはクライアントで処理してサーバー往復を減らし、最小限の CSS でレスポンシブレイアウトを作り、素の JS を使う
必要なら別の Web ページに分ければよい
ところが、HTML、CSS、素の JS だけを使うという理由で、同僚たちには何か変で古臭く聞こえるようだ
特に不足しているものはない
記事でも、やみくもにサーバー側だけを使うのが良いソフトウェア工学ではないと言っている
「問題を引き起こす可能性がある」と言っているのであって、「問題を引き起こす」とは言っていない点に注目すべきだ
クライアント側 JavaScript フレームワークは、複雑なユーザーインターフェースを持つサービスを作るときに役立つことがあるが、コードベース全体のサイズを増やし、処理をクライアントに押し出すことで、遅いネットワークや低性能デバイスのユーザーにパフォーマンス問題を生む可能性がある
開発者が制御できないサードパーティコードに依存させ、フレームワークの変化に合わせるためにサービスに大きな変更が必要になることもある
フレームワークの人気が落ちれば、保守できる人を見つけるのが難しくなるかもしれない
JavaScript フレームワークを使うなら、ユーザーにどんな利益があるのかを根拠に基づいて正当化し、悪影響を理解して緩和し、その利益が潜在的な問題を上回るかを検討すべきだ
また、HTML と CSS だけでは作れないユーザーインターフェース部分にだけ使い、各部分を別個のコンポーネントとして設計する必要がある
コンポーネントを分離すれば、JavaScript の読み込みに失敗しても失敗するのはそのコンポーネント1つだけで、ページの残りは通常どおり読み込まれる