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

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

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

측정

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

  • 리믹스하여 수정을 클릭하여 프로젝트를 수정할 수 있도록 합니다.
  • 사이트를 미리 보려면 View App을 누른 다음 Fullscreen 전체 화면을 누릅니다.

이 웹사이트는 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 청크가 로드됩니다.

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

다음으로 이 사이트에 Quicklink를 구현하여 이러한 청크를 홈페이지에서 미리 가져올 수 있도록 하여 탐색 속도를 높입니다.

이렇게 하면 두 기법의 장점을 결합할 수 있습니다.

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

webpack-route-manifest 구성

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

일반적으로 라이브러리를 설치해야 하지만 이미 자동으로 설치되었습니다. 실행해야 할 명령어는 다음과 같습니다.

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');

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

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 앱을 여세요.

먼저 다음과 같이 빠른 링크 고차 구성요소 (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단계를 반복합니다. 아직 블로그 페이지로 이동하지 마세요.

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

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

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

다음:

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

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

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