🦜

Next.jsにおけるCSSツールの技術選定において考えたこと、選定したツール

2024/03/12に公開

はじめに

Next.js(App Router)を使った開発でCSSツールの技術選定をおこなう機会がありました。
今回は技術選定において考えたこと、選定したツールを一例としてご紹介します。

前提

技術選定をおこなうにあたり、最初に前提を整理しておく必要があります。

どのようなサービスを作るのか

サービスの内容によって要件や仕様、使うツールなどが異なってきます。例えば、動画配信サービスであれば動画プレイヤーライブラリの選定が必要になってくる可能性があります。データをわかりやすく表現する必要があればチャートライブラリを選定することもあるでしょう。
今回は情報紹介サービスのようなものを想定します。

誰が開発するのか

どんなスキルセットを持ち合わせた人が開発するか、複数人であれば難易度はどれぐらいに合わせるかなどを考慮する必要があります。学習コストがどれぐらいかかるものかを踏まえ採用するか検討することになります。
今回は以下の条件を想定します。

  • HTML, CSS, JavaScript歴がだいたい5年以上
  • CSSは割と得意、もしくは少しフォローがあればできる
  • Next.jsは1人は業務実績があり、その他はフォローがあればできる
  • 4名程度で各自上記の条件を満たしている

開発するものは個人か仕事か

個人であれ仕事であれローンチすれば実績になります。個人であれば面接時に実績としてアピールできたり、仕事であれば採用で開発環境としてアピールできたりします。採用に力を入れたい企業は技術選定の基準として「採用に繋がるか」を検討しても良いかもしれません。
今回は仕事で開発することを想定します。

すでに確定しているものはあるか

技術選定の前にすでに確定しているものは動かすことが難しいかと思います。確定していることに対してより優れたものが確信的で多くの人を巻き込んででも変えたいという強い意志と行動力があれば変えることは可能でしょうが、多大な時間と労力をかけることや影響範囲が大きいことが想定されるので余程のことがない限りは確定していることは確定していることを前提とするのが望ましいでしょう。
今回はNext.js(App Router)を使うことを前提とします。

以上の前提をまとめると以下です。

  • 一般的なWebサービス
  • 4名程度の規模でCSSにそこそこ自信を持っているメンバーがいる
  • 仕事で開発するので採用でのアピールもある程度視野に入れたい
  • Next.js(App Router)の環境で使えるCSSツールを選定する

CSSツールの分類

Reactで扱うCSSツールはおおよそ以下の分類に分かれます。

分類 ツール例
CSS Modules Sass
CSS-in-JS Emotion, KUMA UI
UIライブラリ MUI
CSSフレームワーク Bootstrap

上記の表で挙げているツール以外にもたくさんのツールがありますが、今回は上記で挙げたツールを念頭に選定していきます。
それぞれの特長を簡単にまとめます。

CSS Modules

  • CSS Modulesはグローバルスコープ汚染問題を回避するためのもの
  • CSS Modulesの仕組みでSassを利用することが可能
  • 仕様はメンテナンスされていないが、安定している
    • 実装は引き続きメンテナンスされている
    • 何か問題があれば実装側で対応されていくはず

https://developer.hatenastaff.com/entry/2022/09/01/093000

CSS-in-JS

  • JavaScriptの中にスタイルを書くツール群の総称
  • ランタイムでスタイルを更新するツール(ランタイムCSS-in-JS)はパフォーマンスに影響がある
  • ランタイム時のパフォーマンスを改善したゼロランタイムCSS-in-JSが後に登場した
  • ビルド時に静的解析でスタイルを設定し、動的なスタイルはランタイムでおこなう仕組みを採用したハイブリッドCSS-in-JSがさらに後に登場した

それぞれの特長と課題を以下にまとめました。

特長 課題
ランタイムCSS-in-JS ・歴史が他より長く安定してきている
・ランタイム時のパフォーマンス影響において課題があるが改善が進んでいる
・ランタイム時のパフォーマンスに影響がある
ゼロランタイムCSS-in-JS ・ランタイムのパフォーマンス影響が少ない ・ランタイムCSS-in-JSより制約がある
ハイブリッドCSS-in-JS ・スタイリングを静的と動的それぞれ適切なタイミングでおこなうので前者のいいとこどりをしている ・2024年3月現在では出始めたばかりなので頻繁なアップデートや破壊的変更の可能性が高く、アルファ版(メジャーバージョンが0)のものもある。

https://zenn.dev/poteboy/articles/e9f63b87b3cd69
https://zenn.dev/yuku/articles/dd4c5c9c7299aa

