HTMLInspectorとCSSLintとJSHintと試すリポジトリ。
サンプルコードはライセンスありません。 その他Grunt、HTMLInspector、CSSLint、JSHint等はそれぞれに準じます。
ダウンロードしてインストールする。黒い画面でgit
コマンドが使えるようになる。
ダウンロードしてインストールする。黒い画面でnode
とnpm
コマンドが使えるようになる
$ npm install -g grunt-cli
黒い画面で実行し、インストールする。grunt
コマンドが使えるようになる。
リポジトリをクローンしてきて、そのリポジトリに移動する。
$ git clone git@github.com:1000ch/brushup-sample.git
$ cd ./brushup-sample
package.json
に定義してある依存モジュールをnpmでインストールする。grunt
とかgrunt-contrib-jshint
等がダウンロードされる。
$ npm install
通常は以下のコマンドを実行して、html/css/jsが保存等される場合にそれぞれにチェックがかかるようになっている。
$ grunt [watch]
これはgrunt-contrib-watch
モジュールを使って実現しており、設定はgruntfile.js
の12行目から25行目に書いてある。今回は各タスクを別途実行して、HTML/CSS/JSそれぞれを修正していく。
このリポジトリのファイルのcssファイルやjsファイルをCSSLintやJSHintに貼り付けて実行してみてください。
grunt-html-inspector
モジュールを利用して、設定はgruntfile.js
の3行目から5行目に書いてある。
$ grunt html-inspector
The 'bgcolor' attribute is no longer valid on the
<body>
element and should not be used.
<body bgcolor='#fff'>
bodyタグにbgcolor
が付与されているが、使われるべきではない。文書構造をHTMLで定義し、ページの装飾をCSSで行う。
body {
background: #fff;
}
The class 'hoge' is used in the HTML but not found in any stylesheet.
HTML中にhoge
というクラスが使用されているが、CSS中にその定義が存在していない。JSでgetElementsByClassName
する場合等は別だが、CSSの参照コストがかかるので定義されていないクラスは指定しない。
Do not use
<div>
or<span>
elements without any attributes.
CSSのスタイリングや属性値が持たない<div>
や<span>
は、必要ないはず。HTMLでのネストを深くすることで様々な参照コストを上げる可能性があるので、避けること。
必須とされている属性は付与すること。<img>
については、 srcを空にしない 、 widthとheightを指定する ことも忘れずにやること。
<img>
等のsrc=''
、<a>
や<link>
のhref=''
を空文字で指定すると、無駄なHTTPリクエストが発生してしまうブラウザがある。
それによってパフォーマンスが低下するだけでなく、セッションの管理のためにトークン等を利用している場合はリクエストによってトークンが更新されてしまい動かなくなってしまう可能性もある。また、width
とheight
を指定することでHTMLの解析時に<img>
の占める領域が決定するため、画像のダウンロード後に発生する再レイアウトを予防することが可能。
The
<font>
element is obsolete and should not be used.
HTMLは文書構造の定義、CSSは装飾という分離をするため、<font>
タグは非推奨になった。同様の理由で<center>
や<basefont>
等も非推奨である。
An 'onclick' attribute was found in the HTML. Use external scripts for event binding instead.
<button id='#js-button' onclick='alert(0)'>ボタン</button>
HTMLのインラインでイベントを定義するべきではない。管理が非常に難しく、予期しない不具合を起こす可能性がある。
<button id='#js-button'>ボタン</button>
HTMLにはJSから参照するIDやクラスをふっておき、
document.getElementById('js-button').addEventListener('click', function() {
alert(0);
}, false);
JS中でこのようにクリックイベントを定義する。
<script>
elements should appear right before the closing</body>
tag for optimal performance.
<script>
タグは同期的に解決されるため、<head>
タグの中に配置されていたりすると<body>
タグの解析が始まる前に実行されるため、その間ページが白い画面になってしまう可能性がある。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<link rel="stylesheet" href="css/import.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="js/app.js"></script>
</head>
<body>
<div class="outline hoge">
<header></header>
...
</div>
</body>
</html>
</body>
タグのすぐ上部に配置することで、それを避ける事が可能である。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
<link rel="stylesheet" href="css/import.css">
</head>
<body>
<div class="outline hoge">
<header></header>
...
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
<script>
タグを<head>
の中に配置してはいけないわけではない。
<body>
の評価より先にされなければならない場合(例えば要素をJSでゴリゴリ作るとか)はそうするべき。
grunt-contrib-csslint
モジュールを利用して、設定はgruntfile.js
の6行目から8行目に書いてある。
$ grunt csslint
Values of 0 shouldn't have units specified. You don't need to specify units when a value is 0.
値が0の場合はpx
をつけようが%
をつけようが0に変わりないので、除く。
.outline {
margin: 0px auto;
min-width: 320px;
max-width: 960px;
}
数文字減った所でファイルサイズが大幅に減るわけではないが、気をつけておいて損はない。
.outline {
margin: 0 auto;
min-width: 320px;
max-width: 960px;
}
Element (a.active) is overqualified, just use .active without element name. Don't use classes or IDs with elements (a.foo or a#foo).
a.active
は不要に詳細度が増しているセレクタである。.active
にすることで他のタグにも適用することが可能になる。更に具体的には
ul.nav li.active a {}
div.header a.logo img {}
.main ul.features a.btn {}
このように記述していると、<img>
を<div class='header'><a class='logo'>
に入れなければスタイルが適用されないし、.btn
も名前から察するに単独で使用可能なクラスであるべきだろう。
.nav .active a {}
.logo > img {}
.features-btn {}
こうすることで<ul>
を<ol>
に変えてもスタイルが反映されるし、.features-btn
も様々なタグで使用可能になった。
The properties padding-top, padding-bottom, padding-left, padding-right can be replaced by padding. Use shorthand properties where possible.
ショートハンドで記述可能な場合は、ショートハンドで記述することで冗長な表現を避ける事が出来る。
.foo {
margin-top: 10px;
margin-right: 20px;
margin-bottom: 10px;
margin-left: 20px;
}
.bar {
margin-top: 5px;
margin-left: 15px;
margin-bottom: 10px;
margin-right: 15px;
}
これは以下のように記述可能である。
.foo {
margin: 10px 20px;
}
.bar {
margin: 5px 15px 10px;
}
ショートハンドで記述可能なプロパティはmargin
やpadding
の他にもlinear-gradient
やborder
などがあるが、可読性を保った範囲で行っていく。
@import prevents parallel downloads, use instead. Don't use @import, use instead.
import.cssで以下の記述を行っているためである。
@import url("reset.css");
@import url("app.css");
@import
は直接にCSSファイルを解決するため、並列ダウンロードが可能な<link>
タグを複数書くことで描画開始までを速くすることが可能である。
<link rel='stylesheet' href='reset.css'>
<link rel='stylesheet' href='app.css'>
更に良いのは、予めreset.css
とapp.css
を結合しておくことでHTTPリクエストの数を減らすことが可能である。
grunt-contrib-jshint
モジュールを利用して、設定はgruntfile.js
の6行目から8行目に書いてある。
$ grunt jshint
evalで評価された文字列のJavaScriptは、スコープがわかりにくい上にパフォーマンスが低いため使うべきではない。
setTimeout(eval("alert('アラート')"), 0);
ではなく
setTimeout(function() {
alert('アラート');
}, 0);
同等の処理をこのように記述することが可能。
セミコロンが抜けているのと、オブジェクトの初期化にはリテラル({}
)を使ったほうが良い。
var sampleObject = new Object();
ではなく
var sampleObject = {};
と書いたほうが良い。初期化に関しては後述の、配列の初期化と同様の理由である。
オブジェクトに続いて、配列の初期化もリテラルを使った方がよい。
var sampleArray = new Array();
ではなく
var sampleArray = [];
と書いたほうが良い。 短く簡潔に書けるということと、コンストラクタを使うケースは引数の取り方がわかりにいので、思わぬ不具合を招く場合がある。
厳密等価演算子(==
ではなく===
、!=
ではなく!==
)を使用するべき。
if(sampleObject != null) {
}
ではなく
if(sampleObject !== null) {
}
と書いたほうが良い。 等価演算子は内部的に型を変換しているため、低速であり評価のされ方で誤解を招く場合がある。厳密等価演算子は型変換がない分高速である。