透過 Quicklink 在建立回應應用程式中預先擷取

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

本程式碼研究室說明如何在 React SPA 示範中實作 Quicklink 程式庫,示範預先擷取如何加快後續瀏覽的速度。

測量

新增最佳化之前,最好先分析應用程式的目前狀態。

  • 按一下「Remix to Edit」即可編輯專案。
  • 如要預覽網站,請按下「查看應用程式」。然後按下 全螢幕 全螢幕

這個網站是利用 create-react-app 建立的簡易示範,

在新開啟的分頁中完成下列操作:

  1. 按下 Control+Shift+J 鍵 (或在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
  2. 按一下 [網路] 分頁標籤。
  3. 勾選「停用快取」核取方塊。
  4. 在「Throttling」下拉式清單中選取「Fast 3G」,模擬緩慢連線類型。
  5. 重新載入應用程式。
  6. 在「篩選文字方塊」中輸入 chunk,即可隱藏名稱不含 chunk 的所有資源。

顯示首頁區塊的網路面板。

網站採用路徑式程式碼分割,因為一開始只會要求必要的程式碼。

  1. 清除開發人員工具中的網路要求
  2. 在應用程式中按一下「網誌」連結,即可前往該頁面。

系統會載入新路徑的 JS 和 CSS 區塊以轉譯頁面。

顯示網誌頁面區塊的網路面板。

接下來,您要在這個網站中實作 Quicklink,以便在首頁預先擷取這些區塊,加快瀏覽速度。

因此您可以結合使用這兩種技術的優勢:

  • 路徑式程式碼分割功能會指示瀏覽器在網頁載入時,只以較高的優先順序載入必要的區塊。
  • 預先擷取功能會指示瀏覽器在瀏覽器閒置期間,以最低的優先順序載入可視區域連結的區塊。

設定「webpack-route-manifest

首先,請安裝並設定 webpack-route-manifest;這個 Webpack 外掛程式可讓您產生資訊清單檔案,以建立路徑與其對應區塊建立關聯。

通常需要安裝此程式庫,但我們已替您完成安裝。您需要執行的指令如下:

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

config-overrides.js 是存放在您專案根目錄中的檔案,可讓您覆寫 Webpack 設定的現有行為,而不必退出專案

  • 如要查看來源,請按下「檢視來源」

開啟 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() 會建立 RouteManifest 物件並傳遞設定,以便根據網站的路徑和區塊產生 rmanifest.json 檔案。

系統會產生 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 變數宣告後方建立 options 物件,以便在呼叫 quicklink 時做為引數使用:

const options = {
    origins: []
};

最後,請使用較高順序元件來納入每個路徑,並向其傳遞 options 參數和該路徑的目標元件:withQuicklink()

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. 按一下 [網誌] 連結即可前往該頁面。

網誌頁面的網路面板,其中含有從快取擷取的區塊。

「大小」資料欄顯示這些區塊是從「預先擷取快取」(而非網路) 擷取。在沒有 Quicklink 的情況下載入這些區塊,大約需要 580 毫秒。使用程式庫現在需要 2 毫秒,這代表減少 99%