RailsでFont Awesomeのアイコンが画面遷移時にちらつく問題を解消する

自作のRailsアプリの短歌投稿サイトUtakataで、通知アイコンのベルアイコン等にFont Awesomeを利用しているのだけれど、アセット管理をSprocketsからWebpackerに移行してから、画面遷移時にアイコンの表示が毎回再読み込みされてちらつく問題が起きるようになった。

特に利用に支障ないのでかなり長期間放置してしまったけれど、最近Turbokinksとの兼ね合いの問題では?と気づいて「font awesome turboinks」でググってみたらやはりそうだった。

After you’ve installed the SVG with JS version of Font Awesome, and loaded your first page in your Rails app, there are a couple of things that happen.

1. Font Awesome will search for any i elements and replace them withsvgelements.
2. It will create a MutationObserver that watches for changes in the page to do future replacements.

When Turbolinks replaces the body of your page with new content after navigation occurs, Font Awesome automatically reconnects this MutationObserver to the new content.

Here’s where the problem is: there is a flash where icons are missing before they quickly appear. This looks pretty nasty, but we can fix it easily.

MutationObserverという仕組みがbodyの変更を検知してi要素をsvg要素に置き換えることでアイコンの表示を実現しているらしく、Turbolinksがbodyを書き換えるタイミングでその処理が間に合わずアイコンのちらつきが起きちゃってちょっと不快だと思う、でも簡単に直せるよ!的なことが書いてあって、私の遭遇している事象そのまんまだ。

Setting the mutateApproach configuration to sync (available in version 5.8.0 or greater), provides a way to skip this flash of missing icons by rendering them as soon as Turbolinks receives the new body.

mutateApproachという設定項目(デフォルトではasync)をsyncに変えればTurbolinksが新しいbodyを受けたタイミングでただちにアイコン要素の置換処理をしてくれるようになるらしい。

機能追加時点での差分はGitHubで見られるけれど、具体的にどういう仕組みなのかはぱっと見では分かりそうにない。

Webpacker利用の環境で上のように書いたらちらつきが起きないようになった。