15
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

さいきょうの配色 Web サービスが激遅だったので丁寧にパフォーマンスチューニングした

Last updated at Posted at 2020-04-05

「久々に Lighthouse 確認してみるかな……」
start.png

「……!??」

「にじゅーご……?」
25.png

:innocent:

はじめにおことわり

この記事は Nuxt.js で個人開発した Web サービスがパフォーマスンス面でイマイチな状態だったので、それをチューニングした内容をまとめています。

計測は Lighthouse でおこない、その改善指針にしたがいチューニングしています。
パフォーマンスチューニングを幅広い視点で汎用的に行うための記事ではありませんので、あらかじめご了承くださいませ。
(逆に、これから個人開発をするような初学者の人には役に立つ情報があるかもしれません)

さいきょうの配色 Web サービスとは?

:link: ぼくのかんがえたさいきょうの配色Webサービスを公開した話

以前こちらの記事で紹介させていただきましたが、色に興味があることから開発した Web サービス『 yum-yum COLOR 』のことを指します。

構成は Nuxt.js × Netlify で、 PWA にも対応した SPA です。
フロントエンド初学者だった当時の僕にしては、まあまあがんばっていたんじゃないでしょうか。

記事の中でも紹介していますが、当時も Lighthouse で計測をおこなっており、そこそこのスコアを出していました。
Lighthouse の仕様は頻繁にアップデートされており、久々に計測したら散々だった……ということです。

Lighthouse について

冒頭にも紹介した Lighthouse は、 Google が開発したオープンソースのツールで、パフォーマンスをはじめとした Web アプリの品質向上に役立つツールです。

以前は Chrome 拡張により利用できましたが、最近では開発者ツール( Chrome から F12 で表示)にも標準で用意されています。
devtools.png

Chrome 拡張の方はモバイルの測定になりますが、開発者ツールではモバイル・デスクトップのそれぞれを測定することが可能です。
また、開発中のアプリ( URL が localhost:300 など)を測定できるのも開発者ツールのみです。
(スペックの低い PC だと正しく計測できないことがありましたので、どちらも併用するのがよいかもです)

Lighthouse が提案してくれる改善指針

Lighthouse はパフォーマンスなどを計測するだけでは終わりません。
「なにが原因なのか? どうすれば改善するか?」を改善指針として表示してくれます。
next-gen-formats.png

たとえばこれ。
「アプリが利用している画像のフォーマットが PNGJPEG だと重いよ!」といってくれています。
次世代フォーマット(って表現でいいのか?)である JPEG 2000JPEG XRWebP を使おう!
って感じで。

今回はこれらの指針にしたがいチューニングをしていきます。

さいきょうの配色 Web サービスのパフォーマンス

冒頭でキャプションを貼りましたが、チューニング前のパフォーマンスは次のような感じです。
base-performance.png

ひどいスコアですね :sweat:
ここから改善させていきます。

チューニング

1. ESLint

これはチューニング以前の問題なのですが、当時このアプリを開発していた頃は本当にフロントエンドの知識が少なく、 ESLint をビルド時に自動実行する設定にしていませんでした。
それどころか Lint を知らなかったわけで……(笑)

実際に Lint を流してみると微妙なところがたくさんあり、とりあえずエラーを解消させています。
それによるものかはわかりませんが、スコアが『 29 』になりました。
step1.png

2. 次世代フォーマットの画像への差し替え

next-gen-formats.png

これは上ですでに紹介しましたが「画像のフォーマットを新しいものに変えましょう」というものです。
個人的には WebP 推しなのですが、 Safari が対応しておらず、 iPhone ユーザーの多い日本では結構痛手です。

改善方法

Safari のみ JPEG ……というのも考えましたが、それはそれで JS 側が遅くなりそうなので、一番重い画像( 189KB のもの)を PNG から JPEG に変える対応のみ行いました。
(他の画像は比較的軽いですし、透過である必要があるので)
step2.png

うん、気持ちだけスコアアップ :sweat_smile:
ただ、 「Metrics」の First Contentful Paint の時間がかなり縮んでいますし、「 Opportunities 」の Serve images in next-gen formats が縮んでいます。

どちらも 赤字 から オレンジ に変わっていますね。
作ってる身としては、これだけでも気分が悪くないです!

3. Ensure text remains visible during webfont load

Ensure text remains visible during webfont load.png

これは Google フォントなどのいわゆる Web フォントを使用している場合に、一部のブラウザではフォントの読み込み中にテキストを非表示にするために、テキストが点滅しているように見えてしまうそうです。
「それに対して対策を打ってよ」とのこと。

