React.lazyを使うことでコンポーネントを非同期遅延ロードしつつ必要なのだけをロードする仕組みができるらしいのでやってみた

App.tsx

import React, { Suspense, useEffect } from 'react';

/*
importを使わずに動的にコンポーネントを遅延ロードさせて使う場合には以下の感じでやれば一応できるっちゃできるらしい

const LazyContent = React.lazy(() => {
  return new Promise<{ default: React.ComponentType }>((resolve) => {
    const Content = (): React.JSX.Element => {
      useEffect(() => {
        import("./main.css");
      }, []);

      return (<h1>Hello</h1>);
    };

    resolve({ default: Content });
  });
});
*/

const LazyContent = React.lazy(() => import("./Content"));

const App = (): React.JSX.Element => {
  return (
    <Suspense fallback={<div>loading...</div>}>
      <LazyContent />
    </Suspense>
  );
};

export default App;

React.lazyを使ってContent.tsxを非同期で遅延ロードする。その際に<Suspense>を使ってロードされるまでの仮のUIを表示する(ここでいうとfallbackの中のやつ)

Content.tsx

import './main.css';

const Content = (): React.JSX.Element => {
  return (
    <h1>Hello</h1>
  );
};

export default Content;

React.lazyで遅延ロードされるコンポーネントでは、そのコンポーネントがimportしているCSSファイルもViteによって生成された別ファイルとして自動でブラウザに<link>が挿入されCSSが適用される。通常のビルドでは、ViteのcssCodeSplit:true設定によりコンポーネントごとにCSSファイルが分割される。この場合に非lazyコンポーネントではHTML側に<link> を書く必要があるが、React.lazyを使うとJS側で自動的に挿入されるため手動で書く必要はない。

まあそんな感じ

余談

ちなみになんだが、例えばreact-routerなどを使用してページAが使用するコンポーネントが描画されてそれのCSSも<link>が挿入され、その後に別のページのページBとかを表示してコンポーネントが描画される際には前のページが使ってたコンポーネントのCSSとかが外されたりはしないらしい