ジュニアからミドルクラスにレベルアップする為に必要なスキル【フロントエンド向け】

# この記事の前提

まず初めにこの記事は
 **「Webエンジニアとしてのキャリアが1年前後の、まだ設計やチームリーダーを任されたことが無い」**
 層を対象として想定しています。

フロントエンドのこの技術を知るべき、のようなハードスキルではなく、**網羅性を持った思考**というソフトスキルについて話すので比較的汎用性のある内容になっていると思います。

私自身はWebデザイナーからスライドしてフロントエンドエンジニアに転向したので、現在エンジニアとしての経験は浅いもののジュニアのボトムではないという自己認識です。
そして職場ではWeb業界そのものに未経験で入って一年未満の人たちと働いており、数人のチームのリーダーを務めています。

そのメンバーの成長について考えていく中で調べたこと等を、部内の勉強会用のスライドにまとめ、さらに加筆したものがこの記事になります。

**【発表のスライドはこちら】**

https://docs.google.com/presentation/d/1VqWKmGpiUZV09ce7WHVuzaNLE6xr7czzsFLdkcCc6LQ/edit#slide=id.p


また最初におことわりなのですが、会社によってレベル階層（ジュニア・ミドル・シニア）の定義は大きく異なると思われます。
（実際、参考にした[この記事](https://artelogic.net/blog/what-is-the-difference-between-junior-middle-and-senior-developers-software-engineers) では、シニアはCSの学位を持っているのが当然のような雰囲気がありますが、日本の企業でそれが当たり前とは思えません。）
また弊社は受託開発会社で、現状フロント・デザイン・サーバーは別部門として存在しているというのも内容の前提としてあります。
よってこの記事において、**ジュニア・ミドル・シニアの厳密な定義についての議論はご容赦いただければと思います。**

# 前提1：フロントエンドのお仕事って？

### ＝UIに関わる要件に責任を持つこと

上流工程・サーバー側・デザイン側から既に決定した仕様を元に仕事をする部分が多いフロントエンドではあるが、
他の部門が想定できない **「フロントエンドならでは」** の関心事に責任を持つことがその職務であると考える。

そのフロントエンドならではの関心事については詳細を後述します。

# 前提2：クラス別の責務

一般的なクラスごとの責務はこの記事を参考にしています。

https://artelogic.net/blog/what-is-the-difference-between-junior-middle-and-senior-developers-software-engineers

※それぞれおおよそジュニアが1年目、ミドルが2年から4年目、シニアが5年から8年目と記事にはありますが、実際には経験年数に伴って成長する類の分類ではなく、その人が出来る事によってレベルアップするものだと思います。

## ザックリ定義

#### ジュニアクラス：指示された要件を満たす実装が出来る

「要件を満たす」とは、担当する画面をデザイン通りに作ること、あるいは仕様の挙動をバグなく実装することを指すものとする

#### ミドルクラス：他部門やPMと協働して仕様の策定が出来る

仕様の策定は技術選定や環境構築を含む
なおかつ、例えば映像配信などにおいて高品質とパフォーマンスを両立した実装が出来る、グラフィック領域に長けている、UXを考慮したプロダクト設計を提案できるなどの特化分野を持つ。

#### シニアクラス：経験豊富で、より大きなプロジェクトを牽引出来る

ミドルクラスの条件に加え、経験に基づく深い洞察力でより複雑で重大な問題を解決することが出来る。

## 参考記事内のミドルクラスの条件詳細

- 他メンバーの可読性・拡張性を考慮したコードが書ける
- 効果的なリファクタリングを行うことができる
- 大きいタスクを分割してジュニアに指示を出すことができる
- ジュニアの質問に的確に答えることができる
- 環境構築や技術選定が行える
- バグの発見や、詳細なレビューが出来る
- テストの策定やスケジューリングが出来る
- [システム開発ライフサイクル](https://breezegroup.co.jp/202106/systemdevelopment-lifecycle/)の中の2つ以上に秀でたスキルがある

## 「フロントの」ミドルクラスの必要条件

一言で言うと…

**中型までのプロジェクトにおいて、要件を正確に理解し、詳細なフロント側の仕様を決めて、最終的に漏れなく実装されていることに責任を持てる人**

…だと思います


# フロントの関心事とは？

まだまだ他にもあると思いますが、この辺が挙げられますよね。

- 速度パフォーマンス
- グラフィックス・アニメーション
- マルチデバイス対応
- ユーザビリティ・アクセシビリティ
- **通常状態以外の表示のハンドリング**

上記の中でWebアプリを作るフロントエンドエンジニアに特に**必須**であるものの、適切に考慮出来ていないジュニア層が多いと感じるのが最後の項目です。

# 通常状態以外の表示のハンドリングとは

UI/UXに知見のあるデザイナーやバックエンドエンジニアでないと想定しにくい状態、例えば

- サーバーから空の値が返ってきた場合の表示（EMPTY）
- 大量のレスポンスが返ってきた場合の表示形式
- リクエストが失敗した時の表示（エラーハンドリング）
- フォームバリデーションエラーのデザイン・文言・表示方法
- ローディング中の表示

等を**網羅的に想定してどう扱うか提案・実装すること**、とする。

これが出来ない状態で仕様策定や、メンバーのタスクも管理するチームリーダーを任せてもらうことは難しいでしょう。
そういったソフトスキルは実際のところ「フロントエンドに求められる基礎の基礎」だと思いますが、1年目でやっと実装作業に慣れてきたレベルであれば次のステップとして適当かと思います。

この発表をした後に教えて貰ったのですが、この「通常状態以外の表示」はUIデザイン領域では**UI Stack**という概念で知られているようです。

https://digitalidentity.co.jp/blog/creative/ui-stack.html

# 事例で分かるUI Stack：アルサーガ図書館

ここからは、上で挙げた「通常状態以外の表示」をどうハンドリングするか、最近個人開発した社内向け蔵書検索アプリを事例にとって具体的に説明していきます。

### 「アルサーガ図書館」とは？

![スクリーンショット 2022-01-16 211828.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/fc28f628-83b4-e678-5bb8-082337a7703f.png)

Slack botとGASを使って作成した社内蔵書の検索アプリです。

検索機能側仕様は、

**SlackでBotアプリにメンションをされた単語で事前に収集した書籍DB（スプレッドシート）を検索して、その検索結果をSlack投稿用に整形してSlack APIに返す。**

それだけ！

ではこのごく単純な検索機能に対して、上で述べたような観点をどう反映しているかを挙げていきます。

## CASE1: 表示内容が無かった時

### 該当する書籍が見つからなかった場合それを通知するとともに新規登録を提案する💡

【実際のアプリ画面】
![スクリーンショット 2022-01-16 212208.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/79c4b525-93dd-a449-0bd5-04f1edbb74ef.png)

これはオンボーディング（初回登録時）におけるＵＸ用語で **「エンプティステート型」** と呼ばれる、ユーザーがまだ何も登録していない時に登録を促す説明文を表示して離脱を防ぐ手法を使用しています。

【Netflixアプリ】

![a235c7a591dcb4cb984e927a3edef6a2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/3a9469f1-d5a1-01b8-95cc-dfecf2ee35a5.png)

管理側からの登録内容であったり、ユーザーが干渉できないタイプのエンプティの場合も、少なくとも「コンテンツが存在しない」というメッセージを表示したいですね

【Zaim（iOS）】

<img width="300" alt="id796_02.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/5a5cdd14-3e3d-21fa-b035-ae9c6f7cfc91.jpeg">


参考記事：

https://hikarina.co.jp/blog/emptystate_mokuteki/

## CASE2:表示内容が多すぎた時

### 一覧性の保てる個数で切って、続きの表示には別のアクションを用意する

現状、大量に並ぶとスレッドを圧迫するため10件で切ってますが、今後の改良で、10件以降はスレッドに繋げて投げる方法を検討中です

【実際のアプリ画面】

![スクリーンショット 2022-05-23 20.17.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/8ee746f6-b65f-2e35-790d-5ac2e9b27a62.png)



### 通常のアプリであれば、ページネーションかインフィニットスクロールの二択が考えられる

![ZAPBLOG.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/8ab581ce-97f8-d2a3-da81-82219f0c6ac4.jpeg)

画像引用：　https://www.zapbuild.com/bitsntricks/redefining-user-experience-infinite-scrolling-vs-pagination/

## CASE3: 不正なワードが入力された時

ひらがな一文字などで検索されると大量に引っかかり、尚且つ有益な検索結果にならないと考え2文字以上というバリデーションを付けています。（Cとかで検索してもC言語以外の単語も出てきちゃうし…）

【実際のアプリ画面】
![スクリーンショット 2022-03-13 222937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/c675f9cf-8998-1889-da57-4163498be766.png)

### 通常のアプリであれば入力内容のバリデーション表示が必要

![zzzzzz.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/7a4e024d-5737-362d-08db-7e4ba22a722e.jpeg)

### バリデーション検討事項

- フォーム上部にまとめて出すか
- 各フィールドに出すか
- 入力中に出すか、フォーカスが外れた時に出すか
- そのバリデーションはUXを損なわないか（過度に短い文字数制限がないかなど）

### セキュリティ検討事項

- [XSS対策](https://www.amiya.co.jp/column/cross_site_scripting_20210118.html)としてサニタイズ処理が必要か
- 不必要に自由なバリデーションになっていないか

## CASE4: アプリ内部でエラーが発生した時

このアプリは、社内のスペースを使っており、私にエラーログを出すGCPへのアクセス権限がないため、エラーメッセージを管理者にメンションを付けてslackに投稿することでエラーログ兼ユーザへのお知らせとしています。

![スクリーンショット 2022-01-16 220930.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/9bf01cbc-615d-d350-c965-fad958251c71.png)

### 通常のアプリであればエラーページを表示する

- **404（ページが存在しない）**
- **500（サーバー側の不具合）**

の2種類は最低限用意して、ユーザーに適切な対応を促しましょう。

適切な対応とは、例えば以下のようなものです。

404の場合：ホームや必要なページへの誘導
500の場合：時間を空けてアクセスしてもらう、など

【お馴染みGithubのやつ】

![56276896-af93b580-6103-11e9-9885-74981a49a5ae.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/669a6f0e-a9cf-b966-0853-f8dd1a044f6e.png)

![CfRG2NWVIAABdLN.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304716/90633ce1-ea97-4567-b300-5d17e9a282db.jpeg)

# 終わりに

この記事でまとめたことは私としてもミドルクラスの最低条件であり、人によってはそれ未満と感じられるかもしれません。
ですが、現実にこういったことをエンジニアを初めたばかりで最初から考えられる人は少ないように思われます。

個人的には、こういった仕様を考慮できる人に共通しているのは **「アプリはユーザーに使ってもらうためにある」** という価値観を自分の中に持っていることではないかと感じます。

実際アプリを使っていて、エラーのフィードバックやローディング状態などが適切に実装されていると使用中のストレスが大分違いますよね。
（まぁ商業アプリで上記の状態が考慮されていないものは滅多にないですが、個人開発だと割にありがち）
だから例えこの記事の内容を全く覚えていなくても、プロダクトに対してユーザーの視点を持っていれば、この記事で挙げたような仕様は自然と考慮されるはずです。

よって「この要件に必要な機能を作る」ではなく、「ユーザーに価値を提供できるアプリに必要な機能を作る」と考えられるようになれば完全なジュニアから一歩脱出！という感じがしています。

つまるところ、イケてる技術にキャッチアップすることも、難しい技術に挑戦することもエンジニアとして素晴らしい姿勢ですが、こういったアプリケーション全体のクオリティへの貢献が出来るエンジニアになることも同じくらい大切だと思うよー、というのがこの記事で私が話したかったことでした。

ここまでお読みいただきありがとうございました😊