初めに
この記事はyamanokuさんの投稿されたzennのscrapの内容について自分がまとめたものです。(yamanokuさんの許可はいただいています、ありがとうございます!)
compassで1月13日に開催されるFEStudyでyamanokuさんが登壇されるのでもしよければ参加してみてください。
Zennに分割したのを投稿していますが、個人的にまとめてどこかにおいておきたかったためにこのような形で投稿しています。
間違った情報がないように注意はしていますが、もし間違っている箇所、不十分な箇所がありましたらコメントなどでいただけると幸いです。
それぞれの用語などの情報についてリンクを貼っているのでそこまで読めば深くまで理解できると思います。
かなり長いですが、頑張って書いたのでぜひ読んでください。
HTML
HTML Standardを参照できる
- 入れ子関係
- どういった用途で使われるのか
このサイトはHTMLの歴史や書き方について細かく記されているサイトで日本語訳もあります。
入れ子関係については例えばul
ol
の中にはli
を入れなければならないなどのことで
ダメな例
<div>
<div>・hoge</div>
<div>・fuga</div>
</div>
良い例
<div>
<ul>
<li>hoge</li>
<li>fuga</li>
</ul>
</div>
ちゃんと役割を考えて使わないといけないという話です。
他にも山ほどありますがHTML Standardを読めばわかります。
自分自身理解が不十分なところがあり、きちんとマークアップできるようにがんばります。
<head>
内のみで使用できるタグを把握している
-
<head>
内で使用できるのは<meta>
<title>
<link>
です。-
metaタグでは文字タイプや著者などの情報の設定や、descriptionなどOGに関する設定を行うことができます。
ただnuxtではnuxt.config.js
で設定を行ったり。
nextではnext/head
を使用したり、getStaticPropsやgetServersidePropsを使用したりして設定するため使用しているフレームワークがある場合はそれぞれのドキュメントをみましょう。 -
titleタグではブラウザのタブに表示される文字を設定できます。おそらくみなさん知っていると思います。
-
linkタグではcssファイルを読み込んだり、faviconを読み込んだりします。これもみなさん知っていると思います。
cssの読み込みはレンダリングをブロックするのでパフォーマンスの観点ではheadタグの最後においた方がいいです。
-
セマンティクスに基づいた実装の利点を説明できる
セマンティクスHTMLはセマンティック・ウェブの考え方が基になっており、要するにHTMLをそれぞれの意味に基づいてマークアップしましょうということです。
利点
- 検索エンジンがHTMLをクロールする際にその構成の意味を理解しやすくすることができる。
これがいわゆるSEOに関連することで検索エンジンがHTMLを理解できるように書くことでSEOにおいて優位になることができます。
人間だけじゃなくて機械にも読みやすいように書きましょうということです。
- アクセシビリティの向上がはかれる
アクセシビリティについてはwebA11ly.jpのサイトが個人的に網羅的でわかりやすかったです。
視覚しょうがいの方などはウェブサイトを読み上げるスクリーンリーダーを使用しており、例えば構成を全てdiv
で行ったりすると理解ができなくなってしまいます。
ここはWAI-ARIAなどにも関係してくるのでその時に書きます。
- 自分以外の人がみた時にわかりやすい
構成がきちんとそれぞれのタグを理解して書いてあればコードリーディングもしやすくなります。
Nu HTML Checkerを使うことができる
Nu HTML Checker 知りませんでした。指定したURLのHTMLにエラーがないかを調べてくれるものらしいです。
とても便利そうなので使っていきたいと思います。
構文エラーについてを把握できる
tableの構造とかbuttonのtypeとかですかね、構文エラーで理解しにくい例が思い浮かばなかったです。
各ブラウザで使用できるかできないかを把握している
Caniuse
ブラウザ対応で消耗するのいやですね。IEは撲滅してください
WAI-ARIA
W3Cによって定められた仕様でアクセシビリティを向上させるためのHTMLに付与するものです。
HTML自体に意味がついていますが、どうしてもセマンティクスに書けない例があると思います。
例えばボタンなのにdiv
で書かなければならない場合など、その時にdiv
がボタンだと認識してもらわなければならない場合などに使います。
この場合だと<div role="button"></div>
みたいな感じです。
説明するの辛いのでMDNを参照してください
WAI Web Accessibility Tutorialsを参照できる
WAI Web Accessibility Tutorialsをみましょう、チュートリアル形式なのでみたままです。
WCAGを参照できる
WCAGをみましょう、これ全部理解するのは大変そうですね、、、
各種Roleモデルを理解している
基本的にセマンティクスに書けていれば問題ないですが例外が発生した場合に使うために覚えておいた方がいいと思います。自分自身全く覚えれていません。
丸投げしますごめんなさい
https://qiita.com/nezurika/items/eac689a97895a27b8791
https://www.dkrk-blog.net/html/aria_role01
CSS
SASS、SCSS、Stylus
- SASS、SCSS
ruby製のCSSメタ言語でネストや変数、mixin、関数、スタイルシートの分割ができます。
違いは{}
があるかないかです。CSSは{}
を使うので理解しやすくSCSSの方が使われています。
個人的にpugもそうですが、シンプルにはなりますがそれ以上にインデントでの位置関係表示が辛いのでSCSS使っています。
p
.first
font-size: 12px;
p {
.first {
font-size: 12px;
}
}
変数
変数を用いることで何度も色コードやfont-sizeを書かなくて済みます
$text_color: red;
div {
color: $text_color
}
mixin
mixinを使うことで何度も同じことを書かなくて済みます、media query
とかで使います。
$breakpoint-tablet: 1024px; /* 変数宣言 */
$breakpoint-mobile: 640px; /* 変数宣言 */
/* $break-point以下の時に@contentを適用 */
@mixin max-screen($break-point) {
@media screen and (max-width: $break-point) {
@content;
}
}
/* $break-point以上の時に@contentを適用 */
@mixin min-screen($break-point) {
@media screen and (min-width: $break-point) {
@content;
}
}
関数
繰り返しの時とかに使えます、if文もあります
@for $i from 1 through 5 {
.hoge-#{$i} {height: 10px * $i;}
}
Stylus
使ったことがないので違っている可能性があるかもしれないです。
Nodejs製のCSSプリプロセッサです。
SASS/SCSSと同様に変数や関数、mixinなどがあります、継承があること、SASS/SCSSのどちらの書き方もできる点が違う点だと思います。
morishitterさんの記事がわかりやすかったです。
CSS設計についての理解
- BEM、OOCSSなどがあります。
BEM
Block
Element
Modifier
の頭文字をとったもので
block_element--modifier
のようにクラス名を書きます。
利点
細かくクラス名を指定するため、使用している場所などを特定しやすくメンテナンスコストを少なく抑えることができます。
欠点
クラス名が長くなるので書くのが辛いです。
OOCSS
Object Oriented CSS
の略でレイアウトに関するスタイルと、レイアウトに関するスタイルに分けて記述するという考え方のことで
<div class="card large">
<img src="...">
<p class="title">Lorem ipsum dolor</p>
<button class="button bg-red">Add</button>
</div>
button
とbg-red
のようにレイアウトとスタイルに関連するスタイルを分けます。
利点
BEMに比べコード量が減る
欠点
影響範囲が大きくなる
ただスクラップのほうでcatnoseさんがおっしゃっていましたが、BEMについて理解があるといろんなところでやりやすそうとのことなのでBEMについてはきちんと理解しておいて損はないと思います。
詳細度
cssには優先度と詳細度があり
このようなルールがあります
- 優先度が高いもの
- 優先度が同じ場合、詳細度が高いもの
- 優先度と詳細度が同じ場合、最後に宣言されたもの
優先度
優先度には三つあり
- 製作者スタイル
私たちが書くスタイル
- ユーザー定義スタイル
ブラウザの「表示→インターネットオプション→ユーザ補助」等で開かれる画面で設定可能なスタイル
- ブラウザの標準スタイル
それぞれのブラウザが実装しているスタイルで、何もスタイルを設定していない時に適用される
button
などは最初からボーダーや色がついていたりしますよね?あれのことです
順番は上からの順番で優先度が高いです。
自分でスタイルを書いた場合、2に引っかかるので詳細度について考えなけえればなりません
使う機会の多い詳細度は
p#text > #text > p.text > .text で、基本的にidが優先されます
追記
上記の詳細度の順番は正しいですが、詳細度は正しくは点数計算ではないそうです、訂正します。
詳しく知りたい方は以下の記事を参照してください。
izumin5210さんの記事
(Zap212さんありがとうございますmm)
<template>
<p class="hello" id="hello">こんにちは</p>
</template>
<style scoped>
p#hello {
color: red;
}
p.hello {
color: blue
}
#hello {
font-size: 36px;
}
.hello {
font-size: 12px;
}
</style>
この場合だとcolor:red;
とfont-size:36px
が優先されることになります。
cssが大した量ではない場合そんなに困らないと思いますが膨大な量のstyleが定義されている場合詳細度を考えないといけない場合があります。
依存がひどくなると!import
で解決してしまってさらにひどいことになるみたいな感じです。
!import
は最優先となります
scssなどはファイルに分割してネストして書くこと、vueはstyleにscopedをつけることなどで影響範囲を限定し、このような問題が起きにくいようにしています(もちろん起こっている場合もありますが、、、)。
media query
レスポンシブ対応するために書きます
p {
color: red;
@media screen and (min-width:480px) {
color: blue;
}
}
こんな感じで範囲を指定してその画面サイズに対応するcssを適応させることができます。
stylelintなどの静的解析ツール
stylelint
javascriptを書いたことがある方であればeslintを使ったことがあると思います、それと同様のことをcssでできます。
簡単にいうとcssを書くための規則をきめ、それに沿わない場合はlintを通した時にエラーが出るようになります。(カラーコードは全て小文字に統一するなど)
p {
- color: #FFFFFF;
+ color: #ffffff;
}
GridやFlexboxを用いたレイアウト調整
レイアウトを作成する時にGridやFlexboxを使うと思います。
個人的な意見ですがgridは複雑なレイアウトを作成したい時に使い、ほとんどの場合flexboxで解決できる気がします。
これらに関しては説明が大変すぎるので素晴らしい記事に任せます
Flexboxチートシート
Grid
CSS変数
scssの変数と同じです
--main-color: black;
p {
color: var(--main-color);
}
CSSフレームワーク
有名なところではbootstrapやmaterial-ui、tailwindcssなどがあると思います。
cssフレームワークを利用することでcssへの理解があまりなかったとしてもリッチなデザインのページを作成することができます。
cssフレームワークにも種類があり、
- bootstrap、material-uiのようにコンポーネントを提供してくれるもの
- tailwindcssのようにスタイルを便利に定義するためのツールだけを提供しているもの
があると思います。
それぞれ利点、欠点があると思うので少し書きます。
bootstrap、material-uiなど
利点
- コンポーネントを提供してくれるので、デザイナーがいなくとも簡単にリッチなデザインのページを作成することができる
欠点
- 学習コストがかかる
- デザインがありきたりなものになる
コンポーネントを提供してくれるのは便利ですが、カスタマイズが行えないため、使い所をよく考えた上で採用するべきだと思います。
デザインがありきたりなものになるので見た目にオリジナリティが求められる場合では使うべきではないです。
コンポーネントを提供するcssフレームワークの全てについてはTAKさんの記事が本質をついていると思います。
tailwindcssなど
利点
- デザインをカスタマイズができる
- 学習コストがそこまで重くない
欠点
- cssを書く必要がある
- クラス名が長くなる
utility-firstなcssフレームワークなのでtailwindだけで使うのではなくtailwindではメインの部分(レイアウトなど)を実装し、cssで細かい部分を実装する感じになると思います。
強力なcssフレームワークでないがゆえに柔軟なスタイルを適応させることができるのが利点です。
逆にhtmlのクラスに提供されたツールを書いていく形になるのでかなりclass名が冗長になってしまいます、特にレスポンシブ対応を行ったりすると読むのが辛くなります。
css in js
Javascript
現行の仕様に追従したJavascriptを意識して書くことができる
javascriptはtc39が仕様をきめていますが、それのバージョンについて理解しているかという話です。
es2016(es6)、es2017、es2018、es2019、es2020等でなんの機能が追加されたのか、またブラウザによっては使えない場合などがあるのでbabelなどでトランスパイルを行う必要があります。
簡単にですがまとめました。
version | 追加機能 |
---|---|
es2016 | アロー関数 ()=>{} 、import/export、class構文 |
es2017 | async/await |
es2018 | 冪乗の追加 2**4 、promiseにfinally追加 |
es2019 | json.stringifyの改善、catchの時に関数を返さなくて良い |
es2020 | Optional Chaining hoge?.value 、Nullish Coalescing Operator ?? true:false |
varではなくletやconstを使用する
es2015より前では変数や定数を定義するときはvar
を使用していましたが、現行のバージョンでは変数はlet
、定数はconst
を使用するべきで、少なくともPRの中にあれば間違いなく修正させられると思います。
AltJSについて知っている、利用している
AltJSとはコンパイルすることでjavascriptが生成されるプログラミング言語のことです。
javascriptにある問題(動的型付けなのでチーム開発が辛いなど)を解決することができます。
有名どころはcoffee scriptやtypescriptがあると思います。
私はtypescriptしか使用したことがないのですが、javascriptでは不可能な静的型付けを行えるので一定規模以上のプロダクトではコードの保守性を保ちながら開発を行うことができます。
詳しいことはtypescriptのところで書きます。
eslintといった静的解析ツールを用いることができる
eslintはcssのstylelint
と同じでコードを書く際に一定の規則を設けてlinterを通した際にエラーを出して書き方を統一することができます。(例えば全てシングルクオーテーションにするなど)
おそらくチーム開発などではeslintとprettierのどちらかは使用していると思います
pretier
prettierはフォーマッターで定めたルールに則って自動でフォーマットを行ってくれます。
CIでformatter、linterを通すことでPRを出す時にチームのルールに則ったコードに統一することができます。
併用することもできますが少し設定に手間取るかもしれないです、私はeslintだとセミコロンなしにしているのにprettierだとセミコロンありにしていてハマったことがあります。
consoleで実行内容を出力できる
consoleを用いることで簡単にデバックを行うことができます。
MDNを見れば大体理解することができると思います。
console.log
やconsole.error
を使ったことがある方は多いのではないでしょうか?
DOMが何かを理解している
DOMとはDocument Object Modelの略でウェブページをオブジェクト指向の表現しており、javascriptのようなスクリプト言語から変更することができます。DOMはプログラミング言語ではないですが、これをjavascriptで操作することでHTML要素に動きをつけることができます。
<template>
<p>サンプル</p>
</template>
<script>
const paragraphs = document.getElementsByTagName("p");
alert(paragraphs[0].nodeName);
</script>
javascript、JQueryではDOMに直接アクセスして操作することで動きをつけていましたが
最近のjavascriptフレームワーク(vue、reactなど)は仮想DOMを用いて変更の差分部分だけ最描写することで実行の時間を短縮しフロントエンドの領域に新たな風を吹かせました
この辺はmizchiさんの魂の震える記事を読んでいただければと思います。
オブジェクト、配列を作成できる
オブジェクトは関連あるデータの機能の集合のことで例えばユーザー情報などをオブジェクトとして作成することができます。
配列はリストのようなオブジェクトのことで要素数も型も固定されていないです、配列は入った順にindexが振られるのでそれを指定することで呼び出します
key、valueがあるのがオブジェクトで、リストになっているのが配列です。(上手い説明が思い浮かびませんでした)
// オブジェクト
const userData = {
id: 1,
name: "hoge"
};
console.log(userData.id)
// 1
// 配列
const person = [
"hoge",
"fuga"
]
console.log(person[0])
// hoge
配列の操作
配列の操作としては追加、削除などなどたくさんあります。
let fruits = ["りんご","みかん"]
// 配列の末尾にバナナを追加
fruits.push("バナナ")
// ["りんご","みかん","バナナ"]
// 配列の末尾を削除
fruits.pop()
// ["りんご","みかん"]
MDNに一覧があるのでみましょう
イベントを登録できる、削除できる
javascriptを使えばイベントを登録、削除することができます、今回はclickイベントの例です。
まあこれは見ればわかると思います。DOMを指定してイベントをつけたり消したりします。
<p id="p1" style="color: red">クリックして下さい</p>
<p id="p2">テストa</p>
<input type="button" value="削除" onclick="removeEL()" />
<input type="button" value="追加" onclick="addEL()" />
<script>
const p1 = document.getElementById("p1");
p1.addEventListener("click", changeName1);
function changeName1() {
const p2 = document.getElementById("p2");
if (p2.textContent === "OK") {
p2.textContent = "テストa";
} else {
p2.textContent = "OK";
}
}
function removeEL() {
p1.removeEventListener("click", changeName1); //イベントの削除
}
function addEL() {
p1.addEventListener("click", changeName1); //イベントの登録
}
</script>
MDNのJavascriptドキュメントを参照できる
MDNをわからなかったら読みましょう
tc39でプロポーザルが出されている機能を参照することができる
javascriptに新たな機能が追加される際にプロポーザルに詳細が書かれているのでそれを読みましょうという話です。
リンク先を見ればわかると思いますが、5つのステージに分けられており
stage | 意味 |
---|---|
0 | アイデア |
1 | プロポーザルの目的や解決方法をデモで示す、提案 |
2 | ドラフト |
3 | 仕様は完成しておりフィードバック待ち |
4 | 完成しており、取り込まれるの待ち |
毎年ECMAScriptのバージョンが上がるので、その時までにstage4になったものが取り込まれます。
es2020でもOptional Chaininghoge?.value
、Nullish Coalescing Operator?? true:false
が追加されましたがみなさん試しましたか?
まだの方はぜひ試してみてください。
Typescript
静的型付けを理解している
世の中には動的型付言語(Python、Javascriptなど)と静的型付言語(C/C++/Goなど)があります。
静的型付とは変数や関数に型の記入を行うことで、これにより実行しなくともコンパイル時にバグやエラーを検知することができます。
また変数がどれだけメモリを使うかなどがわかるため無駄なメモリが発生しません。
一方でデメリットとしてはコードの記述量が増えてしまうことなどがあげられます。
なぜTypescriptを選ぶのか
個人的な意見ですが、例えばペライチのページなどの小規模のものであればJavascriptでいいと思います。
しかし業務のコードなど規模が大きくなってくるとエラーが起こった時に型があるかないかはエラーの原因の特定などの面でとても大きいと思います。
加えてPRなどのレビューでコードを読む時にコメントを書かなくてもコードから関数の返してくる型がわかればコードを読むのが楽になります。
まとめると、チーム開発で規模の大きな開発の時にPRのレビュー、コードリーディング、新機能の追加などにおいてそれぞれのエンジニアの負担を軽減したいから
だと思います。
扱える型について理解している
typescriptの型にはプリミティブ型とリテラル型、オブジェクト型があります。
型 | 種類 |
---|---|
プリミティブ型 | string, number, boolean, symbol, bigint, null, undefinedの基本型 |
リテラル型 | その文字、数字などしか許されない型 foo 0 など |
void型 | 関数の帰り値で使われる何も返さないことを示す型、明記することはない |
any型 | 次で説明します、簡単に説明するとなんでもありの最終兵器です |
ジェネリクス | 引数の型に応じて帰り値の型を決定するなど動的な型付けを行うことができます |
タプル型 | 要するに配列の型です、ただし配列の操作を行うときは危険なので使わないほうがいいです。 |
オブジェクト型 | intefaceやtypeを使ってオブジェクトに型をつけることができる |
// void型
// 帰り値がないため自動的にvoid型となる
function click():void {
alert("こんにちは")
}
// ジェネリクス
function Foo<T> (abc: T): T {
return abc
}
// 引数の型に応じた型を帰り値の型にする
const res1 = Foo<string>('foo')
const res2 = Foo<number>(123)
// タプル型
const list = [string, number] = ["name", 18]
list.pop();
list.push('address');
// list = ["name", "address"]
const old = list[1]
// oldに入っているのは文字列だがコンパイルエラーは発生しない
// オブジェクト型
interface {
foo: string;
baz: number;
}
型の全体的な話についてはuhyoさんの記事がわかりやすいのでこれを読めば良いと思います。
ジェネリクスについてはYumetaroさんの記事がわかりやすいです
anyについて
こちらもuhyoさんの記事がわかりやすいのでこれを読めば良いと思います。
anyは敗北者です。
型定義できる
typescriptはかしこいので簡単な型定義であれば推測して型をつけてくれますがこのように明記もできます。
// 推論されるため countはnumber型になる
let count = 0
// 関数の帰り値の型を示す
increment(): number {
this.count++;
}
場合において定義ファイルを作成できる
例えばライブラリを使用する時にtypescript対応していない場合は自分で型定義のファイルを書く必要があります。
vscodeなどでライブラリの型定義のファイルにジャンプすれば見ることができます。
declare namespace JSX {
interface IntrinsicElements {
'group': any,
'geometry': any,
'lineBasicMaterial': any,
'mesh': any,
'octahedronGeometry': any,
'meshBasicMaterial': any,
'meshLine': unknown
'meshLineMaterial': unknown
}
}
declare module 'threejs-meshline'
これは私がreact-three-fiberというライブラリを使用した時に書いた型定義ファイルですが、このようにnamespaceとinterfaceを用いて書くことができます。(めちゃくちゃ適当です)
Nossaさんの記事がわかりやすかったです。
型ガードの理解がある
typescriptでは型ガードといってif文などを用いることで処理する変数の型を絞り込むことができます。
let sample: number | string = 1
if (typeof sample === "string") {7
//sampleがstring型の時の処理
} else {
//sampleがnumber型の時の処理
}
みたいな感じです
typeof
だけでなくinstanceof
やin
などでも行えます。
typescriptのドキュメントがわかりやすいです。
新しいJSの機能を利用してできることを理解している
tc39のところで書いたので省略します。
テストツール
なぜテストをしなければならないのかを説明できる
テストを行うことは工数を増やしエンジニアの負担となるが、それ以上にテストによってエンジニアの負担を減らすことができるから
テストによって減少するエンジニアの負担とは
- 機能追加、変更、削除の時などに既存の機能が壊さない可能性をあげられる
- スナップショットテストなどによって意図せぬ変更を検知できる
- テストを通過させることでコードの品質を担保することができる
などが考えられます。
しかし小規模の開発などでは工数増加の負担が上回ることのほうが多いため、学習のためなどでなければ必要ないと思います。
TDD、BDDとは何か
TDD
TDDはTest Driven Development
のことでテスト駆動開発と呼ばれます。
私はしたことがないのですが、簡単にいうとプログラムを書く前にテストコードを書き(テストファースト)、そのテストコードに適合するように実装、リファクタリングなどを行っていく開発手法のことです。
- 実装したい機能の要件を元に失敗するテストコードを書く
- テストを通過する機能要件を満たすコードを書く
- テストを通過する状態を維持しながら②で書いたコードをリファクタリングする
メリット
- 都度バグを潰せるためバグが残りにくい
- エンジニアが安心して開発を行える
デメリット
- 開発に時間がかかるため、導入をよく考える必要がある
- 初めのテストコードで抜けがあると困る
- 時間、資金に余裕がないと厳しい
個人的にはよほど資金がある開発か、私たち学生の個人開発のように納期などが決まっていない開発でないと厳しい気がします。
BDD
BDDはBehavior Driven Development
のことで振る舞い駆動開発と呼ばれます。
TDDとBDDは根本的には違わず、それまでのTDDの語彙では伝わりにくかった部分を言い換えたり、テンプレートを与えることで幾分かハードルを下げるという役割を持っているそうです。
根本的には同じですがBDDでは次のようなテンプレートを追加します
語彙 | 意味 |
---|---|
Given x. When y. Then z. | テンプレートで「xであるときに、yすると、zになる」というように手順的にして読みやすくする |
Given | 事前状態の表現 |
When | 操作、イベントの表現 |
Then | 事後状態の表現 |
x should y | テスト自体を「対象(x)がどうである(y)べきか?」と表現する |
digitalsoulの翻訳記事を参照しました。こちらを読めば詳しくわかると思います。
どういうテストがあるのか理解している
フロントエンドのテストには
- ユニットテスト
単体テストとも呼ばれ小さなプログラムをカバレッジを100%に近い状態で行うテストのこと(getter関数が想定したものを返しているかなど)
これによりどこかでエラーがおこっても個々の関数などを原因から排除でき特定が容易になります。
ユニットテストにはブラックボックステストとホワイトボックステストの二つがあります
-
ホワイトボックステストはテスト対象のコードを中身まで理解した上で行うテストのことで質の高いテストになる一方、労力がかかります
-
ブラックボックステストはコードの中身をみずに、例えばAという関数は「この値を入れるとこの値で帰ってくる」ということだけを意識して書くテストのことです。労力はかかりませんが、潜在的なバグを見落とします。
-
結合テスト
検索機能など一つの機能にたいして行うテストのこと(検索欄にモックのデータを与えてフォームを送信すると送信完了のダイアログが表示されるなど) -
システムテスト
バックエンドとの通信なども繋ぎ合わせてテストを行うこと -
リグレッションテスト
コードになんらかの変更を行った後に動作が担保されているかを確認するために実行されるテストのことです。
デグレーションを防ぐために行われます。
。
- UIテスト
見た目に関するテスト
があります
それぞれのテストにおいてどういうツールを用いるかを理解している
ユニットテスト
フロントエンド開発のユニットテストにおいて使用されるテストツールはrailsであればRspec、javascriptであればjestやenzyme、laravelであればphpUnitなどになるかなと思います。
結合テスト
基本的にブラウザ(chromeやsafari)などで人間の目でみてUIを確認することがフロントエンドだと多いと思います。
システムテスト
Seleniumが有名だと思います。
リグレッションテスト
この後に説明しているCIツールを使用すると思います。例えばCIが走るタイミングをPRが出された時などにするとそのタイミングでテストが走り修正に問題がないかがわかります。
UIリグレッションテストにはStory Bookも使用できると思います。
UIテスト
javascriptであればmochaが有名だと思います。
ブラウザ自動化ツールを知っている
これもSeleniumが有名だと思います。
GUIテストツールについてまとめてくれているjun2014さんの記事があったので紹介しておきます。
テスト自動化ツールを知っている
皆さんCIという言葉を聞いたことがある方がいると思います。
CIはContinuous Integration
の略でPRを出した時やプッシュした時に自動で私たちの書いたテストを行ってくれます。
CIは有名どころではCircleCIやGithubActionsなどが主に使われていると思います。
使ったことがない人はぜひドキュメントを読んで使ってみてください。
Polyfill
なぜ必要なのか説明できる
Javascriptのところで書きましたがJavascriptはブラウザの対応によっては書いたコードが動かない可能性があります、例えばMathを利用している時IEではES5までしか対応していないためMathライブラリがそもそも存在しないため動かないです。
そのためES6で書いたコードをES5に書き換える必要があり、そのためにPolyfill/Babelが必要です。
PolyfillはES5に存在しない関数やライブラリの代替コードのことで
BabelはES6記法をES5にトランスパイルしてくれるものという違いです。
実際にはbabelの中でpolyfillが動いていて対象ブラウザによってpolyfillから代替コードをとってくる形となっています。
リクルートの記事が挙動を理解しやすかったです。
開発においてbabel、core-jsのセットアップができる
宣言的UI
宣言的(declarative)という言葉がreactやvueなどのモダンな技術のドキュメントには書いてあります、私自身vueから入ったため命令的な書き方をするJQueryをほとんど触ったことがなく、なぜこんなにもreactやvueが持て囃されているのだろうと思っていました、
しかし宣言的UIについて詳しく書かれている記事を読むことによって現在のこのフロントエンド技術のトレンドがなぜこのようなことになっているのかということが腑に落ちました。
どのような経緯があり今の状態になっているのかを理解すれば学習するのが楽になると思います。(少なくとも自分はそうでした)
コードの書き方には宣言的な書き方と命令的な書き方があります、命令的な書き方を使用する技術としては上記したようにJQueryがあげられるのでないかと思います。
一方宣言的な書き方をする技術としてHTML/XAMLなどが思い浮かぶ方もいるかと思いますが、reactに端を発する宣言的UIを採用したフロントエンド技術の広がりは仮想DOMを使用することによって実現したHTMLなどとは異なったものです。
従来のJSによるDOM操作とは異なるものだと理解して説明できる
// 命令的な書き方
<script>
const main = document.createElement("main");
let message = "こんにちは";
const input = document.createElement("input");
input.value = message;
input.addEventListener("input", inputHandler);
main.appendChild(input);
const p1 = document.createElement("p");
p1.innerHTML = message;
main.appendChild(p1);
document.body.appendChild(main);
// 宣言的な書き方
<template>
<main>
<input type="text" v-model="message">
<p>{{ message }}</p>
</main>
</template>
<script>
data() {
return{
message: "こんにちは"
}
}
</script>
Yametaroさんの記事からお借りしました
上記のふたつのコードは同じものを実装したコードですがみてわかるように宣言的な書き方のほうが直感的です。
今回の例のように簡単なものであればなんとかなりますが、DOMの追加などが発生する場合、最終的なビューを想像するのが難しいです。
なぜ最初から宣言的な書き方をするものが流行らずに命令的な書き方をするものが使用されていたのだろう???
普通に考えて直感的なほうが使いやすくて良いはずなのになぜだろうと無知な私は思いました。
理由は簡単です、実現できていなかったからです。
宣言的UIを実現することは中身が静的なものであれば問題ありません、問題は中身が動的なものとなり再描画が必要となった時です。
一つの要素が追加される度に画面全体を再描画していては重すぎて現実的に使うのは厳しいですが、
そこを解決したのが仮想DOMによる差分の再描画です。
簡単にいうと宣言的な書き方を実現するために必要な再描画速度を使用可能なレベルで世の中に提供したのがreactであり、そのために仮想DOMが使用されている
ということです。
なのでsonatardさんのスライドでもおっしゃっていますが モダンで良さそうだからreactやvueを使うではなく、宣言的な書き方をしたいからreactやvueを使う
という考えが大切だと思います。
また宣言的UIの実現によって命令的な書き方では最終的なビューは前回の実行結果に依存していたのが状態の変化に応じて再描画するようになったことで前回の実行結果に依存しなくなりました。
仮想DOMによる再描画の話は私自身深く理解しておらず、変な説明をして混乱させてしまう可能性もあり、理解したい方は以下の記事を読んでいただければと思います。
mizchiさんの記事や
sonatardさんのスライド
erukitiさんの記事を読めばより深く理解していただけると思います。
採用しているライブラリ、フレームワークを知っている
vue、react、SwiftUI、Flutterなどがあります、ドキュメントにdeclarative
と書いてある技術は採用していると考えていいと思います。
状態管理を考慮することができる
宣言的な書き方ができるようになったことによって、状態を分離して書くことができるようになりました、状態をどのようにもつのかについて考える状態管理を考慮する必要があります。
状態管理の方法としてはローカル(コンポーネントごと)で保持する方法とグローバルで保持する方法(アプリケーション全体)のふたつがあります
ステートを保持する場所(ローカル、グローバル)を理解している
- ローカル
それぞれのコンポーネントで状態を持つことで、複数のコンポーネントがそれぞれ状態を持つ場合、全体の状態の把握が難しい一方で
それぞれのコンポーネントが状態を含むのでコンポーネントだけで全ての機能が完結し再利用性が高いです、
ReactHooksなどはこちらです。
- グローバル
それぞれのコンポーネントで持つのではなく単一のストアと呼ばれる場所で状態を管理しそれぞれのコンポーネントで呼び出します。
単一の箇所に状態が全て書いてあるので全体の状態の把握が容易である一方で、どのコンポーネントがどの状態を持っているのかが把握しにくいことコンポーネントの再利用性が低くなってしまうことが問題点としてあげられます。
vuex、reduxなどはこちらです。
基本的にそれほど規模の大きくない開発ではローカルで状態管理を行って問題ないと思います、規模が大きくステートを渡す際にいわゆるバケツリレーになってしまうなど辛い状態になってしまうのであればグローバルでのステート管理を行うべきであると思います、ただreacthooksではuseReducerを使えばバケツリレーを防ぐことができるようなのでどちらを採用するのかはよく考える必要があると思います。
react/nextの状態管理についてはtakepepeさんの記事がとてもわかりやすかったです。
ステートを受け渡す方法を知っている
ステートは状態のことを指します、ステートの渡し方は基本的にはローカルとグローバル同じで、
状態を保持するコンポーネントからそのステートが必要なコンポーネントがpropsとして受け取る形になります、
しかしグローバルでステートを定義している場合グローバルステートから直接必要なコンポーネントにステートを渡すことができます。
import Vue from 'vue'
import Vuex from 'vuex'
export default new Vuex.Store({
state: {
user: "taro"
}
})
<template>
<!-- <p>taro</p> -->
<p>{{ this.user }}</p>
</template>
<script>
data() {
return {
user: ""
}
}
// グローバルステートにアクセスして値を必要なコンポーネントで取得することができる。
created() {
this.user = this.$store.state.user
}
</script>
更新方法を知っている
ステートの更新方法は
- コールバック関数で更新する
- イベントを発行する
があります。
// ローカルステート
import React, { useState } from 'react';
function Example() {
// ローカルステートとして`count`を定義、setCountが更新のための関数
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
// クリック時にsetCount関数を呼びcountに1を足す
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
// グローバルステート
import Vue from 'vue'
import Vuex from 'vuex'
export default new Vuex.Store({
state: {
loading: false
}
mutations: {
// setLoading関数の第二引数として受け取ったものにステートを更新する
setLoading(state, payload) {
state.loading = payload
}
}
})
<template>
<button @click="isLoading">ローディング開始</button>
</template>
<script>
// グローバルステートにアクセスして値を必要なコンポーネントで取得することができる。
isLoading() {
// setLoading関数を呼び第二引数にtrueを渡す
this.$store.commit("setLoading", true)
}
</script>
バインディングは単方向か双方向であるか理解している
バインディングには単方向バインディングと双方向バインディングがあります。
単方向バインディングは一方通行に同期を行うことでデータを受け取って見ることしかできないことなどがあげられます
双方向バインディングは双方向に同期を行うことができ、例えばフォームに入力した値がすぐに反映されることなどがあげられます。
双方向バインディングを提供しているフロントエンドフレームワークとしてはVueJsがあげられます、vueはv-modelというディレクティブを提供しており、これにより双方向バインディングが可能です、サンプルコードを添付しておきます。
<template>
<div id="app">
<p>
// v-modelを使用することによって入力した値がすぐにpタグに入る
<input type="text" v-model="message">
</p>
<p>
{{ message }}
</p>
</div>
</template>
<script>
data() {
return {
message: 'Hello Vue.js!
}
}
</script>
バンドルツール
バンドルツールとはcss
やjavascript
ファイルなどの複数のモジュールの依存関係を解消して一つにまとめてくるものです。
これによって開発時に扱いやすくなる他、http/1.1を使用している場合、リクエスト回数を減らすことでパフォーマンスの観点でも利点があります。
最近のフロントエンドフレームワークだとビルド時に自動で行っていたりする(distファイルとかに出力されていると思います)のでわかりにくいですが、理解しておかないといけないものです。
Kosukeeeさんの記事がよくまとまっていると思います。
Webpack, gulp, rollup, parcelというツールが何をするものか理解している
Webpack
Node.jsでサーバーサイドで動かすモジュールバンドラーツールです、バンドルツールの中では圧倒的な使用率でこれさえ使えれば問題ないのではないでしょうか?
(採用理由とかを考えるのであれば他との比較も必要です)
日本人のwebpackコミッターのhirropyさんがいるのでブログ読むのがおすすめです。
hiroppyさんのブログ
webpackにおいて革新的だったのは以下の二点で
コード分割機能によって、アプリケーションを管理可能なチャンクに分割して、オンデマンドで読み込めるようにします。これによりユーザーは、アプリケーション全体のダウンロードとパースを待つ場合よりも、はるかに早くインタラクティブなサイトを使用できるようになります。これは手作業でも可能ではありますが、大変な作業になります。
画像やCSSなどの静的アセットをアプリケーションにインポートして、依存性グラフ内で別ノードとして扱うことができます。ファイルを適切なフォルダに格納する作業に神経を使ったり、ファイルのURLにハッシュを追加するためにスクリプトをいじったりする必要はありません。webpackが自動で処理してくれます。
reactのバンドルツールの記事から参照
gulp
Node.jsをベースとしたタスクランナーでgulpfile.js
に定義したタスクを$ npx gulp minify-css
のような形で呼び出して実行することができます。
cssの圧縮はこんな感じで定義します
gulp.task("minify-css", function() {
gulp.src('src/*.css')
.pipe(cleanCSS())
.pipe(gulp.dest('dest/'));
});
圧縮などの機能はgulp
やnpm script
で行われていたのですが、最近ではバンドルツールに圧縮してくれる機能が入ったりしてしまっています。
rollup
rollupはwebpackと同じくモジュールバンドラーツールですが、webpackなどの他のモジュールバンドラーがes5を前提としていますがrollupはes6を前提としており、一旦全てes6に変換してからbabelでes5に変換します。
これによりes6のtree shaking
を使用することが可能です。
tree shaking
// commonjs(es5)
const pkg = require("pkg")
// es6
import { sample } from 'pkg'
不要なパッケージなどをコンパイル時に削除することでバンドルサイズを小さくすることができます。
しかし、rollupを通した時にes6に変換されないものがあるというのが欠点らしいです。
なので
コード分割が必要で静的アセットを多用しており、es5がベースの場合はwebpack、es6をベースとしており、他者も使用できるものを作成しているのであればrollupを使うべき
です。
実際にreactは他者も使用することができるライブラリなのでrollupを用いてバンドルしているそうです。
reactのバンドルツールの記事がとてもわかりやすかったです。
parcel
これもモジュールバンドラーツールです。
webpackとの違いとしてはwebpackは多機能で細かいところまで設定することができる、一方parcelは細かい設定はできないが手軽にバンドルをすることができるという点で異なります。
しかしビルドしたファイルの出力先や出力するファイル名を指定することができません、これは画像やcssは別ファイルに切り出したいと思っている人からすると厳しいのではないでしょうか。
しかし、ビルドが早いという特徴を持っています。
どういったものがバンドルされているか分析することができる
本来バンドルツールはjavascriptしか読み込めないですが、ローダーを使用することによってcssなども読み込むことができます。
(css-loaderを使用することでcssを読み込むことができるなど)
そのためcss
javascript
画像
webフォント
音声
画像
などがバンドルされると思っていいと思います。
圧縮してファイルサイズを小さくすることができる
html
css
javascript
画像
ファイルを圧縮する際にはgulp
などのタスクランナーを使用します。
gulpでのjsの圧縮
また上記したようにwebpackでも提供しています。
webpackでのcssの圧縮
開発モードとプロダクションモードの切り替えができる
おそらくほとんどの人がnpm script
でNODE_ENV
を用いて切り替えを行っていると思います。
これによりlocalhostのポート番号をモードごとに変更したり、開発モードの時だけ手元の環境変数を渡したりすることができます。
{
"scripts": {
"stg": "NODE_ENV=stg webpack --mode production",
"prd": "NODE_ENV=prd webpack --mode production",
"start": "NODE_ENV=dev webpack-dev-server --mode development --hot --inline --watch-content-base"
},
開発モードの時はnpm run start
で
プロダクションモードの時はnpm run stg
npm run prd
を走らせる。
Code Splittingが何をしているものか理解している
Code Splittingはバンドルしたファイルを適切なファイルサイズに分割することで、http/1.1ではリクエスト回数を減らすことによりパフォーマンスを向上することができたがバンドルサイズが巨大すぎるとそのファイルが読み込まれない限り、画面にcssやjavascriptが適用されないという問題が起こります。
この問題を解決するためにコードを適切なファイルサイズに分割する必要があります。(もちろん大したファイルサイズでなければ分割しなくて良いです)
これにはhttp/2でストリームの導入により一つのコネクションで並行して複数のリクエスト/レスポンスの処理ができるようになったこともあるような気がします。
基本的に分割方法としては
Page
ページごとの分割、
Fold
初期描画画面内にあるかないかでの分割、
Temporal
モーダルなどの最初の読み込みに必要かどうかの分割
の三つで行われているようです。
seyaさんの記事がcode splittingについて詳しく説明してくれています。
numb_86さんの記事がwebpackでの分割方法についてわかりやすいです。
パフォーマンス
個人的な意見ですがパフォーマンスに関してはdev toolの使いかたを覚えるのが一番いいと思います。
私が読んだ本の中で一番勉強になったパフォーマンスに関する本を置いておくのでぜひ読んでみてください。
PRPLパターン、RAILモデルについてそれぞれ説明できる
PRPL
PRPLとはGoogle I/O 2016で提案されたもので Push(preload)/Render/Pre-cache/Lazy-loadの略です。
これはPWA(Progressive Web Application) の構築・配信のための設計アーキテクチャで、PWAというのはwebページをネイティブアプリのようにできるやつのことですね。PWAとは
要するにスペックが低くユーザー体験が低くなってしまいがちなモバイルデバイスのためのパフォーマンス改善のことです。
以下はweb.devの記事の抜粋に説明を付け加えたものです。
P(push/preload)
pushとはhttp/2のserver pushを用いることによってバンドルファイルの読み込み時間を減少させ、それにより描写速度を早くすることです。
これの理解のためにはhttp/1.1 と http/2の違いについて理解する必要があります。
簡単に説明すると、http/1.1ではリクエストを送りそのレスポンスが帰ってきてから次のリクエストの処理を行う所謂直列型のデータ転送プロトコルであったため、一度にまとめてリクエストを送くことで待ち時間を短縮していました。しかしこれにより一つのバンドルファイルに全てをまとめることが横行し、結果としてその大きなサイズのファイルが読み込まれるまで何も表示されないという事態を引き起こしていました。
http/2では接続上にストリームと呼ばれる仮想的な双方向シーケンスを作ることで複数並列でのリクエストの転送を行うことができます。これにより、一つのバンドルファイルに全てをまとめるのではなくバンドルファイルをいくつかの適切な大きさに分割することができます。
簡単にまとめましたがhttp/2では他の変更点もあるのでぜひドキュメントを読んでみてください。
preloadとは<link rel="preload" as="">
をhtmlドキュメントに置くことで初期URLに必要なリソース(cssや画像などレンダリングをブロックする要素)を事前ロードし描写速度を早くすることです。
開発者であれば初期描画に必要なリソースは把握しているはずなので優先順位の高いものをブラウザに伝えることでより早く初期描写を表示できます。
詳しくはweb.devの記事に載っているのでみてみてください。
R(render)
renderでは初期描写(First Paint)をなるべく早く表示させる方法について書かれています。
dev toolからlighthouseを用いればそのページのFirst Paintの速度を低下させている原因について警告を出してくれます。
light houseとは指定したページのパフォーマンス・アクセシビリティなどについて100点満点でスコアを表示してくれるdev toolの機能です。
webフロントエンドエンジニアなら知っておくべきだと思います。
こちらから使い方を知ることができます。
ここではFirst Paintの改善をするために
- 重要なJavascriptはinline化し残りはasyncをもちいて非同期で処理し、重要なcssをinline化しレンダリングをブロックする要素を極力少なくすること
- SSR(server side rendering)することで初期描画を早くすること
をあげています。しかし、SSRの場合は初期描画は早くなるものの、クリックなどへ反応することができるようになる時間(time to interactive)が伸びてしまう点で問題が生じます。
表示されてから操作できない時間が長い方がユーザーの離脱率は高くなると言われています。
P(pre-cache)
一度読み込まれたデータがservice workerにキャッシュされるため2度目以降のページの訪問時にはキャッシュしたデータが表示されます。
そのため2度目以降は表示が早くなる他に、オフライン時でもキャッシュが効いているところは表示が可能です。
L(lazy-load)
lazy-loadは遅延読み込みのことです、初期描写に必要のないリソースを遅延読み込みさせることで初期描写時に必要なリソースファイルのサイズを減少させ、速度を早くします。
画像の遅延読み込みについての記事
RAIL
RAILとはパフォーマンスモデルのことでR(response)、A(animation)、I(idle)、L(load)の略です。
R(response)
タップからイベントまで100ms未満
A(animation)
各フレームの処理16ms未満
I(idle)
メインスレッドのJS処理ブロックは50ms以内
L(load)
First Meaningful Paint まで1000ms以内
これらの数値はあくまで目標ですが達成することができれば素晴らしいユーザー体験のサイトであると言えます。
かなりきつい目標なのでほどほどにしつつ、個人的な意見ですがlight houseでオールグリーンなどが目標でも良いと思います。
計測ツールについて何があるか説明できる
計測ツールについて、私はchromeのdev toolしか知らないのでそれを紹介します。他にあれば教えてください。
network
タブではリソース取得の順番、それぞれのリクエストのステータスコード、通信の時間などを確認することができます。
さらに通信の環境を設定することができ、高速の回線ではなく3Gの回線での速度などを確認することができます。
詳しくはドキュメントを読みましょう。
performance
タブではデバイスの設定を変更することができ、CPUを変更することでモバイル端末使用時のパフォーマンスを確認することができます。
また、ボトルネックとなっている部分を目視で確認することができます。
詳しくはドキュメントを読みましょう。
Chrome Developer Toolsのどのタブで確認するか理解している
dev toolにはさまざまなタブがあります。
詳しく知りたい方はドキュメントを読みましょう
タブ名 | できること |
---|---|
elements | HTMLの構成やcssの適応状況を確認することができます。cssを直接指定して確認することができ、マークアップのときにはとても世話になります |
console | エラーメッセージなどが表示され、consoleコマンドの内容がここで表示されます、変数の中身のデバックで使うと思います |
sources | 構成ファイルがあります、エラーメッセージなどからエラー箇所に飛んだときにここに飛びます |
network | 上記したので省略します |
performance | 上記したので省略します |
memory | 名前の通りメモリの問題を見つけるためのタブです。メモリ使用量を時系列で確認することができ、メモリリークが起こっている場合の原因の特定が行えます |
application | ストレージやキャッシュなどの確認を行うことができます |
security | セキュリティの状態を確認することができます |
light house | performance、a11ly、Best Practice、SEOのスコアを確認することができ、スコアの改善方法を教えてくれます |
Resource Hintsを用いて実行・高速化できる
resource hintsにはDNS-Prefetch
、Preconnect
、Prefetch
、Prerender
の四つがあります。
それぞれ必要な数だけhead
タグ内に設置します。
DNS-Prefetch
DNS-Prefetchを使うと外部ドメイン名(ホスト名)の名前解決(DNSルックアップ)を事前に強制することができます。
ブラウザがドメインにアクセスする前に名前解決が済んでいるので読み込み時間を短縮することができます。
特にまとめサイトなどの外部リンクが多いサイトやソーシャルメディアのボタンを複数設置しているサイトでは有効な手だと思います。
<link rel="dns-prefetch" href="//example.com">
この場合example.com
というドメイン名についてあらかじめ名前解決を試みます。
詳しい情報はこちらのドキュメントにあります。
Preconnect
DNSルックアップ単体であればDNS-Prefetch
を使えばできますが
Preconnectを使うとDNSルックアップ
、TCPハンドシェイク
、TLSネゴシエーション
といったネットワーク接続に必要なことを事前に行うことができます。
<link rel="preconnect" href="//example.com">
<link rel="preconnect" href="//cdn.example.com" crossorigin>
クロスオリジンでpreconnectを行う場合は下の場合のようにcrossorigin属性が必要です。
詳しい情報はこちらのドキュメントにあります。
Prefetch
開発者であればページの動線がわかっているはずなので次にユーザーが訪れるであろうページがどこであるかは理解しているはずです、Prefetchを使うと指定したhtmlファイルやcssファイル、画像を事前に読み込んでおき、遷移時の表示を高速にすることが可能です。
<link rel="prefetch" href="nextpage.html">
<link rel="prefetch" href="//example.com/next-page.html" as="document" crossorigin="use-credentials">
<link rel="prefetch" href="/library.js" as="script">
詳しい情報はこちらのドキュメントにあります。
Prerender
Prerenderを使えば指定したファイルを読み込み描画まで行っておくことが可能である、これにより遷移してすぐにページが表示されることになる。
しかし、一度に指定できるのは1ページだけであり、Chromeのスレッド全体で1つのrel="prerender"しか指定することしかできない、そのため次にユーザーが訪れるページがほぼ確定しているような場合に使用するべきだと思う。
<link rel="prerender" href="//example.com/next-page.html">
詳しい情報はこちらのドキュメントにあります。
CDNを活用できる
CDNとはContent-Delivery-Networkの略でウェブコンテンツ配信用にネットワークを最適化することによって、アクセスが集中したりしてサーバーへの負荷が増加してもコンテンツの配信に影響が起こらないようにすることができます。
簡単にですが、具体的にはCDNではオリジンサーバーとユーザーとの間にオリジンサーバーからウェブコンテンツのコピーを取得、もしくは明示的にコンテンツを入れたキャッシュサーバーをはさみ、代理で配信することでオリジンサーバーの負荷を減少させています。
またCDNは世界中にキャッシュサーバーを置いているので、アメリカの企業がアメリカにサーバーを置いていたとしてもCDNを使用すれば日本のサーバーから
配信されるため日本にいる私たちでも早くアクセスすることができます、物理的な距離という面で速度を早くすることができます。
活用については私は一学生であり、CDNが必要なほどのサービス運営に携わったことがないため、主要なCDNの一覧を置いておきます。
どなたか知識のある方お力添えを。。。
Akamai、元祖です。
Fastly、日経新聞社さんが使用しているそうです。日経さんの速度改善の記事
Amazon cloudfront、天下のアマゾンです。
Cloudflare、こちらも有名ですね。
レンダリングブロックについて説明できる
レンダリングブロックとはブラウザの表示処理がcssファイルなどの読み込みによってブロックされることです。
ブラウザに表示が行われるためにはhtmlファイルがパースされる必要がありますが、表示するhtmlファイルに紐づくcss、jsファイルがある場合、それらもパースしてhtmlによって作成されたDOMに紐づける必要があり、これにより初期描画が遅れます。
もっと詳しいことが知りたければgoogleのドキュメントを読みましょう。
描写される順番について理解している
ブラウザのレンダリングはLoading
→Scripting
→Rendering
→Painting
の順で実行されます。
Loading
htmlファイル、cssファイル、jsファイル、画像がダウンロードされます。
htmlとcssをパースします。
Scripting
jsファイルを解釈してjsを実行し、抽象構文木を作成します。
Rendering
cssスタイルの適応とレイアウト算出を行います。
Painting
jsを適応して最終描画を行う。
HTML→CSS→JS→画像 の順で読み込まれます。
セキュリティ
安全なウェブサイトの作り方を参照できる
安全なウェブサイトの作り方を読みましょう
同一、クロスオリジンのそれぞれの違いが説明ができる
二つのページのプロトコル、ポート番号、ホストが等しい場合同一オリジンです。
以下MDNより参照
以下の表は、各行の URL が http://store.company.com/dir/page.html
と同じオリジンであるかを比較したものです。
URL | 結果 | 理由 |
---|---|---|
http://store.company.com/dir2/other.html | 同一オリジン | パスだけが異なる |
http://store.company.com/dir/inner/another.html | 同一オリジン | パスだけが異なる |
https://store.company.com/page.html | 不一致 | プロトコルが異なる |
http://store.company.com:81/dir/page.html | 不一致 | ポート番号が異なる (http:// は既定で80番ポート) |
http://news.company.com/dir/page.html | 不一致 | ホストが異なる |
XSSとは何かを説明できる
XSSとは(Cross Site Scripting)のことで、CSSでないのはCascading Style Sheets
と被るからだそうです。
ウェブアプリケーションに対する代表的な攻撃手段のことで、簡単にいうとユーザーがWebページにアクセスすることで不正なスクリプトが実行されてしまう脆弱性または攻撃手法
のことです。
不正なスクリプトを含むURLを踏ませることによって、その踏んだユーザーのブラウザで不正なスクリプトな実行され、Cookieなどからログイン情報などを抜き取られてしまうことが被害例として挙げられます。
多分大丈夫だとは思いますが、掲示板などの投稿型のウェブアプリケーションなどを運用している人は気をつけましょう
wanko5296さんの記事の図がわかりやすかったです。
対策方法についてコードベースで説明できる
<!-- 属性値を引用符で囲む -->
<!-- 良い例 -->
<input type="text" value="$data">
<!-- よくない例 -->
<input type="text" value=$data>
<!-- urlが投稿できる場合、事前にスキームをhttp、httpsであるかを確認する -->
if ($data !~ /^(http|https):/) {
エラー文
}
vue/reactそれぞれのフレームワークでのXSS対策のページがあったので共有します。
vue
react
ブラウザ側での脆弱性対策について理解している
対策の方法としてはフォームなどにスクリプトを埋め込むことができないようにすることです。
具体的な説明をすると
- 入力できる値を制限する(バリデートする)こと
-
&,<,>,”,’
といった文字をエスケープしてスクリプトを無害化すること
が挙げられます。
詳しくは安全なウェブサイトの作り方に全て載っています。
CSPとは何かを説明できる
CSPとはContent Security Policy
の略で、該当するウェブページについてContent-Security-Policy
HTTPヘッダーを返すように設定し、実行を許可するスクリプトの正しいドメインをブラウザーに向けて指定することによりXSSの発生する箇所を削減・根絶することができます。
もう少しいうと、HTTPヘッダーやmetaタグを設定すだけで などのインラインスクリプト、onclick="~" などのイベントハンドラ、href="javascript:~" や eval() によるスクリプト実行が禁止され、実行するスクリプトファイルも許可されたものだけにできます。
詳しいことはMDNにあります。
SameSite Cookieについて説明できる
SameSite CookieとはCookieの送信を制御するSameSite属性の仕様のことで、「現在のドメイン」から「遷移先ドメイン」へCookieが送信されるのを制御することです。ドメインをまたぐリクエストに対してCookieを自動付与しないようにすることで、安全性の向上につなげていきます。
これにより「偽装されたリクエスト」に対してCookieを送らなくなるので、CSRF(Cross Site Request Forgeries)」や「Timing Attack」への対策となります。
MDNです。
npmモジュールの脆弱性をチェックをする方法を知っている
まずは脆弱性を調べたいプロジェクトに移動してnpm audit
をします。
そうすると
こんな感じで脆弱性のあるパッケージについて表示してくれます。
high
moderate
low
の三つのレベルがあってhigh
moderate
は解消した方が良いです。
npm audit
にはnpm audit fix
というコマンドもあり、大抵の脆弱性は自動で解消してくれます。
治らない脆弱性は手動で直す必要があります。
hibikikudoさんの記事を読むのをお勧めします。
npmのモジュールの問題で動かなかった場合の個人的な解決法
まず
-
npm audit
で脆弱性がないかを確認して -
npm outdated
でバージョンが古すぎていないかを確認するようにしています、古かったら依存関係に注意しながら更新します。
大体これで直ります。
依存関係の場合とかだとエラー文で探したらgithubのissueとかが出てきて解決したこともあります。
それ以外だとグローバルに変なのが入っている(グローバルにnode module
がある)、vscodeのバージョンが古すぎて言語のバージョンがずれてるとかが自分が過去経験しています。
デザインツール
デザインツールに関してですが、ほとんど参考リンクを貼るだけになってしまいました。
プロダクトのデザインツールで何が使われているか理解している
デザインツールに何が使われているかはチーム、会社によって異なると思いますが、AdobeXDやSketch、Figmaが多いと思います。
わからない場合は確認しておきましょう。
ここから先はデザインツールごとの話になるので、上記したデザインツールを使用したことがない方はどれか一つを選んで使い方を練習してみるといいと思います。
(すでに作成してあるウェブアプリケーションのデザインを作成してみるなど)
私自身sketchを使用したことがないですが、AdobeXDもFigmaも無料で使用することができるので一度触ってみることをお勧めします。
画像の書き出し方について理解している
それぞれのツールごとにやり方があります。
AdobeXDでのやり方
Sketchでのやり方
Figmaでのやり方
2倍や3倍の解像度書き出し方が分かる
ディスプレイによって解像度が異なります、例えば最新のmacbookなどはretinaのディスプレイで解像度が高いです。
このような解像度の高いディスプレイではきちんと対応しないと画像がぼやけてしまいます。
その対応のために解像度を2倍、3倍で書き出す必要があります。
AdobeXDでのやり方
Sketchでのやり方
Figmaでのやり方
un-Techさんの記事が解像度についてわかりやすかったです。
アイコンの場合、SVGにて抽出できる方法を知っている
SVGはScalable Vector Graphics
の略で利点としては、GIF
PNG
JPG
のようなビットマップ画像ではなくベクター画像なので画像を拡大しても粗くなりません。
そのため上記したような解像度の対応は必要なくレスポンシブの対応をしても一つのファイルで対応できます、しかしベクター画像は計算式によって画像を表現しているため、写真などの多くの色を使うものには不向きです。
なのでアイコンなどのあまり多くの色を使わない際に使われます。
また写真のように色を変える際にわざわざデザインツールを通さなくてもcss上で色を変更することが可能です。
AdobeXDでのやり方
Sketchでのやり方
Figmaについては上記したURLと同じです。
CSSを抽出できるものの場合、どこから確認すればいいか理解している
おそらくAdobeXDしかできない?と思うのでXDのリンクを貼っておきます
AdobeXDの場合
スポイトツールで色の抽出ができる
スポイトツールを使うと他の部分で使われているカラーコードを取得することができます。
AdobeXDでのやり方
Sketchでのやり方
Figmaでのやり方
要素間の空きや余白がどれくらいあるか確認することができる
全てのツールで同じだと思いますが、始点としたいオブジェクトを選択した状態で、比較したい要素をホバーすると間がピクセル数で表示されます。
rem
やem
を使っている場合は別途計算が必要ですが、ピクセルパーフェクトが求められる場合はこれがわかっていればcssを書くのがとても楽になります。
画像
ベクター画像とビットマップ画像の違いを説明できる
SVGのところでも説明しましたが、ベクター画像は点と線を数値化しそれを計算式によって画像にしているため、拡大したりしてもそれに応じて計算式の結果が変動し画像が粗くならないです。
一方で写真などの多くの色を使うものには不向きでアイコンなどに用いられることが多いです。
ビットマップ画像は点の集まりで構成される画像のことで点の集まりであるため拡大すると点の細かさに限界がきて画像が粗くなります。
一方できめ細やかな色表現を行うことができ、写真などは全てビットマップ画像です。
各画像圧縮方式についてざっと説明できる
圧縮は、非可逆圧縮と可逆圧縮の2種類があります。
非可逆圧縮
圧縮前の状態に戻すことができない圧縮方法です、つまり圧縮済みのファイルを解凍しても圧縮前の状態に戻すことができないです。
データの一部を除去します。画質が悪化する為、画像をどれだけ圧縮するかに注意する必要がありますがファイルサイズは大幅に減らすことができます。
可逆圧縮
圧縮前の状態に戻すことができる圧縮方法です、つまり圧縮済みのファイルを解凍することによって圧縮前の状態に戻すことが可能です。
データを圧縮します。画質が悪化しませんが、レンダリングする前に画像を圧縮解除する必要があります。
詳しい説明は省きますが、オリジナルの画像だとファイルサイズがとんでもないことになってしまうので圧縮は必須です。
きちんと圧縮してから画像は使うようにしましょう。
JPG, GIF, PNGの拡張子それぞれの特徴について説明できる
JPG
JPG(ジェイペグ)はJoint Photographic Experts Group
の略で名前の通り写真に適した画像形式です。
ファイルサイズが小さくても綺麗に写真を写せます。一方で非可逆圧縮を使用しているため上書き保存するたびに画像が粗くなります、さらに背景を透明にすることができないです。
似たような拡張子にJPEGがありますが、違いはないです、JPGの方がよく使われているのでどちらかに統一する場合はJPGに統一しましょう。
GIF
GIF(ギフ)はGraphics Interchange Format
の略でアニメーションでよく使われている画像形式です。
データ容量がとても小さく、背景を透明にすることも可能ですが、色を256色しか使用できません。ロゴやイラスト、アニメーションに使われます。
PNG
PNG(ピング)はPortable Network Graphics
の略でGIFが特許問題で自由に利用ができなくなった際に専門家達によって作成されました。
JPG、GIFの問題点を解消するために生まれたので高画質の画像を生成し、透過、画像の劣化にも対応しており、GIFの問題点であった256色しか使えないという問題点も解消していますが、ファイルサイズが大きくなってしまいます。
普通の写真はJPG
ロゴやアイコンはSVGかGIF
高画質な画像を使いたい場合、写真だけど背景を透過させたい場合はPNG
などと使い分けられると良いと思います。
WebPを用いることのメリットについて説明できる
WebP(ウェッピー)はGoogleが開発している新たな画像フォーマットです、2010年ごろからあるらしいです。現在IE以外の主要ブラウザは対応しています。
WebPを用いることのメリットは非可逆圧縮であるにもかかわらず透過させることができる点です。つまり透過画像をWebPで書き出せます。
またファイルサイズを非可逆圧縮であるJPGより小さくすることができます。(25%~34%小さくできるそうです)
WebPへの変換方法についてはGoogleが提供しているcwebpがあるのでこちらを使うと良いと思います。
レスポンシブデザイン
レスポンシブデザインにする必要について説明できる
ユーザーがページを閲覧する際に使用する端末として、パソコン(ラップトップ、デスクトップ)、モバイル、タブレットが挙げられますが、レスポンシブ対応をすることによってパソコンのユーザーとモバイルのユーザーのためにわざわざ別ページを用意したりする必要がなくなります。
また現在のブラウザなどへのアクセスはスマートフォンなどのモバイル端末の普及率の高さからも無視できる量ではないですし、むしろそちらからのアクセスの方が多い可能性まであります。
この辺はGoogle Analyticsなどを導入していればどの端末からのアクセスが多いのかを理解できると思います。
もしスマホからアクセスした時にPC用のページが出てきてブラウザバックされてしまうととても勿体無いです。
この辺りのユーザーを取り込むためにレスポンシブデザインにする必要があります。
もちろんユーザーが100%パソコンからのアクセスなどであるのならば対応する必要はないです。
中間幅についての挙動を考慮した提案ができる
中間幅というのは例えばスマホとタブレットの間の中途半端な画面サイズなどの時の話です。
この記事が全てだと思います。この記事を読んで実践するべきです。
Thinking About The In-Between Design Cases
日本語訳されているものがあるのでこちらも貼っておきます。
日本語訳版
どのブレイクポイントがあるとよいか理解して説明できる
ブレイクポイントはレスポンシブの境界です、例えば767px以下はスマホ用の画面など
@media (max-width: 767px) {}
これはどの端末のユーザーに向けてサービス・ページを作成しているかに依るのでひとくくりにはなんとも言えないです。
個人的には
- ラップトップ 1080px ~
- タブレット 429px ~ 1079px
- モバイル ~ 428px
です。
もちろん私の経験が足りていないことは百も承知なので意見があればいただきたいです。
Hashimotoさんの記事がとても勉強になりました。
特に一覧をまとめたPDFがとてもわかりやすかったです。
OSS
セマンティック バージョニングにおいて各数字が何であるか理解している
セマンティック バージョニングにおいては major.minor.patch
とします。
APIをすでにプロダクションとして提供しているのであれば1.0.0
からはじめれば良いと思います。
major
APIの変更に互換性のない場合はメジャーバージョンをあげます。
major番号が0のものは開発段階を指し、この時はどの数字が上がっても後方互換性はないです。
minor
後方互換性があり機能性を追加した場合はマイナーバージョンをあげます。
patch
後方互換性を伴うバグ修正をした場合はパッチバージョンを上げます。
rc
rcはrelease candidate
のことで最終確認バージョン(プレリリース)のことです。
例えばcomposition-api
は@vue/composition-api": "^1.0.0-beta.22
となっています
プレリリースは、通常バージョンより低いバージョンです。
1.0.0-beta.22
< 1.0.0
となります。
プレリリース文字列にも順番があります。
1.0.0-alpha
< 1.0.0-beta
< 1.0.0-beta.2
< 1.0.0-RC
< 1.0.0
composition-api
のバージョンがbeta.22
となっているように2までというわけではないです。みたことないですがgamma
とかもあります。
なぜセマンティックバージョニングを使用するのかは読むべきです。
ライセンスの有無を理解している
GitHubなどで新しくリポジトリを作る時にライセンスファイルを作るかどうか選べると思います、あれです。
ライセンスに則った使用をしている
年末にTatamoさんの記事が上がっていたのでこれがとてもわかりやすかったです。
使用しているバージョンがEOL(End of Life)かどうかを確認できる
witchcrazeさんの記事がよかったです。
EOLになる場合のアップデート対応や方針などを説明できる
EOLになってもその日付にサービスが終了するわけではありませんが、その後に発生するエラーやセキュリティの脆弱性などへの対策が行われなくなります。
アクシスさんの記事がEOLについてまとまっていてよかったです。
場合によってはIssueやPull Requestなどで提言できる
おそらくみなさんGitHubは使ったことがあると思うのですが、リポジトリのIssueにエラーの報告を行ったり、自分で発見したエラーを解決するPull Request(以下PR)やすでにバグとして挙げられているIssueを解決するPRを出すことで自分の使用しているライブラリやフレームワークに貢献することができます、
このZennでもIssueをたてるところがあるのでもしよければ活用してみてください。
Zenn Roadmap
運用している場合、どのようにメンテナンスしているか説明できる
運用していないので全くわからないです、どなたか助けてください。
よくあるライセンスの種類について知っている
ライセンスごとのコンテンツの利用制限について知っている
全然知らなかったのでloveeさんの記事を参照します。
ライセンスの種類としては
copyleft系
permissive系
があります。
copyrightが権利という意味なのでそれに反する(自由にして良い)という意味でcopyleft、それに寛容という意味のpermissiveという言葉で系統があります。
copyleft系の代表的なライセンスにGPLがあります
GPLライセンスの特徴としてはGPLライセンスで配布されているOSSを改良したりしてそれを公開する場合は必ずGLPライセンスで配布しなければなりません
permissive系の代表的なライセンスにBSD、MIT、Apacheがあります。
permissive系のライセンスはcopyleft系と異なり、permissive系のソースコードを改変して公開する場合にも必ず元のライセンスと同じもので公開しなければならないというような制限はありません。
BSDライセンスはライセンスの原文を手動で一部(年数と著者)を変更しなくてはならないようです。
MITライセンスはBSDと違って手動で変更する必要がありません
Apacheライセンスは上記のふたつと二次改変についての制限は同じですが、ゆるすぎたために企業にとって逆に使いにくいという状況になったそうです。
その点で特許や商標に関してだけ制限をかけることができるのがApacheライセンスです。
最後に
二週間ぐらいかかりましたが、一応書き終わりました。
かなり自分で調べる中で勉強になることが多かったです。
どなたかバックエンド版で書いてくれないかな〜〜〜〜〜〜