Next.js 製ブログページのパフォーマンスを向上させるために実施したこと

Next.js 製ブログページのパフォーマンスを向上させるために実施したこと

はじめに

どーも、入田 / ぐるたか @guru_taka です!
今回はブログページのパフォーマンスを向上させるため施策を行いました。施策前後の結果は下図の通りです。
▼Before
sp_before_pagespeed_Insights
▼After
pc_after_pagespeed_Insights
sp_after_pagespeed_Insights
PC もスマホも全体的にパフォーマンスが良くなりました!本記事では、ブログページのパフォーマンスを向上させるために行ったことを紹介します。

バージョン情報

  • React:17.0.2
  • Next.js:10.2.2
  • react-syntax-highlighter:15.4.3

原因

主な原因は容量の大きい JavaScript のファイルによって、長時間のレンダリングブロッキングが起きていたことです。最も容量の大きいファイルに関しては、約 2.6 秒ほど処理を終えるまでに時間がかかっています
bad-performance-cause1
また使用されていない JavaScript のファイルも配信されていました。
bad-performance-cause2

Webpack Bundle Analyzer で容量を確認

ということで、バンドルサイズを @next/bundle-analyze で確認してみます。具体的な手順は以前の記事をご覧ください!
performance_bundle_size_check1
performance_bundle_size_check2
上図のように refractor というモジュールが大容量ファイルの原因であることが確認できました。refractor とは、react-syntax-highlighter に関連するモジュールです。 ボトルネックになっていたのは react-syntax-highlighter と判明しました。

改善策

主な改善策は以下2つです。
  • 巨大なバンドルサイズを細かく分割
  • 不要なシンタックスハイライトの CSS ファイルを読み込まない
改善したコードは以下のようになります。
▼ Before
import { Prism as SyntaxHilighter } from 'react-syntax-highlighter'; import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism';
▼ After
import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter'; import vscDarkPlus from 'react-syntax-highlighter/dist/cjs/styles/prism/vsc-dark-plus';
最も効果が著しかった施策は、巨大なサイズを細かく分割したことでした。具体的には react-syntax-highlighterPrismAsyncLight というモジュールを使用します。
PrismAsyncLight を使うことで、コードボックスを先にレンダリングします。そして、非同期で必要な言語ファイルを動的に読み込み。その結果、レンダリングブロックの時間を大幅に削減できるようなります。
詳細は公式リポジトリでご確認ください!
For optimal bundle size for rendering ASAP, there's a async version of prism light & light.
This versions requires you to use a bundler that supports the dynamic import syntax, like webpack.
This will defer loading of refractor (17kb gzipped) & the languages, while code splits are loaded the code will show with line numbers but without highlighting.
引用:react-syntax-highlighter Async Build | GitHub
実際に、改善した後にバンドルサイズを @next/bundle-analyze で確認してみると、下図のように全体の容量は微増していますが、チャンクファイルが細かく分割されていることがわかります。
after_bundle_size_check
パフォーマンスを計測してみると、下図のように数値が向上していました!
pc_after_pagespeed_Insights
sp_after_pagespeed_Insights

最後に

以上になります。react-syntax-highlighter を使用している方は、非同期のファイル読み込みに対応している PrismAsyncLight / LightAsync を使用するだけで、パフォーマンスが劇的に向上します。
コード付きのブログページを開発している方の参考になれば幸いです!

株式会社キカガク コンテンツマーケティング責任者
入田 / ぐるたか
twitter: @guru_taka

参考文献