どのフォントを利用しているのか調べてみると roboto というフォントでした。
使った覚えがなかったので node_modules に対して Grep すると、犯人は bulma でした。
CSS フレームワークである bulma の標準スタイルでこのフォントを使っていたようです。

改善方法

こちら に書いてありますが、 @font-face スタイルに font-display: swap; を指定することで改善するそうです。

@font-face {
  font-family: 'Pacifico';
  font-style: normal;
  font-weight: 400;
  src: local('Pacifico Regular'), local('Pacifico-Regular'), url(https://fonts.gstatic.com/s/pacifico/v12/FwZY7-Qmy14u9lezJ-6H6MmBp0u-.woff2) format('woff2');
  font-display: swap;
}

また、 Google フォントであれば URL に &display=swap を付与するそうです。

<link href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap" rel="stylesheet">

ただ、 bulma のフォントにはどちらもうまく適用できませんでした……。

:link: Nuxt.jsにBulmaを導入して変数を使ったカスタマイズを行う

こちらの記事を参考に @nuxtjs/bulma の利用をやめたり試行錯誤しましたが解決方法がわかりません :head_bandage:
(わかる方いたら教えてほしいです)

4. Reduce the impact of third-party code

Reduce the impact of third-party code .png

これはわかりやすいですね、サードパーティのコードのインパクトが大きいよ! だそうです。

しかも一番パフォーマンスに影響を与えているのは……広告。
広告収入は個人開発をしている人にとって重要な収入源なので、これはこのままで(笑)

5. Minimize main-thread work

Minimize main-thread work .png

いかにもパフォーマンスという項目がきました。
メインスレッドのロードに要した時間の内訳です。

これを見ると分かるとおり、 Script Evaluation がもっともロードに時間がかかっています。
実はスクリプトのロード時間に関しては、次の項目で詳細がわかるようになっているのでそちらを見てみましょう。

6. Reduce JavaScript execution time

Reduce JavaScript execution time.png

JS の解析、コンパイル、および実行がかかっているということです。
デフォルトではサードパーティのコードも表示されているので、右上のチェックボックスを外すと自分のコードのみ表示することができます。

改善方法

まずは JS のコードを分析してみましょう。

nuxt.config.js
/*
 ** Build configuration
*/
build: {
  analyze: true,
},

nuxt.config.js にビルドオプションを追加し、アプリをビルドしましょう。

$ yarn run build

するとブラウザに次のような画面が表示されます。
yum-yum-color_.nuxt_stats_client.html.png

これはプロジェクトで利用されているコードの割合を示しています。
画面内で大きく表示されているものほど、その容量も大きくなります。

「……Font Awesome。おまえだったのか」

さいきょうの Web 配色サービスでは、ヘッダーに Twitter や GitHub 、それにブログ用のリンクを用意しており、そこで Font Awesome のアイコンを利用しています。

それなのに、利用の仕方は……こう。

import { fas } from '@fortawesome/free-solid-svg-icons'

面倒くさがり屋の自分を恨みたくなる設定です :sob:

これをちゃんと、

import { faBlog } from '@fortawesome/free-solid-svg-icons'

として利用しました。
yum-yum-color_.nuxt_stats_client.html (1).png

おー Font Awesome 小さくなりましたね。

スコアは……
step5.png

これはまあまあ改善されましたね!
やっと許容範囲といったところでしょうか。

その後も色々と試しましたが……

step5-2.png

逆に下がってしまったり……安定しません。

さいきょうの Web 配色サービスでは配色を扱うその特性上、インライン SVG を利用しているため一つのファイル容量が大きくなるなど、どうにもこうにもうまくいきませんでした。

ただし別の方法でパフォーマンスを担保している

このアプリが遅いのは SPA は初期の読み込みに時間がかかるという特性がダイレクトに響いています。

それを解消する一つの方法として PWA があります。
現にこのアプリも 2 回目以降の表示は高速(というか爆速)、 Lighthouse のスコアほど遅い印象は受けないと思います。
(自分で言う)

これから個人開発をはじめるかたは PWA を意識してみるのもいいかもしれません。

おわりに

この記事は企画とタイトルを先に思いつき、チューニングしながら記事を書き進めていきました。
チューニングがバッチリな結果であれば良かったのですが、実際はそうもうまくいかないもので…… :sweat_smile:

パフォーマンスチューニングの技術記事としては微妙なものですが、Lighthouse を使ったことがない人や、ソースコードの解析を知らない人にとって少しでも役に立てば幸いです :yum:

15
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?