2021-02-02
Cyber AgentのWeb Speed Hackathon Vol.2に参加するのでフロントのパフォーマンスチューニングを少し勉強しました。(執筆時は未参加)
今回はLight House v6の指標についてまとめました。
web.devの内容をなぞっていきます。
LightHouse 6は以下の6つの指標に基づいて測定される。()の数値は重視される比率。
weight: 15%
FCP measures how long it takes the browser to render the first piece of DOM content after a user navigates to your page.
ユーザーがページに訪れた際に最初のDOMがレンダリングされるまでにかかる時間。
→ 対応:
font-display: swap
を追加 <link rel="preload" href="/assets/Pacifico-Bold.woff2" as="font" type="font/woff2" crossorigin>
weight:15%
Speed Index measures how quickly content is visually displayed during page load. どれだけ速く、ページが視覚的に表示されるか。
.box:nth-last-child(-n+1) .title { /* styles */ }
MinificationとData Compressionをしよう。
Minification
CSS,JSなどのコードファイルのminifyをしろ。(webpack v4以降なら自動でやってくれるからいらないよ👍)
Data Compression
サーバー - クライアントのデータのやりとりを最適化しよう。GzipもしくはBrotliで。BrotliはGzipよりいいよ。
ブラウザへ送るファイルを圧縮するには Dynamic
と Static
の2通りのやり方があるよ。どちらも一長一短だよ。
Dynamic comporession
リクエストが来た時にファイルを最適化するよ。手動で最適化したり、ビルド中にするより簡単だよ。けど圧縮率(?)が上がると遅延が生じるよ。
expressではcompression middlewareライブラリを使えば静的ファイルをgzip
でdynamic compressionできるよ。
const express = require('express');
const compression = require('compression');
const app = express();
app.use(compression());
app.use(express.static('public'));
const listener = app.listen(process.env.PORT, function() {
console.log('Your app is listening on port ' + listener.address().port);
});
Brotli
にはshrink-rayが使えるよ〜
・Static comporession
事前に最適化して保存しておくよ。ビルドが長くなるけどアクセス時の遅延は起こらなくなるよ。
webpackのpluginが使えるよ。
module.exports = {
plugins: [
new CompressionPlugin()
]
}
weight: 25%
The Largest Contentful Paint (LCP) metric reports the render time of the largest image or text block visible within the viewport.
viewport内で一番重い画像やテキストのレンダリング時間。
<img>
<svg>
内での<image>
<video>
url()
を使うもの対応
weight: 15%
Measuring TTI is important because some sites optimize content visibility at the expense of interactivity. This can create a frustrating user experience: the site appears to be ready, but when the user tries to interact with it, nothing happens.
一定数のサイトはinteractivityを軽視してコンテンツの表示速度ばかり重視している。
A page is considered fully interactive when:
FCPによって測定された有意なコンテンツが表示され、イベントハンドラがほとんどの要素に登録され、ユーザーの動作に50ms以内でに反応する事。
対応
weight: 25%
TBT measures the total amount of time that a page is blocked from responding to user input, such as mouse clicks, screen taps, or keyboard presses.
ユーザーの入力への返答がブロックされた時間(blocking portion)の合計。
50ms以上かかる処理はlong taskとされる。
例えば70msの処理は70 - 50で超過分の20msがblock portionとされる。
参考: Are long JavaScript tasks delaying your Time to Interactive?
対策:
weight: 5%
cumulative(意:累計)
レイアウトが頻繁に変わりすぎるページだとUXを損なうからよくないよ〜
対策
width
,height
の動的な変更ではなく、 transform: scale()
を使おうtop
, right
, bottom
, left
を動的に変更せず、transform: translate()
を使おう指標は6つあるが、改善策はそれぞれに固有の物ばかりでなく共通の物が多い。
Minimize main thread work(JS)
Reduce JavaScript execution time
ブラウザ(LightHouse)でJSファイルを見てもchunkされた状態になっているので、webpackのビルドプロセスを把握する必要がありそう。
参考: https://qiita.com/mizchi/items/418be9abee5f785696f0
次回はwebpackの最適化とかをまとめていくつもりです。