Quicklink를 사용하여 React 앱 만들기에서 미리 가져오기

Addy Osmani
Addy Osmani
Anton Karlovskiy
Anton Karlovskiy
Demián Renzulli
Demián Renzulli

이 Codelab에서는 React SPA 데모에서 Quicklink 라이브러리를 구현하여 미리 가져오기로 후속 탐색의 속도를 높이는 방법을 보여줍니다.

측정

최적화를 추가하기 전에 항상 애플리케이션의 현재 상태를 먼저 분석하는 것이 좋습니다.

  • 수정할 리믹스를 클릭하여 프로젝트를 수정할 수 있도록 합니다.
  • 사이트를 미리 보려면 앱 보기를 누릅니다. 그런 다음 전체 화면 전체 화면입니다.

이 웹사이트는 create-react-app으로 빌드된 간단한 데모입니다.

방금 열린 새 탭에서 다음 안내를 완료합니다.

  1. `Control+Shift+J` (또는 Mac의 경우 `Command+Option+J`)를 눌러 DevTools를 엽니다.
  2. 네트워크 탭을 클릭합니다.
  3. 캐시 사용 중지 체크박스를 선택합니다.
  4. 제한 드롭다운 목록에서 Fast 3G를 선택하여 느린 연결 유형을 시뮬레이션합니다.
  5. 앱을 새로고침합니다.
  6. 필터 텍스트 상자chunk를 입력하여 이름에 chunk이 포함되지 않은 리소스를 숨깁니다.

홈페이지 청크를 보여주는 네트워크 패널

이 사이트에서는 경로 기반 코드 분할을 사용하며, 이로 인해 처음에 필요한 코드만 요청됩니다.

  1. DevTools에서 네트워크 요청을 지웁니다.
  2. 앱에서 블로그 링크를 클릭하여 해당 페이지로 이동합니다.

새 경로의 JS 및 CSS 청크가 로드되어 페이지를 렌더링합니다.

블로그 페이지 청크를 보여주는 네트워크 패널

그런 다음, 홈페이지에서 이러한 단위를 미리 가져올 수 있도록 이 사이트에 퀵링크를 구현하여 탐색 속도를 높입니다.

이를 통해 두 기술의 장점을 결합할 수 있습니다.

  • 경로 기반 코드 분할은 페이지 로드 시 더 높은 우선순위로 필요한 청크만 로드하도록 브라우저에 지시합니다.
  • 미리 가져오기는 브라우저가 유휴 상태일 때 가장 낮은 우선순위로 표시 영역 내 링크의 청크를 로드하도록 브라우저에 지시합니다.

webpack-route-manifest 구성

첫 번째 단계는 경로를 해당 청크와 연결하는 매니페스트 파일을 생성할 수 있게 해주는 webpack 플러그인인 webpack-route-manifest를 설치하고 구성하는 것입니다.

일반적으로는 라이브러리를 설치해야 하지만, Google에서는 이미 설치되어 있습니다. 실행해야 하는 명령어는 다음과 같습니다.

npm install webpack-route-manifest --save-dev

config-overrides.js는 프로젝트 루트 디렉터리에 있는 파일로, 프로젝트를 퇴장하지 않고도 웹훅 구성의 기존 동작을 재정의할 수 있습니다.

  • 소스를 보려면 소스 보기를 누릅니다.

수정을 위해 config-overrides.js를 열고 파일 시작 부분에 webpack-route-manifest 종속 항목을 추가합니다.

const path = require('path');
const RouteManifest = require('webpack-route-manifest');

다음으로 다음을 추가하여 webpack-route-manifest 플러그인을 구성합니다. 코드를 config-overrides.js 하단에 추가합니다.

