LoginSignup
6
3

More than 1 year has passed since last update.

自作サイトを自作ライブラリで5倍読み込み速度を高速化した話

Last updated at Posted at 2022-11-21

こんにちは。ぬこすけ です。

随分前なのですが、 React で手軽にサイトを高速化できるライブラリ react-dom-lazyload-component を作って公開しました。

ふと、「本当に サイト高速化の効果があるのか? 」と思い、自作サイトに react-dom-lazyload-component を使ってみました。

自作ライブラリが本当にサイト高速化に役立つのか、検証したいと思います。

react-dom-lazyload-component ってどんなライブラリ?

ブラウザの決まった枠内に入るまで DOM を非表示にするライブラリです

IntersectionObserver というブラウザ API をご存知の方はピンと来るかもしれません。

スクリーンショット 2022-11-18 9.04.12.png

上の画像のように、 Viewport という領域があります。
Viewport という領域は自分で調整できますが、一旦、ユーザーが開いているブラウザの表示領域だと思ってください。

ユーザーがブラウザをスクロールしていき、赤い四角の「 Visible!! 」のように対象の DOM が Viewport に入ると DOM が描画されます。

一方で Viewport 外の DOM はグレー四角の「 Invisible 」のように DOM は描画されません。

こうすることで 必要なタイミングで必要な UI だけ描画 されるようになり、 サイトの表示高速化 が期待されます。

特に、 必要なタイミングで UI 描画に必要なリソース( JavaScript など)を取得 するようにすれば 初期描画の高速化 もできます。

自作したサイトってどんなサイト?

この react-dom-lazyload-component の実験台の対象となるのは「 Instagram Hashtag Translator 」 というサイトです。

どんなサイトかいうと、 インスタグラムの投稿で外国語でハッシュタグをつけたい時に、インスタグラム向けにハッシュタグを翻訳し、コピペして投稿できるようにするツール です。

例えば、「猫 カフェ」で英語も含めてハッシュタグを用意したい場合は、「#猫 #カフェ #cat #cafe」という形でアウトプットを出してくれます。

chrome-capture-2022-10-18 (1).gif

企画の背景や技術スタックなど、詳しい話は Qiita の記事 でまとめているので、ご興味あればご覧ください。

いざ、検証!の前に

自作ライブラリを使ってどのくらいサイト高速化できるか検証する前に、Instagram Hashtag Translator の簡単な前提条件を確認しておきましょう。

  • 使っている主なライブラリとバージョン
    • React v18.2.0
    • Next.js v13.0.3
      • app Directory といった v13 の最新機能は使っていません。
  • インフラ
    • Vercel

また、 react-dom-lazyload-component の導入前の PageSpeed Insights の実行結果は次の通りです。

  • PC
    before-pc.png

  • モバイル
    before-sp.png

遅い!笑

ここからどのくらい高速化するのか、見ていきましょう!

react-dom-lazyload-component を使った実装

どのように実装していくかも触れておきます。
次のような react-dom-lazyload-component をラップしたコンポーネントを用意します。

import { FC, ReactNode } from 'react';
import LazyLoad, { LazyLoadProps } from 'react-dom-lazyload-component';
import LoadingIcon from '~/components/atoms/icons/LoadingIcon';

type LazyProps = Pick<LazyLoadProps, 'as' | 'suspense'> & {
  readonly className?: string;
  readonly children: ReactNode;
  readonly id?: string;
};

const Lazy: FC<LazyProps> = ({ className, children, as, suspense, id }) => (
  <LazyLoad
    className={className}
    as={as} // div や span など使いたいタグ名。 
    fallback={<LoadingIcon />} // Viewport 外で表示する UI と React.Suspense の fallback
    suspense={suspense} // React.Suspense を使うかどうか
    id={id} // DOM の id
  >
    {children}
  </LazyLoad>
);

export default Lazy;

この Lazy コンポーネントはブラウザの表示領域に入るまで LoadingIcon という読み込み中の UI を表示し、表示領域に入ると children を表示させます。

Lazy を使う側として、ユーザーのファーストビューで表示されないフッターのコンポーネント例をあげます。

import dynamic from 'next/dynamic';
import { FC } from 'react';
import Lazy from '~/components/atoms/Lazy';

const Copyright = dynamic(() => import('~/components/atoms/Copyright'), {
  suspense: true,
});

const Footer: FC = (): JSX.Element => (
  <Lazy
    className='クラス名入れる'
    as='footer'
    suspense
  >
    <Copyright />
  </Lazy>
);

export default Footer;

この Footer コンポーネントはブラウザの表示領域に入った瞬間に表示されます。

1つポイントとしては next/dynamic を使ってコンポーネントの遅延読み込み をしている点です。

このようにすることで、Footer コンポーネントがブラウザの表示領域に入った時に初めて Copyright コンポーネントが読み込まれるため、 初期描画が早くなるメリット があります。

next/dynamic を使った例ですが、 React.lazy を使っても良いでしょう。

このフッターのようにユーザーのファーストビューで表示されないコンポーネントを react-dom-lazyload-componentnext/dynamic を組み合わせて修正をしていきます。

react-dom-lazyload-component を使った結果

PageSpeed Insights の結果はこうなりました!

  • PC
    after-pc.png

  • モバイル
    after-sp.png

PC は 39 → 70 に爆上がりしました 。良さげです🥳。
「読み込み中」の UI ( LoadingIcon ) で高さを指定をしていないので、「 Cumulative Layout Shift 」 は上がっちゃいました😜。

モバイルは 34 → 45 なのでスコア的にはそこまでアップしていませんが、 「 First Contenful Paint 」 や 「 Speed Index 」などの各指標が 4 ~ 5 倍ほど改善 されています。
これもまた良さげです🥳。

まとめ

自分で作ったサイト「 Instagram Hashtag Translator 」 を、これもまた自分で作ったライブラリ「 react-dom-lazyload-component 」を使ってサイトを高速化するお話でした。

ぜひ react-dom-lazyload-component を使ってみてください!

もしバグや使い方がわからない場合は日本語でも OK なので、 Github の issue なりにコメントいただければと思います!

今回は React のパフォーマンス改善例でしたが、フロントエンド全般のパフォーマンス改善のハウツーをまとめた記事もあるので、こちらもご参考にしていただければと思います!

最後に Twitter もやっているのでぜひフォローください!

ここまでご覧いただきありがとうございました!

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3