React Content Fontでフォントの読み込みを効率化する
Published: 2023-07-19 15:21:40

Language:
- [English](https://dev.to/adbutterfield/making-font-loading-more-efficient-with-react-content-font-4bbd)
- [日本語](https://dev.to/adbutterfield/react-content-fontdehuontonodu-miip-miwoxiao-lu-hua-suru-20oo)
- [中文](https://dev.to/adbutterfield/shi-yong-react-content-fontti-gao-zi-ti-jia-zai-xiao-lu-3ink)

ウェブパフォーマンスにおいて、各キロバイトが重要です。開発者はユーザーのインターネット速度に関わらず、スムーズな体験を提供するために、アプリケーションを効率的にすることを常に目指しています。特に、日本語や中国語のような広範な文字セットを持つ言語のアプリケーションを開発する際には、通常大きなサイズのフォントを効率的に使用することが大きな関心事となります。

例えば、日本語の「Noto Sans Japanese」の単一のフォントウェイトだけでもファイルサイズは驚くべき5.7MBにもなります。このような大きなファイルをユーザーにダウンロードさせるのは理想的ではありません、さらに複数のフォントウェイトが必要な場合はなおさらです。ここで登場するのが、この問題に特化して開発されたパッケージ、[React Content Font](https://www.npmjs.com/package/react-content-font)です。

## React Content Fontとは何か？

[React Content Font](https://www.npmjs.com/package/react-content-font)はReactアプリケーション用に設計されたパッケージで、ウェブページをチェックしてそのページに含まれるユニークな文字のリストを取得し、その文字だけを含むフォントをGoogle Fontsからリクエストします。このプロセスは最適化されたリクエストを使用するため、必要な文字だけがロードされ、ユーザーがダウンロードする必要のあるデータを最小限に抑えます。

このパッケージは使いやすく、アプリケーションの高い位置にコンテクストプロバイダを追加するだけです。fontName propで欲しいフォントを指定すれば、デフォルトで正常な（つまり400の）ウェイトのフォントをリクエストします。

例えば、App Routerを使用したNext.jsアプリがある場合、`app/layout.tsx`ファイルを以下のように更新できます：
```tsx
import FontProvider from 'react-content-font';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="jp">
      <body>
        <FontProvider fontName="Noto Sans JP">{children}</FontProvider>
      </body>
    </html>
  );
}
```
複数のフォントウェイトが必要な場合、または一部のウェイトのイタリックバージョンが必要な場合でも、[React Content Font](https://www.npmjs.com/package/react-content-font)のfontWeights propで対応可能です。
```tsx
import FontProvider from 'react-content-font';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="jp">
      <body>
        <FontProvider fontName="Noto Sans JP" fontWeights={[400, 600]}>
          {children}
        </FontProvider>
      </body>
    </html>
  );
}
```
## さまざまなフォントニーズに対応

さらに、あなたがイタリックバリアントを持つ日本語のフォントを探しているかもしれません。それはあまり一般的ではありませんが、使用したいフォントにはその機能があるかもしれません。[React Content Font](https://www.npmjs.com/package/react-content-font)では、どのウェイトでもイタリックバリアントをリクエストすることができます。
```tsx
import FontProvider from 'react-content-font';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="jp">
      <body>
        <FontProvider
          fontName="Noto Sans JP"
          fontWeights={[400, 600, ['ital', 400], ['ital', 900]]}
        >
          {children}
        </FontProvider>
      </body>
    </html>
  );
}
```
また、このパッケージではfont-displayプロパティを指定することが可能です。このプロパティはフォントファイルのロードと表示方法を定義し、直接パフォーマンスを影響を与えます。
```tsx
import FontProvider from 'react-content-font';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="jp">
      <body>
        <FontProvider fontName="Noto Sans JP" display="block">
          {children}
        </FontProvider>
      </body>
    </html>
  );
}
```
## フォントのロード状態の確認

場合によっては、コンテンツを表示する前にフォントのロードを待ちたい場合や、ローディング状態を表示したい場合があります。[React Content Font](https://www.npmjs.com/package/react-content-font)はフォントのロード状態をフラグするフックを提供します。この機能により、フォントのロード状態に基づいてコンテンツの可視性を制御することができます。
```tsx
'use client';

import { useFontContext } from 'react-content-font';

export default function PageText() {
  const { isFontLoaded } = useFontContext();

  return (
    <p style={{ visibility: isFontLoaded ? 'visible' : 'hidden' }}>
      よそはほかまあこの威圧心というのの後をしないう。きっと場合で仕事帰りはひょろひょろその評でたなりでするが行くたをも表裏できなけれでば、なぜにはもっなないうた。個人にできたのはついに十月から向後ますだない。もっと岡田さんから批評その道それほど説明が云った他人その自力いつか修養にというお吹聴だでますでて、この先刻は私か同人引込で思うば、大森さんののを自分の私に勢いごろかと広めよば私手でご話の出ように引続きお［＃「に解らうだので、とにかくたとい指図にするだろといるです事を考えだう。
    </p>
  );
}
```
ただし、リクエストされたフォントに文字が含まれるように、テキストをレンダリングすることが重要です。

## フォントの更新の検出

[React Content Font](https://www.npmjs.com/package/react-content-font)はまた、フォントが更新されているかどうかを知ることを可能にします。これにより、アプリケーションのUXにさらなる制御を提供します。
```tsx
'use client';

import { useFontContext } from 'react-content-font';

export default function PageText() {
  const { isFontLoaded } = useFontContext();

  return (
    <>
      {isFontLoaded && (
        <p>
          よそはほかまあこの威圧心というのの後をしないう。きっと場合で仕事帰りはひょろひょろその評でたなりでするが行くたをも表裏できなけれでば、なぜにはもっなないうた。個人にできたのはついに十月から向後ますだない。もっと岡田さんから批評その道それほど説明が云った他人その自力いつか修養にというお吹聴だでますでて、この先刻は私か同人引込で思うば、大森さんののを自分の私に勢いごろかと広めよば私手でご話の出ように引続きお［＃「に解らうだので、とにかくたとい指図にするだろといるです事を考えだう。
        </p>
      )}
    </>
  )
}
```
こちらもロード状態の確認と同様に、文字がリクエストされたフォントに含まれるようにテキストをレンダリングする必要があります。

## あなたの意見を教えてください！

[React Content Font](https://www.npmjs.com/package/react-content-font)の開発者として、この旅は挑戦的でありながらも報われる経験でした。自分自身のために作ったものですが、他の人々もこれを使いたいと思うことでしょう。

あなたのプロジェクトでこのパッケージは役立ちましたか？改善できる箇所はありますか？あるいは、将来の拡張のための創造的なアイデアがありますか？あなたの意見を聞きたいです！