Home
Product
Article
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がレンダリングされるまでにかかる時間。
Ensure text remains visible during webfont load
→ 対応:
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.
どれだけ速く、ページが視覚的に表示されるか。
レンダリングプロセスの根幹を司るmain threadを最適化すべし。
main threadはHTMLのparse, DOMの構築, CSSのparseと適用, そしてJSのparse, 評価, 実行と言った、コードの大部分を扱う。
またmain threadはユーザーからの操作(イベント)に対応する為、常に忙しいが、これを後回しにするとUXへ影響する。
対応: (多すぎて書ききれない...)
.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?
対策:
What is causing my Long Tasks?
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の最適化とかをまとめていくつもりです。
・1. First Contentful Paint (FCP)
・2. Speed Index
・3. Largest Contentful Paint (LCP)
・4. Time to Interactive (TTI)
・5. Total Blocking Time (TBT)
・6. Cumulative Layout Shift (CLS)
12min