丁寧に学ぶフロントエンドアーキテクチャ：第1章「フロントエンドの基礎」

# 目次
この記事は、丁寧に学ぶフロントエンドアーキテクチャの第1章です。
**いいね・ストックをよろしくお願いします！**

https://qiita.com/wolfmagnate/items/f2044201266e48cdd299

# はじめに
初回は、フロントエンドアーキテクチャの基礎を学びます。
そもそもフロントエンド設計が必要なのかという根本的なところから、フロントエンド設計で重視するべき内容、そもそもフロントエンドとはどこまでを指すのかというところまで、網羅的に解説していきます。


# 丁寧なフロントエンド設計をしよう
フロントエンドでは様々な開発環境、フレームワーク、バンドラ、ビルドツールが乱立しており、様々な表現方法、記述方法、開発方法が模索されています。
それに対して、ソフトウェア設計の文脈では、フロントエンドは**雑に**扱われていると感じています。

ソフトウェアが対象としている主たる処理はバックエンドで行われており、フロントエンドはただ表示するだけなので、**特に設計の対象とするべき内容は存在しない**といった考え方です。

@Philomagi さんの「WEBフロントエンドにおけるソフトウェア設計の考察」でも、フロントエンドに「ドメイン」は存在しないという言説について触れられています。

https://speakerdeck.com/tooppoo/consideration-of-software-design-in-web-front-end?slide=23

ソフトウェア設計についての書籍でも、ビジネスロジックとDB操作の記述を中心とした設計技法ばかり重視されています。
画面がかかわるような部分は、UIレイヤー、Viewレイヤーのように単一のレイヤーで扱われ、あたかも「ここまでいけばほぼ終わり！」と言いたいかのような書き方をされがちです。

:::note info
**フロントエンドにはフロントエンド固有の複雑性があり、丁寧に設計する価値がある**
:::

個別のツールの使い方ばかりを追い求めて、背後にある設計原則について学ばなければ、いつまでたっても正しい設計ができるようになりません。
例えば、新しいCSSプロパティの効果、CSSプリプロセッサの機能を追いかけるだけでは、CSS設計のスキルは改善しません。

:::note warn
**「こう書けばこうなる」を超えた視点を持たないと、設計力は成長しない**
:::

# フロントエンド設計の目標
まずは、ソフトウェア設計の目的をおさらいしておきましょう。ソフトウェア設計とは、ソフトウェアの各種品質特性を高く保つために、ソフトウェアの仕組みを決定することです。
フロントエンド設計を行う上では、どのような品質特性を高める設計が正しい設計であるかを理解しておく必要があります。

## 保守性
ソフトウェア設計において最も重要な品質特性が保守性です。

:::note info
**保守性**
システムが、以下の要素を備えているか
- 理解しやすい（読みやすい）
- 正しく変更しやすい（書きやすい）
- 再利用性が高い
- テストが容易である
:::

フロントエンド設計に限らず、ソフトウェアを設計する際は保守性を優先する必要があります。
その他の品質特性をどの程度重視するかは、ソフトウェアの対象領域によって異なります。フロントエンドでは、次のような品質特性が特に重要視されます。

## パフォーマンス
:::note info
**パフォーマンス**
システムがマシンのリソースを効率よく利用して、素早くユーザーに価値を提供できるか
:::
フロントエンドは個々のユーザーの端末で1回ずつ実行されるため、パフォーマンスの中でも重要なのは**必要な処理を減らす**ことと、**何らかの反応を返すまでのレイテンシの削減**です。対照的に、**ユーザー端末のスループット**は制御できないため、重要ではありません。

### 必要な処理を減らす
- ネットワーク最適化
    - リクエスト数を減らす
    - キャッシュを行う
- リソース最適化
    - 画像最適化
    - アセットのminify
- 静的生成
### レイテンシの削減
- ページ読み込みのレイテンシ
    - 最初のコンテンツフルペイント（FCP）
    - 最大コンテンツフルペイント（LCP）
    - インタラクティブになるまでの時間（TTI）
- ユーザインタラクションのレイテンシ
    - 入力遅延
    - スクロールやアニメーションの遅延
    - 操作への即時応答

## ユーザビリティ
:::note info
**ユーザビリティ**
すべてのユーザーがシステムを正しく、効率よく、安全に利用できるか
:::
ユーザビリティは、フロントエンドエンジニアだけで達成できる品質特性ではありません。デザイナーと協力することで達成する必要があります。例えば、どのタイミングでバリデーションを実行するかはUXデザインですが、バリデーションのロジックはエンジニアリングに属します。したがって、