UIライブラリ

  • UIコンポーネントやUIウィジェットを提供するための一連のJSとCSS
  • MUI(旧 Material-UI)が有名
    • MUIはEmotion(CSS-in-JS)をデフォルトのスタイルエンジンとして使用している

CSSフレームワーク

  • スタイルや定義を提供するための一連のCSSクラスとスタイル定義
  • Bootstrapが有名

https://qiita.com/xrxoxcxox/items/6c82a62d41f14d530db1
https://qiita.com/mei2678/items/eb95f0aa381fef731b28

Next.jsの状況

Next.jsはv13.4からApp Routerが利用できるようになりました。
App Routerは公開されてからまだ日が浅く対応がまだの機能やツールがあります。
Next.jsの状況次第では採用を見送るツールが出てくる可能性があるので現状を確認します。

App RouterになったことでCSSツールに影響があるものの代表として、レンダリングするタイミングが変わることが挙げられます。

  • サーバー側でレンダリングすることが基本(React Server Components)
  • クライアント側でレンダリングしたい境界のファイルの先頭に 'use client' と記述

サーバー側でのレンダリングを基本として親から子へとツリー構造にコンポーネントが呼ばれていき、クライアント側でレンダリングしたいファイルに 'use client' と記述することでサーバーとクライアントの境界ができ、その境界以降はクライアント側でレンダリングします。

現在、App Routerではレンダリングのタイミングによって使用できるツールが限定されているようです。

サーバー側でレンダリング

  • CSS Modules
  • PostCSS
  • Tailwind CSS

クライアント側でレンダリング

  • 一部の CSS-in-JS
  • MUI

今回はルーティングで使うpage.tsxはサーバー側でのレンダリングとし、それ以降のコンポーネントをクライアント側でレンダリングすることとします。
よって上記に書かれているツールはすべて選定対象とします。

https://rightcode.co.jp/blog/information-technology/next-js-13-4-app-router-syain
https://nextjs.org/docs/app/building-your-application/styling/css-in-js

選定基準の観点

技術選定をおこなうにはさまざまな観点で検討する必要があります。
組織やプロダクトの要件等を踏まえ以下のような観点で検討するのが望ましいと考えました。

  • パフォーマンス
  • 品質
  • 学習コスト
  • 持続性
  • 効率性
  • 認知度

以下、ざっくりと説明しますが、あくまで観点として検討する内容でありそれぞれ明確な指標は特に設けていない点、ご了承ください。

パフォーマンス

パフォーマンスとは、主にページ表示速度のことと捉えてください。ユーザー体験に直結することなのでフロントエンド領域としては考慮する必要があります。以下を確認しますが、公式サイトやGitHubなどで言及されていないものもあるのでわかる範囲での確認に留めます。

  • ファイルサイズは大きすぎないか
  • 使用しないものまで読み込まないといけないか
  • レンダリング速度にネガティブな影響を与える要因となる明確なものはあるか

品質

CSSにおいて一貫性、再利用性、保守性などの観点で品質水準を一定に保てるかを検討します。ツールを使って担保できるか、または設計や決め事でカバーすることになるか確認します。

学習コスト

仕事での開発において開発するメンバーのスキルセットを加味して選定する必要があります。メンバーにとって学習コストが高いと初期導入や新規参入時などに想定よりも工数がかかってしまう可能性があります。ただし、あらかじめガイドラインやドキュメントを用意するなどの学習コストを下げる対策をしておくことをおこなうのであれば採用する判断をしても良いかと思います。趣味であれば学習することを目的として採用する判断をしても良いと思います。

持続性

仕事で選定する場合、使用するツールが定期的に更新されているか、破壊的な変更を短期間に繰り返していないかなどを確認する必要があります。コミュニティが活発かどうかも余裕があれば確認するとなお良いでしょう。メジャーバージョンが0のもの、または更新が数年止まっているようなものは選定を控えたほうが無難かもしれません。
趣味であればあまり気にしなくても良いかもしれません。新しいツールを試しに使って得られることもあるでしょう。

効率性

開発のしやすさ(いわゆる使い勝手、DX)が良いか調査します。ここは個人の好みが出やすい部分なのでメンバーと意見を出し合って擦り合わせると良いかと思います。今回は私の感覚で評価します。

認知度

広く認知されているもの、人気なものにはある程度の理由が存在することが多いです。また、採用活動に有利に働く可能性もあります。しかし、認知度は他の観点に比べて優位性は高くないと考えています。認知度よりプロダクトの要件を満たしているかを優先するべきでしょう。

各ツールの選定基準に対する対応表

以上を踏まえ、今回はそれぞれ代表的であると考えるツールをもとに簡単な比較表で表現してみました。

