遅延負荷成分を持つCLSの双対性


あなたのWebアプリを最適化するとき、あなたの目標は、ユーザーのための経験をより良いものにすることです:それは、より少ないデータを転送して解析することによって、通常「速く」を意味します.しかし注意:同じWebアプリケーションは、より遅い接続上で累積レイアウトシフト(CLS)を引き起こすことができますが、高速接続でCLSなしで実行します.
あなたがコアウェブvitalsについての再会を望むならば、私はthis postでGIFと彼らに説明しました.

TL;DR: slower connections can result in CLS when lazy loading components that you wouldn't see on wifi connections.

Either don't lazy load the component at all or await for the js file to be loaded and mounted.


双対性



我々は、Webアプリは低速接続で同じようにロードすると仮定すると、遅くなります.残念なことに、それは怠惰なロード可能なコンポーネントで常にケースでありません.
怠惰なロード可能なコンポーネントで、我々は2つの非同期に対処します:
  • async APIレスポンス( JSON )
  • 非同期レイジーローディングコンポーネント( JS )
  • API応答(1)が動的にロードされたJS(2)より速いならば、どうですか?あなたのウェブコンテンツの真ん中にあるコンポーネントを怠惰に読み込む場合はどうですか?上記のscreencaptureで見るこれらの質問への答え:GoogleはCLSであなたを罰します.

    CLS測定


    私はコアウェブvitals、特にCLSについて多くの混乱を見ました.
    他のコアWeb vitalsとは異なり、CLSは継続的に測定され、累積的にスコアに追加されます.古典的なスパのWebアプリケーションのため、これはGoogleは、ルートごとにCLSのスコアを維持することを意味します.
    CLSには以下の特徴があります.
    各々のルートが変化したあと、CLSは0 にリセットされます
    どんなユーザーインタラクションの後でも、あなたはCLSがアカウントにとられない500 msの猶予期間を得ます

    Measurements by real users: Chrome users send Core Web Vitals metrics to Google directly. It's not a Googlebot that captures these metrics while crawling the site.

    These real user measurements are collected as Field Data and flow into Google's CrUX report.


    つまり、現実の世界を考慮に入れる必要があるということです.
  • あなたがインドから多くのトラフィックを持っているならば、あなたのサーバーは世界の他の端にあります、あなたのLCP(最大のcontentfulなペンキ)が多分苦しむでしょう.
  • 中国からのトラフィックが多いなら、一部のサービスが中国のISPによってブロックされ、ロードされないでしょう.これはあなたのコンテンツ内の不要なCLSを引き起こす可能性があります.
  • 解決策


    我々は、何の時にユーザーに表示するかを完全に制御する必要があります.二重性を念頭に置いて、次のことを知る必要があります.
  • APIリクエストはまだ読み込まれますか?
  • Asyncコンポーネントはまだ読み込まれますか?
  • スケルトンローダは、APIリクエストと非同期コンポーネントの両方が準備ができているまで待つ理想的な方法です.

    1 :怠惰な負荷成分をすべてではいけません


    最も速いエラーの最も簡単な解決策は、怠惰な読み込みコンポーネントを通過することです.ほとんどの場合、怠惰な読み込みを通して保存されたキロバイトは、それが引き起こすかもしれないCLSを正当化しません.あなたのパフォーマンスの予算がそれを許可する場合は、このソリューションを移動します.
    我々は10 %のログインユーザーとWebアプリケーションを持っていると仮定しましょう.
    function render() {
        // not all users require to download and render HugeComponent
        if (isLoggedIn) {
            return <HugeComponent />;
        }
    }
    
    コード分割なしで、我々はそれを必要としないユーザーの90 %に<HugeComponent>のJSを送ります.これはlcpとfidに影響する.
    コード分割によって、<HugeComponent>のJSを追加コンペに詰め込みます.JSチャンクは、それが必要であるとき、ワイヤーの上にそれを送ります.
    // without code splitting
    import HugeComponent from '@/components/HugeComponent';
    
    // with code splitting
    const HugeComponent = () => (await import(
        /* webpackChunkName: "additional-comps" */ 
        '@/components/HugeComponent')
    ).default;
    
    コンポーネントを怠惰に読み込むかどうかを決める2つの基準があります.
  • のサイズ
  • は、ユーザー
  • のためにしばしばしばしばレンダリングされるでしょう
    パフォーマンスの予算が厳しいという結論に達した場合、コンポーネントを遅延的に読み込む必要があります.

    コンポーネント1:コンポーネントのロードとマウントを待つ


    お使いのコンポーネントがユーザーの大部分のために使用されていない場合、それは多くのバンドルを増やすだろう、このソリューションを見てください.
    非同期コンポーネントをLazlyにロードしてマウントするのを待ちます.コンポーネントをレンダリングする必要がありますが、実装は後で発生します.ここでどのように行うことができるの要点です.
    function Parent({ isLoggedIn }) {
        const [isLoading, setLoading] = useState(false);
        // important: only hide the children with display: none.
        // if we used if-else, we'd never load the lazy loadable component;
        // and then we'd never change isLoading with its callback.
        const styles = { display: isLoading ? 'none' : 'block' };
    
        return (
            {/* HugeComponent is lazy loaded, because not all users will need it */}
            (isLoggedIn && <HugeComponent 
                style={ styles } 
                mounted={() => setLoading(true)}
            />)
    
            {/* display skeleton element for time of loading */}
            (isLoading && <div className="skeleton-loader"></div>)
        );
    }
    
    
    function HugeComponent(props: { mounted: () => void }) {
        const [dataA, setData] = useState(null);
    
        useEffect(async () => {
            const result = await lib.request();
            setData(result);
            // tell the parent component that everything is ready to be fully rendered
            props.mounted();
        }, []);
    
        return (/* ... */);
    }
    
    display: hiddenのローディング状態に対して<HugeComponent>を使用しなかった場合は、asyncコンポーネントのロードをトリガーしません.したがって、ライン28は決して到達することができません、そして、isLoading州は永久にfalseにとどまります.

    結論


    あなたがCLSのためにGoogle Search Consoleで緑のURLを失ったとき、あなたはそれを自分で再現することはできません、より遅い接続であなたのWebアプリをデバッグしてみてください.
    それで、あなたが怠惰なロード可能な構成要素を使用しているならば、可能性はCLSの双対性の犠牲者であるかもしれない高いです.