あーさーの備忘録

ゆっくり自由に生きてます

CSSだけで実装したタブは本当に"軽い"のか?

はじめに

どうもご無沙汰しております。あーさーです。ここのところ体調が優れず実家に帰って引きこもり中です。夏休み始まってすぐの検診もあまり数値が良くなかったので、例年にも増しておとなしく夏休みを過ごしています。いや、こんな退屈な夏休みなら早く終わってほしいですね。3Qが待ち遠しいです。

さて今回は、今までFuelPHPの話ばかりしてきたので、話題を少し変えCSSの話をしようと思います。と、その前にPRを。

【PR】受験生応援サイトを公開

goukaku.jizi.jp

私が所属する某実行委員会の某局で受験生応援サイトを作りました。私はデザインとフロントコーディングを主に担当しました。今までサーバーサイドでゴニョゴニョやっていたことが多かったので色々新鮮な感じで製作させていただきました。

実はこのサイト、一見普通のサイトに見えますが、1つ特徴的なことがあります。それは「Javasciptを使っていない」ということです。いや、正確に言うとGoogle Analyticsのコードがあるのですが、それ以外のページのコンテンツにはJavascriptを使っていません。メニューの動きやタブの切り替え、マテリアルデザインのfabチックなボタン、すべてがCSSだけで実装されています。

いきなりPRを挟んで申し訳ありません。ただ、何の気なしにPRを突っ込んだわけではありません。今回のテーマは、「CSSだけで実装したタブは本当に"軽い"のか?」です。このサイトで行われている、「Javascriptを使わない」取り組みが果たして正しいのかどうかを検証していきます。

jQueryでタブを実装する方法

と、その前に、まずはjQueryを使ったオーソドックスな方法でタブの切り替えを実装する方法をご紹介します。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test1</title>
<style>
.is-hidden {
    display: none;
}
</style>
</head>
<body>
<ul>
    <li id="tab1">TAB 1</li>
    <li id="tab2">TAB 2</li>
    <li id="tab3">TAB 3</li>
</ul>
<div>
    <div id="content1">CONTENT 1</div>
    <div id="content2" class="is-hidden">CONTENT 2</div>
    <div id="content3" class="is-hidden">CONTENT 3</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(function(){
    $('#tab1').on('click', function(){
        $('#content1').removeClass('is-hidden');
        $('#content2').addClass('is-hidden');
        $('#content3').addClass('is-hidden');
    });
    $('#tab2').on('click', function(){
        $('#content1').addClass('is-hidden');
        $('#content2').removeClass('is-hidden');
        $('#content3').addClass('is-hidden');
    });
    $('#tab3').on('click', function(){
        $('#content1').addClass('is-hidden');
        $('#content2').addClass('is-hidden');
        $('#content3').removeClass('is-hidden');
    });
});
</script>
</body>
</html>

他にもいろいろなやり方があると思いますが、詳しくはGoogle先生に聞いてください。show()hide()よりもCSSのクラスの付け外しのほうが若干軽いとか。li#tab[n]を押すと、対応するdiv#content[n]が表示されます。[n]には1~3の数字が入ります(属性セレクタと混同するような表記をしてしまい申し訳ありません)。

CSSだけでタブを実装する方法

次に、CSSだけでこれを行う方法です。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test1</title>
<style>
.tab-input {
    display: none;
}
#content1, #content2, #content3 {
    display: none;
}
#radio1:checked + #content1 {
    display: block;
}
#radio2:checked + #content2 {
    display: block;
}
#radio3:checked + #content3 {
    display: block;
}
</style>
</head>
<body>
<ul>
    <li id="tab1"><label for="radio1">TAB 1</label></li>
    <li id="tab2"><label for="radio2">TAB 2</label></li>
    <li id="tab3"><label for="radio3">TAB 3</label></li>
</ul>
<div>
    <input type="radio" name="tab-input" class="tab-input" id="radio1" checked>
    <div id="content1">CONTENT 1</div>
    <input type="radio" name="tab-input" class="tab-input" id="radio2">
    <div id="content2" class="is-hidden">CONTENT 2</div>
    <input type="radio" name="tab-input" class="tab-input" id="radio3">
    <div id="content3" class="is-hidden">CONTENT 3</div>
</div>
</body>
</html>

どのタブが選択されているかを、非表示にしたラジオボタンの値で保存することで実装しています。クラスを使えばCSS部分がもっと短く書けるはずなのですが、jQuery版との対応を取ってidセレクタを使用しています。idセレクタは詳細度が大きいのでできれば使いたくないんですがね。ついつい#hoge[id="hoge"]と書き直したくなってしまいます(idセレクタを属性セレクタに置き換えることで詳細度がクラスレベルまで下がります)。

ページの読み込み速度

jQueryで実装したものとCSSだけで実装したものと、どちらが"軽い"か。まずは、ページの読み込み速度を測って検証します。検証には、私のPCのGoogle Chrome(60.0.3112.90)の開発者ツールを利用し、ローカルに保存したhtmlファイルをスーパーリロードで10回読み込み、平均値を取ります。

試行回数 jQuery CSS
1回目 80 16
2回目 83 16
3回目 89 16
4回目 84 17
5回目 74 17
6回目 83 16
7回目 81 17
8回目 77 17
9回目 89 16
10回目 81 16
平均 82.1 16.4

(単位:ms)

CSSのほうがjQueryを読み込まない分速いですね。通常jQueryはキャッシュされるので、それを考えるとCSSだけで実装した場合との違いはほとんどないようです。

再描画までの時間

次に、クリックしてからレイアウトを再計算して描画するまでの時間を計測します。先ほどと同じ条件で、Google Chromeの開発者ツールの「Performance」を利用しました。

結果だけ言いますとどちらも0.00msでした。目立った違いもないようです。アニメーションとかつけたら変わるのでしょうか。

そもそもこの比較は実験として成立しているか

こんな小学生の夏休みの自由研究のような記事を書いてしまい申し訳ございませんでした。実験の基本は対照実験。比べたいもの以外の条件の同じにしないと比較しようがないのですが、果たして本当に対照実験になっていたんでしょうか。計測の方法は正しかったのでしょうか。Javascript同士のベンチマークはいろいろ記事が上がっているので分かりますがCSSと比べるっていうのは私にはよく分かりませんでした。まぁ、ただ得られた結果としては、特にパフォーマンスの違いがない以上、jQueryを読み込まなくて良いCSSのみの実装の方が良い、ということで。次回は.mailfilterを使って、メールをトリガーとして動くプログラムの解説をします。それでは。