gatsby-ssr.jsがないとサイト全体の挙動がおかしくなった話
サイトの初回読み込み時に画像が表示されてから、一度消えて再表示される問題が発生。 これは画像の問題ではなくgatsby-ssr.jsを作成してやればで解決できることでした。 そして他にもサイトで起こっていた複数の原因不明の問題も実はこれが原因だったようです。
解決方法
一番目立っていた問題が画像の点滅だったため、ずっと画像処理の問題だと思っていたのですが、最初に読まれる静的 HTML と SPA 実行時の css の内容が一致しないことが原因だったので、gatsby-ssrを作成して設定してやる必要がありました。
gatsby-browser がこう設定されているので、
import React from 'react'
import { WrapPageElementBrowserArgs } from 'gatsby'
import Layout from './src/components/templates/Layout'
export const wrapPageElement: React.FC<WrapPageElementBrowserArgs> = ({
element,
props,
}) => {
return <Layout {...props}>{element}</Layout>
}
gatsby-ssr で import して、そのまま export すれば解決します。
export { wrapPageElement } from './gatsby-browser'
具体的な症状
再生速度を1/3にしています。 特に下にある三つの記事のサムネイルがわかりやすいでしょう。 このように表示されてから、一度消えて再度表示されますが、実際はもっと早いので点滅しているような感じになっていました。
他に、地味ですが、フォントも css では指定していないゴシック系で一度表示されています。 フォントの切り替わりを二回も起こしていますね。
ちなみに当初原因が分からなかったときに、点滅が目立たないようヘッダーの background-color を黒にしていたので、分かりづらいですがヘッダーの背景画像も同様の症状を起こしています。
gatsby-ssr を作成して正常に動作するとこんな感じに、一度の読み込みできちんと表示できています。 これが普通なのですが、普通に動くって素晴らしい。
※今回、アニメ gif ではどうしても重くなるのでアニメ webp を採用してみました。 MacOS でも Big Sur 以降は対応された現代なら、個人サイトはもう使っても大丈夫でしょう。多分。
解決までの経緯
この問題について、ずっと画像処理の問題として調べていたのですが、それでは見つかるはずがありません。 偶然にもネットサーフィンしていて、拝見した Gatsby の css の問題について記載している記事が自分のサイトにも効果があるのかと気になって試してみたところ、予想外の解決となりました。感謝。
後から調べてみると gatsby-browser と gatsby-ssr の関係についてはしっかり公式にも書いてありました。 gatsby-ssr の存在しない starter から作り始めて develop では問題が起こらなかったので、その必要性を認識しないままでした……
You generally should implement the same components in both gatsby-ssr.js and gatsby-browser.js so that pages generated through SSR with Node.js are the same after being hydrated in the browser.
// DeepL翻訳 一般的には、gatsby-ssr.jsとgatsby-browser.jsの両方に同じコンポーネントを実装して、Node.jsのSSRで生成されたページがブラウザでハイドレイトされた後も同じようになるようにします。 https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/
display=swap
設定の web フォントに対して、代替フォントとして明朝系を指定してたのにゴシック → 明朝 → Webフォントと変化していたのは、CSSの不一致が原因だったからなんですね。
CSS未適応のフォント → CSS指定の代替フォント → 読み込まれたwebフォントという処理になっていたわけです。
修正後は明朝 → Webフォントと一般的な二段階の変化になっています。
調査が迷走した原因
最初に問題が発生して調べたときに、Gatsby 公式の issues にオープンしていた『gatsby-plugin-image 画像がちらつく/点滅している』という凄く似た問題が上がっていたので、その印象で画像の問題と決めつけてしまったのが失敗でした。
参考として問題が起こっている方のサイトのキャプチャ動画が掲載されているのですが、一度消えて再表示される感じが凄く似ているんですよ。 ちょうど問題を認識したのが Gatsby3 へのアップグレードで gatsby-image から gatsby-plugin-image へと入れ替えた直後でしたし、余計に間違った予想に固執することに。
色々と試したこと
issues で解決法として示されていた gatsby-plugin-image を v1.1.0 にダウングレードしてみたり――
service-worker で画像をキャッシュしている問題じゃないのか、と gatsby-plugin-offline の設定を調査してみたり――
gatsby-plugin-image の読み込み設定のせいじゃないか、と色々と変更してみたり――
コンボーネント内部で意図せず再読み込みが発生しているんじゃないか、と hooks の処理に異常がないか調べたり――
問題を認識してから、なんだかんだ一月ぐらい遠回りすることになりました。
更に追加で解決したこと
サイトを更新して Netlify へデプロイしてから、キャッシュを持っているブラウザでトップページへ初回アクセスすると、一度リロードしないと画面が真っ白のままになる時があるという症状も起こっていました。 (キャッシュ絡みで gatsby-plugin-offline の設定を失敗しているのだろうとばかり)
他にも、初回アクセスでトップページやブログ記事ではなく、カテゴリ一覧のページや、404ページにアクセスすると、他のページに移動したときにhtmlの入れ子が崩れるという問題もありました。 静的html → SPA への移行時がおかしくなっていたようで。
これらがすべて今回の対策ですべて解決しました。 想像以上に、gatsby-ssrがないことの影響範囲は大きかった!
というか、最近当サイトで起こっていた原因不明の問題の大半がこれ絡みだったという……Woozy Face Emoji
まとめ
gatsby-browser を使うときは、必ず gatsby-ssr も一緒に作ろう!