まばたきよりも速くしたい!

静的なプロフィールページを高速化する試みを綴ります。
極めている方からしたら止まって見えるほど遅いかもしれませんが...
簡単に、そしてそれなりに高速化できたので共有します:clap:

出来たページ → rigani's profile

最初に計測結果です。

webpagetest

計測結果

Load Time First Byte Start Render Speed Index
0.192s 0.131s 0.233s 233

Document Complete

Time Requests Bytes In
0.192s 1 6KB

Fully Loaded

Time Requests Bytes In
0.107s 1 6KB

PageSpeed Insights

計測結果

モバイル/パソコン 共に100点:grinning:
Good 100/100

それでは!以下が私のやったことです:airplane:

リクエスト数を極限まで減らす

CSSはstyle属性やstyleタグで設定

複数箇所で使う場合はstyleタグに、要素固有のスタイルはstyle属性で設定してしまいましょう。
style属性で設定する場合はセレクタでの捜索が発生しないので、ごく僅かながら速くなると思います。

<body style="margin:2px 0 0;padding:3vh 0 5vh;background:#fffdfd;font-family:'Yu Gothic',YuGothic,sans-serif;font-size:15px;font-weight:500;font-feature-settings:'palt';letter-spacing:.08em">

画像はbase64で埋め込む

こことかでデータURIスキームに変換してhtmlに埋め込みます。
複数箇所に使う画像の場合はCSS変数でbackground-imageに設定すればファイルサイズ削減できますね!

あっfaviconもリクエストされてる:tired_face: どうしようこれ...
(svgをbase64化して埋め込みました。対応ブラウザ少ない)

JSはasync/deferで読み込む

「ていうかjs使うのやめよう!」となってページから取り除きましたが、一応書いておきます。
どちらもscriptタグで使える非同期での読み込み指定ですが、実行のタイミングが異なります。
詳しくは以下のクールなまとめを見てください:pray:
script タグに async / defer を付けた場合のタイミング

1byteでも軽くする

無駄なコードを削除

minifyしてくれるツール使えばいいと思いますが、いい機会なので手動でやりました。
ツール用意するのがめんどくさかった

CSSの最小化

以下のCSSを最小化してみます。

何もしてないCSS
#l li {
  margin: 0 0.7em;
  list-style: none;
}
  • 最終行のセミコロンを削除
  • コロン後のスペースを削除
  • 小数で整数部が0の場合は削除
  • セレクタとカッコの間のスペースを削除
最小化後
#l li{margin:0 .7em;list-style:none}

HTMLの属性間のスペース削除

W3Cのチェックで怒られたのでちゃんと空けるようにしましたが、一応書いておきます。
htmlは属性間のスペースを取り除いても表示はできます。

<meta name="viewport"content="initial-scale=1">

あとは改行を消したらminify完了!

画像を最適化する

「ていうか普通のラスター使うのやめよう!」となってページから取り除きましたが、一応書いておきます。
GuetzliやMozjpegなどのエンコーダを使います。
見た目にほぼ影響を与えず、画像サイズをごそっと小さくできるかもしれません。
先人がとても良いまとめをしてくださっていたので、共有です。
GuetzliとMozjpegは、どっちが高性能か。

ぼかし画像等は極小サイズで用意して引き伸ばして使う

4x4とかの極小サイズ画像を引き伸ばして使います。
少しぼかすとそれっぽくなるかも

filter: blur(3px);

imgに下記のスタイルを指定すると、ぼかされずにピクセルを保ったまま拡大してくれます。すごいね

image-rendering: pixelated;

私が使ってるのこれ → l.gif

アイコンはSVGで描く

Webページ表示速度において足を引っ張りがちなラスター画像を、ベクター画像に置き換えてみましょう。
SVGでもコードを短く書くことを意識すると、びっくりな軽さになります。
このVueアイコンは167バイトです! やったね:)
(htmlに埋め込む場合はxmlnsが不要なので132バイト!)

Vueのロゴ

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0,0,40,35">
  <path d="M8,0h8l4,7l4-7h8L20,21" fill="#35495d"/>
  <path d="M0,0h8l12,21L32,0h8L20,35" fill="#41b883"/>
</svg>

そこのお前!ラスター画像に含まれるデータ量はベクター画像N枚分だぜ!

この記事が神でした
精度を保ってSVGを1バイトでも小さくする

圧縮して配信する

gz形式で配信することによってファイルサイズを抑えます。
gzipコマンドでgz形式に変換できます。

gzip -c 対象ファイル > 保存ファイル

このまま配置しても正しく読み込んでくれない(と思う)ので、メタデータを設定します。
(以下はAWS S3での設定です)
S3でのメタデータ設定。Content-Encodingをgzipに、Content-Typeをtext/htmlに設定している。

アップするたびに設定するのめんどくさい...
CLI使ったら自動化できるかな?

CDNを使う

今回はAWSのS3とCloudFrontの組み合わせを使いました。
最も効果があったと思われる点ですが、手順を説明すると非常に長くなってしまうため割愛します:rolling_eyes:
CDNもパフォーマンス比較してみて、これ!ってところを見つけるといいかもです。
CDNPerfで比較できます。
https://www.cdnperf.com/

なんだか日ノ本の外では動的な?マルチCDN?が芽を出してるとかなんとか。
私が知らないだけで日本でも流行ってるのかもしれないですが:flag_jp:

おわりの言葉

という感じで、惜しくもまばたき*には負けてしまいましたが、想定していたよりも簡単に高速なWebページを作ることができました。
そろそろツイフィールから乗り換えてみようかなって方は是非試してみてください:wave:

*1回のまばたきの速さは平均で100 - 150ミリ秒だと言われている。Wikipedia | まばたき

Webフロントエンド表示速度、最速化手法まとめ
↑参考になりました〜!

[雑感]
大洗女子の制服とVue、似過ぎ:thinking:

2922contribution
<meta name="viewport"content="initial-scale=1">

ですが、viewportの周囲の引用符を省略して<meta name=viewport content="initial-scale=1">とすれば、HTML5としての文法上の問題なくさらに1バイトを削れます。

引用符で囲まれない属性値構文
0個以上の空白文字が続き、1つのU+003D EQUALS SIGN文字が続き、0個以上の空白文字が続き、属性値に対する上記の要件に加えて属性値が続く、属性名は、任意のリテラルに空白文字、U+0022 QUOTATION MARK文字(")、 U+0027 APOSTROPHE文字(')、"="(U+003D)文字、"<"(U+003C)文字、">"(U+003E)文字、またはU+0060 GRAVE ACCENT(`)文字を含んではならず、かつ空文字列であってはならない。(HTML5の和訳より)

456contribution

@jkr_2255
な、なんと!!非常に面白いですね:flushed:
大変勉強になります。早速本文で紹介させていただきます
コメントしてくださってありがとうございました!