自己紹介
初めまして!現在音楽講師をしてと申します。未経験からエンジニアへの転職を目指し日々学習をしております。
楽器歴はもう17年と日々演奏技術を磨きながら最新の音楽情報をキャッチアップしております。
そんな私がプログラミングを始めたのは、別のミュージシャンの方が自分のホームページを持っていたので「僕も作ってみたいな」という気持ちからでした。
そこからプログラミングについて調べみるとそのページにはログイン機能などがあり、これはなんだと?と思い調べてみました。
調べていくと、Webアプリケーションが作れ、雛形が揃っていて尚且つ学びやすいというフレームワークがあるという記事を見つけました。そこで出会ったのがRuby on Railsでした。まずは始めないと正解・不正解も分からないので、何事も触れてみようと思い学習をスタートしました。
独学で勉強し少しずつ理解が深まるごとにどんどんプログラミングにハマっていきました。
▼なぜエンジニアになりたいか?
IT技術を用いて困っている人の役に立ち、さらに自らが開発に携わったサービスで多くの人を喜ばせたいからです。
そう思う理由は2つあり、一つはプログラミングは音楽と似ていて面白いから、もう一つは自分の経験や技術をもとにした考えによって結果が出ることにやりがいを感じるからです。
プログラミングと音楽は、学べば学ぶほどできることが増える部分や、難易度の高い内容に挑戦したいと思わせることも似ていますが、それ以上に、磨き上げた技術力を用いることで多くの人を喜ばせられる部分が最も似ていると思いますし、魅力を感じています。音楽はその魅力があったので10年以上も続けてこられました。
そんな中、コロナ禍の影響で人伝いでのバンドメンバー探しが難航した際に、バンド募集サイトを利用しましたが、「便利」と思う反面「もっとこうしたい」と思う箇所もありました。それをきっかけにプログラミングの学習を本格的に始め、技術を学ぶほどできることが増えて可能性が広がる感覚にハマっていきました。
一方で、現職の音楽講師で最もやりがいを感じるのは、「生徒の課題に対して、自らの経験や技術力を生かして考えた提案を行い、それによって成果が上がること」です。
それと同様の体験として、縁あって開発の実務案件に参画したのですが、顧客の課題に対して苦戦しながら改善策を考え抜き、仕様決めから設計・実装まで一通り行いました。自分の考えたコードがリリースされ、課題の解決に繋がり、感謝の言葉を頂いた時はこの上ないやりがいを感じました。
音楽と同様に好きな技術を磨きながら、それを用いることで人の役に立ち、今度はプログラミングの世界でより多くの人を喜ばせる働き方がしたいと思い、エンジニアを目指しています。
案件の概要
実務案件を頂けたのですが、今回クライアントから依頼があった内容は、医院紹介サイト(Rails)のSEOの改善とCore Web Vitalsの改善をしてほしいという案件内容でした。
チームメンバーでタスクを分けしたのですが、私が担当させて頂いたのはCore Web Vitalsの改善でした。(Core Web Vitalsの詳しい内容は後述)
メンバー構成と実務期間は、リーダーであるY氏と、私含め3名の未経験者が2ヶ月間実務に取り組みました。
実務案件を申し込んだ理由と経緯
応募したきっかけは、入社前後のギャップを埋めたいと思い応募しました。実務を体験をすることによって独学でプログラミングに触れている時と実務とのギャップを少しでも埋めることができ、入社後の成長、心構えを知る事が出来るのではないかと考えたからです。
もう一つは書いてあることしかできない(言われたことしかできない)人間ではなく、自走して課題を解決できる人間であることを少しでも証明したいと思ったため、今回の実務案件に挑戦させていただきました。
実務経験を積みたいと思い検索する中で、実務の募集を見つけました。どうしても実務経験を積みたいと思い2度も応募フォームを送信し気持ちが届いたのか実務案件に参画させて頂くことになりました。
1. 実装準備
実装を始める前に、初めて聞く用語の理解や、計測ツールを使っての問題の洗い出し方法を理解してから着手しました。まずは実装準備をどの様にしてきたのかを説明していきたいと思います。
Core Web Vitalsとは?
Core Web Vitalsの知識が無いと何も始まりませんので実務ではしっかり用語の意味を理解してから着手しました。
ここでは閲覧して頂いている皆様に簡潔にお伝えさせて頂きますm(_ _)m
-
Core Web Vitalsとは
-
ユーザー体験を向上させるためのGoogleが定めたガイダンス
-
一言で表すとユーザーが感じる使い勝手を評価する指標
Core Web Vitals参考URL
https://webtan.impress.co.jp/e/2020/06/05/36210
内容を深ぼると指針が分かりやすく定められていました。
Core Web Vitalsの指針
####LCP(Largest Contentful Paint)
読み込みパフォーマンスを測定して数値化したもの。ユーザーがそのWebページのなかで最も有意義なコンテンツをどれだけ早く見ることができるかを表す指標。一言で言うと読み込み時間の事。ページの読み込み開始から2.5秒以内にそのページが描画されることが望ましいとされる。
####FID(First Input Delay)
ユーザーがWebページを閲覧する際に ページのレスポンスが良いかどうかを測定した数値。
ユーザー体験(UX)の最適化にはこのFIDの数値が 100ミリ/秒未満であることが望ましいとされる。
####CLS(Cumulative Layout Shift)
ユーザーがページを閲覧する際、 テキストや画像などのコンテンツが快適に表示されているか否かを示す指標。
ユーザー体験(UX)の最適化には、このCLSの値を 0.1未満に維持しなければならない。
参考URL
https://mtame.jp/seo/corewebvitals/
何を改善するのか?
Core Web Vitalsの3つの指針を理解したのですが、今回どこの指針の部分を改善するのかを決めないといけません。
Core Web Vitalsの改善方法を調べていくと、ウェブページの読み込み速度をスコア測定してくれるツールである**『PageSpeed Insights』**というツールをがある事を知りました。ツール内で今回依頼を頂いたサイトURLを入力すると計測してくれます。計測結果で表示された内容で、適切な画像サイズの画像、使用していないJavaScriptの削減、使用していないCSSの削減の3項目が改善の余地があると指摘を受けました。
今回私が施策提案させて頂いたのは、使用していないCSSの削減と、適切な画像サイズの変更の2項目です。
前もって説明させて頂きますが、適切な画像サイズの画像の施策については、実装する事が出来ませんでした、、、
理由は、
- 指摘のあった画像部分だけを圧縮すればいいのだと施策を勘違いしてしまったこと
- 使用していないCSSの削減*の施策に時間が掛かってしまったこと
の2点です。
こちらに関しては力不足を痛感しました。とても悔しい気持ちでした、、、
しかしこの悔しい気持ちをバネに今後エンジニアとして更に**『成長していきたい』**と気持ちが強くなりました!!
PageSpeed Insights URL
https://pagespeed.web.dev/?utm_source=psi&utm_medium=redirect&hl=ja
指摘を受けた内容
原因特定
CSS削減の余地があると指摘を受けたのですが、まずは現状どのようにCSSが読み込まれている状況なのか確認しました。すると、assets/stylesheet/apllication.css
に全ファイル読み込まれている記述がありました。
@import 'bases/_variable';
@import 'bulma/bulma';
@import 'bases/_base';
@import 'partials/*';
@import 'pages/*';
更に全ページの共通のレイアウトファイルであるviews/layout/application.html.slim
にstylesheet_link_tag 'application'、 media: 'all'
で全てのCSSファイルが読み込まれている現状でした。
= stylesheet_link_tag 'application' media: 'all'
このコードを見てわかったことは、全ページで共通のCSSを読み込んでしまっている事が原因で、ページ表示速度が遅くなっている、ということです。
原因を解決する為の学習
全ページで共通のCSSを読み込んでしまっている事が原因だったのですが、CSS設計の基礎を知らないと解決策の模索が出来ないなと思いました。そこでCSSの事をもっと詳しくなりたいと思い書籍を購入しました。
書籍を読んだ内容を元に今回のCSS設計時に重要となる観点をまとめ、その観点に基づいて最適な設計案を作成しました。目を通して特に重要であると思われる内容を絞り出しました。
参考書籍URL
https://www.amazon.co.jp/dp/B0856YMH7L
CSSの問題点と原因
CSSの問題点は、ページ数が増えるとCSSもどんどん複雑になり、管理しきれなくなってくる事です。数ページだけのシンプルなサイトであれば大した問題ではありませんが、世の中で使われているWebサイトは、決して小規模なものだけではありません。1ページのみでもWebサイトと呼べますが、上限は限りなく、100ページ、1,000ページ、10,000ページ超のWebサイトも珍しくありません。
そんな状況で何も考えずトップページではp要素を「大きくしたいから、fontsizeを18pxから20pxに変更しよう」とするとどうなるかというと、もちろんトップページだけ見れば意図した通りにp要素は20pxになります。しかしCSSの「スタイリングの内容がCSSファイルを読み込んでいるすべてのページに反映される」という仕様上、他のページのすべてのp要素も20pxになってしまいます。きちんとスタイリングの規則を決めた上でCSSが作成されているのであれば、まだよいですが、規則をきちんと決めていないと、「ページ数が増えると、CSSもどんどん複雑になり、管理しきれなくなってくる」という問題が発生し始めます。
規則のないCSSは、ページ数が10ページを超えただけでもすべてを把握するのは難しいです。そしてWebサイトは、制作して、公開し、終わり、ではありません。その次には情報を更新したり、新たなページを作成したり運用し続けていかないといけません。数ヶ月後の自分が、あるいは他の人が読み解いて、想定外の影響がないように運用していくのは、とても骨が折れる作業です。そしてそんな状態を避けようと規則を定めたとしても、すぐに破綻することがほとんどです。なぜこのようなことが起こってしまうのでしょうか?
- その原因は「CSSはすべてがグローバルスコープ」です。グローバルスコープとは読み込んだCSSファイル全てが同じスコープで管理されてしまう事。
原因を回避する為のCSS設計とは
ではどの様な設計によってCSSを管理し壊れにくくすることができるのかと言うと、具体的には、「予測できる」、「再利用できる」、「保守できる」、「拡張できる」の4つ設計指針がある様です。これはGoogleのエンジニアであるPhilip Walton氏が「CSS Architecture」という記事で提唱した考え方です。
###4つのCSS設計指針とは
-
予測できる
-
スタイリングが期待通りに振る舞うかどうか
-
スタイリングの影響範囲が予測できるか
-
再利用できる
-
既存のパーツを別の箇所でも使用したいとき、コードをいちいち書き直したり上書きする手間がない状態
-
保守できる
-
新しいモジュールや機能を追加・更新、あるいは配置換えしたとき、既存のCSSをリファクタリングする必要がない状態
-
拡張できる
-
CSSに携わる人が1人であっても複数からなるチームであっても、問題なく管理できる状態
-
自分とその他の開発者にとってメンテナンス・管理がしやすくする事
施策提案の設計
上記の4つの設計指針と問題点を元に、現状のクライアントの開発人数が少ないこと、また今後実際に運用するのはクライアントである為、最終的にこのような設計方針で検討する事にしました。
- ルールが複雑でない
- 拡張しやすい
- 影響範囲がみだりに広すぎない
- 現状からの修正コストが大きすぎない
何故このように考えたのか
-
ルールが複雑でない
-
実際に運用し続け、複雑なルールを設定してしまうと今後変更したい時に修正しにくいのでシンプルな設計が必要だと思いました。
-
拡張しやすい
-
Webサイトは「公開して終わり」ではなく、公開後も運用が続き、その中で既存のページやモジュールに対する変更が発生することも珍しくありません。今後もサービスが大きくなる可能性があると考えたからです。
-
影響範囲がみだりに広すぎない
-
影響範囲の広いCSSを修正しようとしても、影響範囲が広いので、どこでレイアウト崩れなどが発生するかわかりません。一度影響範囲の広いコードを書くと、修正と確認の作業コストにずっと悩まされ続けてしまうと考えたのでこの様な方針にしました。
-
現状からの修正コストが大きすぎない
-
あまりに大きな修正ををしてしまうと依頼の納期に間に合わなくなってご迷惑おかけしてしまうと考え、大きな修正コストは掛けられないと判断しました。
実装方法を模索
設計指針に基づいて、分かりやすく複雑でなく、現状からの修正が大きすぎないというテーマを元にCSSの設計について調べてみました。調べてみるとファイル分割に焦点が当てられている記事を見つけました。
参考記事の内容
ViewファイルとCSSファイルを1対1になるようにファイルパスを揃えて、スコープ用にdata属性を書きます。修正したいViewファイルがあった場合、対となるCSSファイルを修正するだけで他のページに影響を与えず修正出来るのでとても管理しやすくなります。
次の手順で、各ページで必要なCSSファイルだけを呼び出す
- Viewファイルごとのルート要素に、自身の
app/views/
以降のファイルパス(拡張子抜き)を data-scope-path というデータ属性で設定。 - 対となる CSS 側では [data-scope-path="..."] という属性セレクタで絞って参照。
ファイルはapp/assets/stylesheets/エントリー名/scopes
に格納。
参考記事URL
https://tech.basicinc.jp/articles/166
何故この案にしようとしたのか
この記事を読んでいくと、
設計を理解しているメンバーがプロジェクトから離れるとCSSの影響範囲を把握するのが大変です。CSS設計の場合、グローバルスコープなので全ページ確認しないといけないという大変な作業が待っています。新しいプロパティを追加する事によって、他のページのスタイルを崩してしまわないかと、複数のページを確認しなければなりません。どれだけCSSが得意な人がプロジェクトに入ったところで、解決は大変です。
とありました。
今後設計を理解しているメンバーが離れる事もあると思います。前任の方がプロジェクトから離れ新しいメンバーがプロジェクトに参加し、新規にプロパティを追加した事によってどこのページに影響しているのか把握出来ず、複数のページを確認しないといけない確認作業が大変になってしまいます。
そこでViewファイルとCSSファイルを1対1になる様に設計しておけば**『このページはこのCSSファイルを変更するだけでOK 』**と分かりやすいので、メンバーの入れ替わりがあっても管理しやすいのではと考えました。
この方法を使用し、全ページで同時に読み込まれているCSSファイル分割してページ毎にCSSファイルを読み込ませたら、分かりやすく、管理しやすいのではと思いこの案で実装していこうと思いました。
実装方針の提案書
今回の案件に対しクライアントに以下の様に提案書を提出しました。
CSSの設計方針
viewsの各ファイルに対して、以下方針で対応するCSSファイルを作成します
-
ページファイル:
-
CSSと1:1対応させる
-
パーシャルファイル
-
CSSと1:多対応させる
施策提案書を提出し確認を取る
実装方法を確認したところ、大まかな流れですが承諾頂けました。
一つクライアントから、『ページ単位での分割は実装/移行コストが少し高いように感じるのでコントローラー単位での分割に切り替えて欲しい』という依頼を頂きました。
私が提案した内容は、コントローラ単位での分割にも応用出来る内容でした。そこで開発方針を「ページ単位での分割」から「コントローラー単位での分割」に切り替えました。実装方針を固める事が出来たので本格的に実装開始する事にしました。
まず最初にユーザーがアクセスし、表示されるトップページで使用されるコントローラーから施策をスタートしました。順次流入数が多いページで使われるコントローラーの順番で進めていく方向で決まりました。施策内容と施策順序の許可を頂けましたので、ここから実際に手を動かし実装開始となります。
#2. 実装開始
まずは全ページ読み込まれてしまっているのでコントローラー毎に必要なCSSファイルを読み込めるようにする為の基盤作りから進めていきました。
全ページの共通のレイアウトファイルであるviews/layout/application.html.slim
に対し
##1. if文の条件分岐で値が入っていたら個別のCSSを読み込み、なかったら既存のapplication.cssを読み込む
-
stylesheet_link_tag yield(:stylesheet_scope)
でビューテンプレートに対応するCSSファイルを呼び出す
- if content_for?(:stylesheet_scope)
= stylesheet_link_tag yield(:stylesheet_scope), media: 'all'
- else
= stylesheet_link_tag 'application', media: 'all'
##2. 設定したいコントローラで扱われるビューファイル全部にvirtual_pathを指定
- 各ページテンプレートの最上位の要素に記載
- stylesheet_scope(@virtual_path)
##3. メソッドを定義しスコープを受け取れるようにする
STYLESHEET_PATH_PATTERN = /^(?<controller>[a-z_]+?)\/(?<method>[a-z_]*)$/
def stylesheet_scope(path)
controller_name = path.match(STYLESHEET_PATH_PATTERN)&.[](:controller)
content_for :stylesheet_scope, controller_name
end
##4. app/assets/stylesheets/
直下にCSSファイル作成
- コントローラー名の CSSファイルを作成し、コントローラで使われているビューファイルのCSSを全て読み込ませる
@import 'bases/_variable';
@import 'bulma/bulma';
@import 'bases/_base';
@import 'partials/_footer';
@import 'partials/_header';
@import 'pages/_hoge';
@import 'partials/_fuga';
#3. 実装結果
数値を確認した結果、ページの読み込みスピード改善ができていました。
下記の検証手順で確認してみると、現在読み込まれているCSSファイルが確認できます。
今後サービスが大きくなり別の方がアサインされた場合でも拡張しやすく、新しいモジュールや機能を追加し、配置換えしたときでも保守性も保たれると思います。特にコントローラーとCSSファイルを1:1にする事によってどこのCSSファイルを読み込んでいるか分かりやすくなったと思い、今後の運用しやすくする為の基盤が作られたと思います。
個別読み込みと読み込みスピード改善の検証方法
Coverage機能による検証手順
-
Google Chromeの検証ツールからCoverage機能を使用
a. 「Coverage」という機能を使用するのですが、標準では表示されていないので初回は追加設定します。
b. 「開発者ツール」右上に表示されている「…」が縦に並んだ設定ボタンをクリックします。
c. 「More tools」から「Coverage」を選択し追加します。
d. 「Coverage」が追加されると、開発者ツールの下に表示されます。 -
Coverageで表示されるURLを確認
a. 対象ページ:設定したCSSファイルが読み込まれている
b. 対象外のページ:application.cssが読み込まれている -
読み込みスピードの改善数字
a. Before: LCP 1.5秒
b. After : LCP 0.8秒
##計測結果と確認一覧
実装後にPageSpeed Insightsでページ読み込みスピードが改善されているか数値確認し、Coverage機能を使い現在読み込まれているCSSファイルの確認をしました。
###確認項目
読み込み箇所の確認は以下の通りです。
個別読み込みを設定し必要なCSSが読み込まれている
個別で設定したCSSファイルだけがしっかり読み込まれています。
個別読み込みを設定していないので全ファイルのCSSが読み込まれている
@import 'pages/*':
のようにディレクトリ内の全ファイルが読み込まれています。
###計測結果
計測結果は以下の通りです。
コントローラ毎に個別のCSSが読み込まれている状態の計測数値
個別読み込みを設定していない状態の計測数値
#実務を始める前と終えた後の変化
実務経験前と経験後でプログラミングに対しての考え方や取り組み方が大きく変わりました。
具体的に3つです。
##1. エンジニアとしての心構え
実務を経験する前は書いてある事をそのままやる事しかしてこなかったと思います。教材があり、そこに書いてある事をそのままやるだけで自分で考えて取り組んでいませんでした。
今回実務体験をさせていただき、課題に対してどうやって解決出来るか思考し、それに対しての解決策を導き出す大切さを知る事ができました。書いてある事をそのままやるのではなく自分で思考して取り組む大切さを知る事ができました。
##2. コードに対しての品質の意識
これは本当に反省です。最も意識が変わった事だと思います。実務経験前の私は動けば大丈夫くらいな気持ちでコードを書いていました。
コード品質の良し悪しがサービスの良し悪しにも直結します。しっかり理解したコードを書き、他の人が見ても分かる様なコードを書き品質を落とさない大切さを知る事ができました。
##3. 相手が言っていることを理解する力と伝え方
仕事は基本相手がいて成立するものなので、自分から提案する力、正確に伝える文章力、相手が本当に必要としていることを汲み取る力が大切だと気づけました。
今回の実務を終えて一つ毎日続けようかなと思うことが一つあります。
それは読書です。
元々読書はしていたのですが今後はアウトプット前提の読書をしていきます。
アウトプットとは読書をしたら感想文を書くという事です。感想文を書くという事は、何となく読書してたら感想は書けないので集中して読む+作者の意図を正確に理解する力がついていくと思います。今後エンジニアとして働くときに相手の言っている事の理解と背景を汲み取る力をつける事によって、一番良い結果をクライアントやお願いしてくれたメンバーにお返しが出来ると思いました。ビジネスマンとして成長する為に、今後**『読解力』と、『ロジカルシンキング』**の二つの力を付けていきます。
#実務を終えての感想とプログラミングに対しての思い
今回の経験を踏まえて、自分に改めて足りていないもの、学習しなければならないこと、エンジニアという職業がコードを書くだけの職業ではないこと、技術以外に必要となるスキル、エンジニアになるってどんなことなのか等、本当に多くのことを学ばせていただきました。
実務を通し、改めてエンジニアという職業の魅力を感じました。エンジニアの技術と現職の楽器の演奏技術は似ているなと改めて感じました。
僕は音楽講師を目指した時も技術面に関して何度もつまずき悩まされた事がありました。
そんな僕でも自分の弱点をしっかり分析し一つずつ解消する事によって講師テストに合格する事ができました。
今回も状況がよく似ていると思っています。
エンジニアという立場で仕事をするとは、音楽に置き換えるとライブ出演したような感覚でした。
最初は周りに迷惑をかけてしまう事があると思いますが、誰よりも情熱を持って取り組んでたらその差は埋まると思っています。
エンジニア転職した後も、一つ一つ毎日技術や知識を積み上げて成長し、会社で必要とされ、将来リーダー的なポジションを目指し、メンバーを引っ張っていける様なエンジニアを目指して行きたいと思います。
今回リーダーのY氏に褒められた部分が明るく、ポジティブなのでチームに居るとチームが明るくなると言っていただけました。とても嬉しかったです。技術面では未熟ですが、エンジニアではチーム開発する時の雰囲気作りも大切なんだなと学べました。将来的にチーム開発に携わる時は雰囲気作りのサポートもしていきたいです。それと僕は教える事は仕事柄得意な方だと思うので、新人教育などにも携わっていきたいなと思い、段階的に各ポジションに就いてみたいと思っています。
学習が大変という意見もありますが、好きな事を「学習する」という考えは、違和感があります。
僕は楽器の練習を練習と思ってなく、好きな事だから自然と追求するものだと思っています。
プログラミングに対しても同じ思いでいます。まだ分からない事だらけで自然に追求していけるレベルまで到底達していませんが、そのレベルまでいったら僕は凝り性なのでどんどん追求できる自信があります。
そして何より感謝したいのは、リーダであるY氏と、クライアントです。
私に何度もコードレビューや、施策提案の進め方を丁寧に指導していただく事によって、今回の実務をやり遂げる事ができました。まだまだ自分の力だけでは出来ていないことばかりですが、今後しっかり成長し、あの時育ててよかったなと思ってもらえる様なエンジニアに成長していきます。
同じミスをしない対策として、読解力を鍛え、何をして欲しいか理解し、技術+知識+理解力を付けていきます。
一緒に実務に挑戦した仲間たちにもとても感謝しています。大変な時に励まし合える仲間がいる事は本当に素晴らしいなと実感しました。
エンジニアとしてまだまだ至らない部分が多くありますが、学習を継続するとともに、今後の転職活動に力を入れたいと思います。ご覧いただきありがとうございました。