CSS Modules CSS-in-JS UIライブラリ CSSフレームワーク
想定ツール Sass Emotion, Kuma UI MUI React Bootstrap
パフォーマンス ⚪︎ ⚪︎ ⚪︎
品質 ⚪︎ ⚪︎
学習コスト
持続性 ⚪︎ ⚪︎
効率性 ⚪︎ ⚪︎
認知度 ⚪︎ ⚪︎

マークを付けた理由をツールごとに良い点、懸念点として以下に簡単にまとめました。

CSS Modulesを採用する場合

良い点

  • CSSの書き方とほとんど同じで学習コストが比較的低い
  • Sassファイルを資産として他のプロダクトに活用しやすい

懸念点

  • 仕様がメンテナンスされていない点は動向を気にしておく必要がありそう
  • 品質においては命名規則はBEMやガイドラインなどの取り決めをおこなう必要がある

CSS-in-JSを採用する場合

良い点

  • スタイルをJavaScriptで書ける
  • 動的な値を扱いやすい

懸念点

  • ツールによって書き方が異なるので技術的負債に繋がる可能性が比較的高い
  • 比較的歴史の長い有名なものはパフォーマンスが気になり、パフォーマンスが良いものは歴史が浅く採用する決断力が問われる
  • JavaScriptでのスタイリングに慣れていないと初期に学習コストがかかる

UIライブラリまたはCSSフレームワークを採用する場合

良い点

  • 品質を一定に保てる可能性が高い
  • あらかじめコンポーネントが用意されているので作り込む工数の削減が多少期待できる
  • ドキュメントが用意されているのでレールから外れなければそのまま開発ドキュメントとして利用できる

懸念点

  • UIライブラリを経験していないと一定の学習コストがかかる
  • 要件を満たせるか、どのような制限があるか、やりたいことを実現できるかなどを確認する必要がある

最終的な選定

前述までの内容を加味して以下の選定をおこないました。

  • 汎用的なコンポーネントはMUIのコンポーネントをラップして剥がせるように組み込む
  • 動的なスタイリングはEmotionを使用する
  • MUIで対応できないスタティックなスタイリングはCSS Modules(Sass)を使用する

それぞれの採用理由を説明します。

MUIを採用する

フレームワークに乗っかることによりドキュメントに沿った書き方で統一性が保てることを期待しました。また、用意されたコンポーネントは作り込む工数が多少削減できそうです。独自でゼロから考えて作り込むよりもフレームワークはどのようなものが必要かしっかり練られた上で用意されている可能性が高いので参考になる点が多いという期待もあります。いろんなフレームワークがある中でMUIがある程度期待するコンポーネントを用意していたので採用しました。(今回はフレームワークごとの比較は割愛します。) どこまでカスタマイズできるかは触ってみないと見えてこないですが、コンポーネントごとにMUIを剥がしやすいような作りにすることで不安を解消することにしました。

Emotionを控えめに使用する

MUIで用意されたものにはないスタイルを設定する場合には、異なるツールを使う必要があります。MUIではEmotionをデフォルトで採用しています。EmotionはCSS-in-JSで動的なスタイリングをおこなう際に使い勝手が良いので、動的なスタイリングのみ使用する方針として控えめに採用しました。理由としては、基本的にjsxの部分にスタイルをあまり書きたくないためです。jsxはDOMの役割を持っていてスタイルとは役割を持っているのでそれぞれ役割が異なると考えます。スタイルを切り離すのであれば、CSS Modulesとして馴染みのあるSassで書いたほうがわかりやすいと考えました。

CSS Modules (Sass) で拡張する

CSS ModulesもMUIは対応しています。MUIで用意されたものだけで表現が難しいものに関してはCSS Modulesの形式でscssファイルを用意して使用することにしました。自由度が高いため、命名規則はBEM(MindBEMding)の形式で書くルールにしたり、stylelintでルールを設けて機械的にLintでルールから外れないように制限するなどの対策を合わせておこなうこととしました。

以上で技術選定において考えたこと、選定したツールの紹介でした。

さいごに

今回は前提を整理してツールの大まかな分類分けをおこなったり選定基準の観点から各ツールを評価するような技術選定をおこないました。もちろん技術選定のやり方は他にもいろんなやり方や考え方があると思います。開発後にほとんどメンテナンスを期待しないようなものであれば興味のあるツールや新しいツールに挑戦してみるのも良いと思います。
今回の内容はざっくりとした流れで書いているので、細かい部分で気になる点も多々あるかもしれません。もし気になった点があるということは私より視野が広いもしくは詳しい方だと思いますので、良ければ知っていることや調査したことなど、いろいろとコメントしていただければと思います。

Discussion