monolithic kernel

react-fontawesome でページ読み込み時に一瞬だけアイコンが大きくなる問題

追記 2022-02-15

@fortawesome/fontawesome-svg-core を 6.0.0 に上げたところ、このブログではうまく動かなくなった。改めて対処方法を調べているうちに、gatsby-plugin-fontawesome-css という GatsbyJS 向けのプラグインを発見。やっていることの大筋はおそらくこの記事で紹介した内容と変わらないものの、入れてみたらうまく動いてくれたのでそれ以上は深追いせず解決とした。


装飾のためにこのブログに導入したところ、問題が起きるようになったため調査した。react-fontawesome の Issue とそこから辿れる公式のドキュメントに辿り着いた。

要するに、アイコンが大きくなるのは CSS が適用されていないために起きているらしい。デフォルトだと autoAddCss というオプションが true になっていて動的に CSS が読み込まれるのだが、サーバサイドレンダリングなどでアイコンが埋め込まれた HTML が生成されている場合には CSS の適用が間に合わないようだ。GatsbyJS を使う場合もアイコンが埋め込まれた HTML が事前に生成されることになるので、autoAddCss では間に合わない。このような原因なので、開発中には問題にならず、プロダクションのビルドでのみ顕在化する。

解決策としては、autoAddCss による CSS のロードを無効化し、代わりに CSS がアイコンよりも先にロードされるように埋め込めばよい。具体的なコードは先程の Issue のコメントにあった。

layout.js 的なファイルに以下のコードを入れてあげることで、強制的に CSS がアイコンよりも先にロードされるようになり、問題は生じなくなった。

// This ensures that the icon CSS is loaded immediately before attempting to render icons
import "@fortawesome/fontawesome-svg-core/styles.css"
import { config } from "@fortawesome/fontawesome-svg-core"
// Prevent fontawesome from dynamically adding its css since we did it manually above
config.autoAddCss = false

サーバサイドレンダリングは、もろもろの事情のために無茶なことをしているという感覚はある。そう考えると、デフォルトのままだとサーバサイドレンダリングで不具合が生じるのはまあ仕方ないか。GatsbyJS を使うと自動的にサーバサイドレンダリングと似たような状況になるので、それによってつらさが生じやすいというのはあるかもしれない。


Related articles