自作の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 withsvg
elements.
2. It will create aMutationObserver
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 thisMutationObserver
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 tosync
(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利用の環境で上のように書いたらちらつきが起きないようになった。