はじめに
今回はブログページのパフォーマンスを向上させるため施策を行いました。施策前後の結果は下図の通りです。
▼Before
PC もスマホも全体的にパフォーマンスが良くなりました!本記事では、ブログページのパフォーマンスを向上させるために行ったことを紹介します。
バージョン情報
- React:17.0.2
- Next.js:10.2.2
- react-syntax-highlighter:15.4.3
原因
主な原因は容量の大きい JavaScript のファイルによって、長時間のレンダリングブロッキングが起きていたことです。最も容量の大きいファイルに関しては、約 2.6 秒ほど処理を終えるまでに時間がかかっています。
また使用されていない JavaScript のファイルも配信されていました。
Webpack Bundle Analyzer で容量を確認
ということで、バンドルサイズを @next/bundle-analyze
で確認してみます。具体的な手順は以前の記事をご覧ください!
上図のように 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-highlighter
の PrismAsyncLight
というモジュールを使用します。
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
で確認してみると、下図のように全体の容量は微増していますが、
チャンクファイルが細かく分割されていることがわかります。
パフォーマンスを計測してみると、下図のように数値が向上していました!
最後に
以上になります。react-syntax-highlighter
を使用している方は、非同期のファイル読み込みに対応している PrismAsyncLight
/ LightAsync
を使用するだけで、パフォーマンスが劇的に向上します。
コード付きのブログページを開発している方の参考になれば幸いです!
株式会社キカガク コンテンツマーケティング責任者
入田 / ぐるたか
twitter:
@guru_taka
参考文献