概要
Next化でコンポーネントをSSRとCSRで出しわけることができることになったので、SSRする必要のないコンポーネントが表示されるまで高さと幅を持ったスケルトンコンポーネントを表示することで、UIがカクつくのを防止する。
イメージ
どんなコンポーネントにスケルトンを実装するか
真っ先に表示されてほしいものはSSRするのでスケルトンは必要ない
- ページの本文とか
- 上のイメージの例ではページパスはSSRしている
別に早く表示する必要のないものはSSRしないのでスケルトンがあるとよい
- 上のイメージの例ではいいねボタンとか、タグの情報とか
- 基本こっちが多めになるのか?
スケルトンの実装方法
const TagLabels = dynamic(() => import('../Page/TagLabels'), { ssr: false, loading: () => <Skelton additionalClass={`${TagLabelsStyles['grw-tag-labels-skelton']} py-1`} />, });
dynamic importにおいてNext.jsのssr: false
オプションとloading:
を使うことでレンダリング中にコンポーネントを表示させることができるのでこれを活用する。
スケルトンの実装におけるルール
高さのハードコーディングはしない
.grw-page-editor-mode-manager-skelton :global { width: 213px; height: calc($btn-line-height + bs.$btn-padding-y*2 + bs.$btn-border-width*2); // こっちが理想 height: 35.99px; // これはダメ }
本物のコンポーネントの高さを変数に切り出したり、bootstrapのpaddingの値を活用したりして高さを計算して設定する。 でも本当にどうしようもない時は仕方がないかもしれない...
幅に関してはUIがカクつく原因にはあまりならないので、程よい値を設定する。
スケルトンと本物のコンポーネントのスタイルは同じファイルにあったほうがわかりやすい
PageEditorModeManager.module.scss@use '~/styles/bootstrap/init' as bs; @use '~/styles/mixins'; $btn-line-height: 1.2rem; .grw-page-editor-mode-manager :global { .btn { width: 70px; white-space: nowrap; @include mixins.border-vertical('before', 70%, 1, true); &.view-button, &.edit-button { line-height: $btn-line-height; .grw-page-editor-mode-manager-icon { @include bs.media-breakpoint-down(sm) { font-size: 1.2rem; } } } &.hackmd-button { line-height: $btn-line-height; .grw-page-editor-mode-manager-icon { @include bs.media-breakpoint-down(sm) { font-size: 1.2rem; } } .grw-page-editor-mode-manager-label { font-size: 12px; letter-spacing: -0.6px; } } } } .grw-page-editor-mode-manager-skelton :global { width: 213px; height: calc($btn-line-height + bs.$btn-padding-y*2 + bs.$btn-border-width*2); }
cssファイルのモジュール化などを活用して、同一ファイルにまとめた方がわかりやすい。