module.exports = function override(config) {
  config.resolve = {
    ...config.resolve,
    alias: {
      '@assets': `${path.resolve(__dirname, 'src/assets')}`,
      '@pages': `${path.resolve(__dirname, 'src/pages')}`,
      '@components': `${path.resolve(__dirname, 'src/components')}`,
    },
  };

  config.plugins.push(
    new RouteManifest({
      minify: true,
      filename: 'rmanifest.json',
      routes(str) {
        let out = str.replace('@pages', '').toLowerCase();
        if (out === '/article') return '/blog/:title';
        if (out === '/home') return '/';
        return out;
      },
    }),
  );

  return config;
};

새 코드는 다음 작업을 실행합니다.

  • config.resolve는 페이지, 애셋, 구성요소에 대한 내부 경로를 사용하여 변수를 선언합니다.
  • config.plugins.push()는 사이트의 경로와 청크를 기반으로 rmanifest.json 파일이 생성될 수 있도록 RouteManifest 객체를 만들고 구성을 전달합니다.

manifest.json 파일이 생성되어 https://site_url/rmanifest.json에서 사용할 수 있습니다.

이 시점에서는 프로젝트에 Quicklink 라이브러리를 설치해야 합니다. 편의상 이미 프로젝트에 추가했습니다. 실행해야 하는 명령어는 다음과 같습니다.

npm install --save quicklink

수정하려면 src/components/App/index.js를 엽니다.

먼저 Quicklink 고차 구성요소 (HOC)를 가져옵니다.

import React, { lazy, Suspense } from 'react';
import { Route } from 'react-router-dom';

import Footer from '@components/Footer';
import Hero from '@components/Hero';
import style from './index.module.css';
import { withQuicklink } from 'quicklink/dist/react/hoc.js';

const Home = lazy(() => import(/* webpackChunkName: "home" */ '@pages/Home'));
const About = lazy(() => import(/* webpackChunkName: "about" */ '@pages/About'));
const Article = lazy(() => import(/* webpackChunkName: "article" */ '@pages/Article'));
const Blog = lazy(() => import(/* webpackChunkName: "blog" */ '@pages/Blog'));

다음으로 Blog 변수 선언 뒤에 quicklink를 호출할 때 인수로 사용할 options 객체를 만듭니다.

const options = {
    origins: []
};

마지막으로 각 경로를 withQuicklink() 고차 구성요소로 래핑하고 options 매개변수와 해당 경로의 타겟 구성요소를 전달합니다.

const App = () => (
  <div className={style.app}>
    <Hero />
    <main className={style.wrapper}>
      <Suspense fallback={<div>Loading...</div>}>
        <Route path="/" exact component={withQuicklink(Home, options)} />
        <Route path="/blog" exact component={withQuicklink(Blog, options)} />
        <Route
          path="/blog/:title"
          component={withQuicklink(Article, options)}
        />
        <Route path="/about" exact component={withQuicklink(About, options)} />
      </Suspense>
    </main>
    <Footer />
  </div>
);

이전 코드는 링크가 뷰에 들어올 때 withQuicklink()로 래핑된 경로의 청크를 미리 가져오도록 지시합니다.

다시 측정

측정에서 처음 6단계를 반복합니다. 아직 블로그 페이지로 이동하지 마세요.

홈페이지가 로드되면 해당 경로의 청크가 로드됩니다. 그런 다음 Quicklink는 표시 영역 내 링크에 대한 경로의 청크를 미리 가져옵니다.

홈페이지 미리 가져오기 청크를 보여주는 네트워크 패널

이러한 청크는 가장 낮은 우선순위로 요청되며 페이지를 차단하지 않습니다.

다음:

  1. 네트워크 로그를 다시 지웁니다.
  2. 캐시 사용 중지 체크박스를 선택 해제합니다.
  3. 블로그 링크를 클릭하여 해당 페이지로 이동합니다.

캐시에서 선택한 청크가 포함된 블로그 페이지를 보여주는 네트워크 패널

크기 열은 이러한 청크가 네트워크가 아닌 '미리 가져오기 캐시'에서 검색되었음을 나타냅니다. 퀵링크 없이 이 청크를 로드하는 데 약 580ms가 걸렸습니다. 라이브러리를 사용하면 이제 2ms가 걸려 99% 감소합니다.