- システム自体のユーザビリティ

に加えて、

- デザイナーとフロントエンドエンジニアのコミュニケーションの容易さ

が高くなるような設計を行う必要があります。

## 重視されない品質特性

バックエンドでは重要でも、フロントエンドでは重要ではない品質特性が存在します。

:::note warn
**フロントエンド設計で重視されない品質特性**
- 信頼性
    - 可用性
    - クラッシュからの復旧
    - リカバリの簡単さ
- スケーラビリティ
- データ整合性
- セキュリティ（ただし、ブラウザ上の処理に限る）
:::

# フロントエンドの定義
## Webシステムの自然なアーキテクチャ
保守性の基本として、**汎用性が高い部分を抽出して、再利用性を高める**というものがあります。
Webシステムは、ブラウザがバックエンドを操作して機能を実現します。バックエンドに近いほど、フロントエンドや特定のアプリケーション、特定の機能や操作方法から離れたレイヤーになり、かつ整合性を持ったデータがDBに保存されているため、汎用性が高い処理を実装しやすくなります。
逆に、フロントエンド側はユーザーに近いため、最終的に完成するアプリケーション、つまり、再利用を行った結果完成した「作りたいもの」に近くなります。

:::note
**再利用性を高めるアーキテクチャの構造**
1. 画面を意識しない汎用的な「システムの機能」を提供するレイヤー
1. 画面を意識して、「画面構造、画面の操作の実現」を提供するレイヤー
1. Webフロントエンドを意識して、「画面の構造に対応するHTML・CSS」を生成するレイヤー
:::

フロントエンドに近いほど、作りたいものである「Webシステムを利用したあるアプリケーションのある画面」に近づいていることが分かります。

バックエンドに近いほど再利用性が高いため、利用の関係は次のようになります。

![1-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412657/7eeabbd6-09c4-4dfe-8f34-6b8f9cf175b5.jpeg)

## フロントエンドの定義
それでは、このようなレイヤー構造のうち、フロントエンドはどこまででしょうか。
答えは次のようになります。

:::note
**フロントエンドとは、画面を意識している範囲である**
:::

HTMLなどが全く関係しない部分でも、**画面構造を意識していれば、その時点でフロントエンド**だと言えます。

## クライアントサイドの定義
次に、類義語であるクライアントサイドという言葉についても明確化しておきます。

:::note
**クライアントサイドとは、ブラウザで実行される範囲である**
:::

例えば、HTMLをサーバーで生成するSSR(Server Side Rendering)では、クライアントサイドで動作する処理は存在しません。ブラウザが全自動で描画を行うからです。対して、Reactなどを使ってブラウザ上で動的にDOMを更新するならば、それはクライアントサイドの処理です。
ここで、フロントエンドにまつわる大きな誤解を説明します。

:::note warn
**フロントエンドの誤解**
フロントエンド＝ブラウザ、と考えると、モダンなフロントエンドアーキテクチャを理解することはできない。現代のフロントエンドはブラウザを意識したHTML生成でさえサーバーで実行される可能性がある。
:::

## フロントエンドレイヤー
ここまでで説明したように、実はフロントエンドはブラウザを意識する部分としない部分に大別できます。アーキテクチャ上の重要なレイヤーであるため、命名しましょう。

:::note
**Viewレイヤー**
フロントエンドのうち、ブラウザを意識した処理
:::

例えば、UIのアニメーションのスクリプト、HTML構造設計、CSS設計、これらはすべてViewレイヤーの関心事です。

:::note
**BFFレイヤー**
フロントエンドのうち、ブラウザを意識していないもの
BFFのほうがViewよりも汎用性が高い
:::

例えば、バックエンドから得られた詳細なデータ構造から、UIに必要な部分だけを抽出する処理はBFFレイヤーです。**画面の論理的な構造のみを意識**しているため、ブラウザ関連の内容を一切無視することができるのです。

BFFレイヤーは基本的にブラウザ上では実行されません。わざわざブラウザを意識しないで実行できるレイヤーを分割したのにブラウザに依存させるのは意味がないからです。そのため、サーバー上で実行されます。BFFがBackend For Frontendという名称なのはこれが理由です。（これが有名な名称になってしまっているので慣例に倣って命名しましたが、本質的にはFrontend in Backendとするのが正確だと思います）

# おわりに
今回は、フロントエンド設計の基礎を学びました。
具体的な設計手法については次回以降説明していきますが、この章で説明する内容は、全ての基礎であり、必須の心構えになっています。

https://qiita.com/wolfmagnate/items/dc4184b97bf13b9f9e5e