delay-hydration
nuxt-delay-hydration

透過延遲水合作用來提高您的 Nuxt v2 Google Lighthouse 分數。

nuxt-delay-hydration

NPM Downloads


狀態: 穩定版 v2 v0 ✅ , v3 主分支
感謝我的 贊助計劃 💖
關注我 @harlan_zw 🐦

⚠️ 這是一個“技巧”,旨在讓 Google Lighthouse 認為您的網站比實際速度更快。

  • 它只應在漸進式增強網站中使用。
  • 它可能不會提供任何實際的效能或 SEO 優勢(請使用 CrUX 進行測試,而不是 Google Lighthouse)。

功能

  • 🔥 減少您網站的“阻塞時間”
  • 🚦 使用路由規則進行逐頁配置
  • 🔁 (可選)重播水合前點選

為什麼要延遲水合作用?

延遲水合作用是一種向 Google 提示我們的指令碼並非應用程式正常執行所必需的技術。

透過延遲水合作用,我們可以減少“阻塞時間”指標,從而提高 Google Lighthouse 分數。

以前您可能使用過 vue-lazy-hydration,它執行良好。但是,它只是提供給 Google 提示的一種更詳細的方式,就像我們使用此模組一樣。


什麼是漸進式增強應用程式?

漸進式增強應用程式是旨在無需 JavaScript 即可執行,然後逐步透過 JavaScript 進行增強的應用程式。

您的指令碼不應是使用網站所必需的,這正是我們透過延遲水合作用向 Google 提示的。

為此,您可以確保

  • 初始響應中提供了完整的 HTML
  • 指令碼不會觸發 CLS
  • 避免使用指令碼設定影像,這會影響 LCP

此模組的工作原理
一個 Promise 被注入到您的應用程式中,其位置取決於模式。一旦以下任一事件觸發,該 Promise 就會被解析:
  • 互動事件(滑鼠移動、滾動、點選等)
  • 帶有固定超時的空閒回撥

空閒的 CPU 時間向 Google 提示這些指令碼並非應用程式執行所必需。

例如

  • 如果 Google 機器人訪問頁面且沒有互動,預設情況下,水合作用不會發生,直到瀏覽器空閒回撥 + 6 秒
  • 如果使用者訪問頁面並移動游標或滾動,水合作用將立即觸發。與未水合應用程式互動的機會將最小化

請記住,這是一個投機取巧的解決方案。在 Google 能夠識別漸進式指令碼增強之前,我們需要依靠這種方法。


安裝

如果您使用的是 Nuxt 2.x,請參閱 v0 分支上的文件。⚠️ Nuxt 2 已棄用,將不再獲得支援。

npx nuxi@latest module add delay-hydration

要求:漸進式增強的 SSR 或 SSG Nuxt 應用程式。


使用

// nuxt.config.ts
export default {
  modules: [
    'nuxt-delay-hydration',
  ],
  delayHydration: {
    // enables nuxt-delay-hydration in dev mode for testing
    // NOTE: you should disable this once you've finished testing, it will break HMR
    debug: process.env.NODE_ENV === 'development'
  }
}

注意:除非您啟用了 除錯,否則該模組在開發模式下不會執行。

選擇模式

預設情況下,未選擇任何模式,您需要選擇模組的工作方式。

型別: init | mount| manual | false

預設值: false

型別描述用例
false 預設停用模組測試
init延遲所有指令碼的載入。零或極少外掛/模組。
mount 推薦在 Nuxt 掛載時延遲。外掛和一些第三方指令碼將正常工作。最小的非關鍵外掛和第三方外掛。
手動延遲由 DelayHydration 元件提供。所有其他應用程式

無論您選擇哪種模式,請閱讀 進一步最佳化

初始化模式

此模式會延遲所有指令碼的載入,直到水合 Promise 被解析。

它透過鉤住 HTML 渲染,移除所有指令碼標籤並在水合 Promise 被解析後重新新增它們來實現此目的。

這將提供最大的速度提升,但風險也最大。

優點: 提供最大的阻塞時間減少

缺點: 如果您有關鍵的第三方指令碼,則存在風險

基準: 約 90-100% 減少

export default {
  delayHydration: {
    mode: 'init'
  }
}

掛載模式

此模式會在 Nuxt 掛載時延遲。外掛和一些第三方指令碼將正常工作。

這將延遲您的佈局和頁面元件。

優點: 更安全,仍然提供良好的改進

缺點: 如果某些佈局依賴於 JS,仍然可能導致它們崩潰。

基準: 約 70% 減少

export default {
  delayHydration: {
    mode: 'mount'
  }
}

手動模式

使用手動模式,您可以手動指定要延遲應用程式的哪個部分。當您需要頁面某些部分始終立即水合時(例如導航抽屜)非常有用。

優點: 最安全的最佳化方式

缺點: 速度提升取決於使用情況

export default {
  delayHydration: {
    mode: 'manual'
  }
}

DelayHydration 元件

設定模式後,您需要使用該元件。

<template>
  <div>
    <DelayHydration>
      <div>
        <LazyMyExpensiveComponent />
      </div>
    </DelayHydration>
  </div>
</template>

指南

按頁配置

您可以使用路由規則對模組進行按頁配置。

// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    // delay the home page
    '/': { delayHydration: 'mount' },
    // disable the module for the admin
    '/admin/': { delayHydration: false }
  }
})

您還可以使用 defineRouteRules 在頁面級別定義它們。

除錯

除錯模式
建議您在將模組部署到生產環境之前,對應用程式進行徹底測試。

為了確保模組按您的預期工作,有一個 debug 模式,啟用後它將在控制檯中記錄行為。

在本地環境中始終進行除錯可能是一個好主意,在這種情況下,您可以這樣做

export default defineNuxtConfig({
  delayHydration: {
    debug: process.env.NODE_ENV === 'development',
  },
})

視覺化水合狀態
如果您的應用程式相當靜態,有時可能不清楚它是否已水合,這會使除錯變得困難。

為了簡化操作,有一個元件 HydrationStatus,它會告訴您正在發生什麼。

<template>
  <div>
    <MyHeader />
    <DelayHydration>
      <div>
        <!-- Show the hydration status, only for debugging -->
        <HydrationStatus />
        <main>
          <nuxt />
        </main>
        <my-footer />
      </div>
    </DelayHydration>
  </div>
</template>

效能審計

使用我的審計工具:https://unlighthouse.dev/

重播水合點選

這是什麼以及如何啟用
延遲水合作用的一個問題是,使用者互動事件可能在指令碼載入之前發生,導致使用者必須多次點選才能實現預期操作。試想一下一個使用 Javascript 觸發的漢堡選單,如果您的應用程式未水合,那麼點選它將沒有任何作用。

最好的解決方案是以不需要 Javascript 即可互動的方式編寫您的 HTML

然而,在某些使用場景中,您需要使用 Javascript,並且對第一次點選做出響應非常重要。在這種情況下,您可以啟用點選重播。

export default defineNuxtConfig({
  delayHydration: {
    replayClick: true
  },
})

這是一個實驗性配置,您應該在將其部署到生產應用程式之前自行測試此選項。

進一步最佳化

非同步載入重量級元件
當您同步載入重量級元件時,JavaScript 將與主應用程式負載捆綁在一起。

這將降低您的所有效能指標。建議您對這些元件使用非同步匯入。

執行 nuxi analyze 以查詢大型元件。載入它們時,請在它們前面加上 Lazy

高階配置

配置應在您的 Nuxt 配置中的 delayHydration 鍵下提供。

如果您發現實驗室或實際資料的效能不佳,您可能需要調整此高階配置。

過濾路由

注意:建議使用路由規則而不是這些過濾選項。

使用 includeexclude 選項,您可以指定要延遲水合作用的路由。

// nuxt.config.ts
export default defineNuxtConfig({
  delayHydration: {
    include: [
      '/blog/**',
    ],
    exclude: [
      '/admin/**'
    ],
  },
})

您可以提供一個類似於路由規則的 glob 模式或一個正則表示式。

事件水合

hydrateOnEvents

  • 型別: string[]
  • 預設值: [ 'mousemove', 'scroll', 'keydown', 'click', 'touchstart', 'wheel' ]

控制哪些瀏覽器事件應觸發水合作用恢復。預設情況下,它相當激進,以避免可能的使用者體驗問題。

replayClick

  • 型別:boolean
  • 預設值:false

如果水合作用的觸發器是點選,您可以重播它。重播它將在您的應用程式被水合後重新執行該事件。

例如,如果使用者點選了一個漢堡圖示,並且需要水合作用才能開啟選單,那麼在水合完成後它會重播點選。

⚠️ 這是實驗性的,請謹慎使用。

空閒水合

idleCallbackTimeout

  • 型別: number (毫秒)
  • 預設值: 7000

在等待空閒回撥時,可以定義一個最長等待時間(毫秒)。當發生大量網路請求時,這很有用。

postIdleTimeout

  • 型別: { mobile: number, desktop: number } (毫秒)
  • 預設值: { mobile: 5000, desktop: 4000, }

在空閒回撥之後需要等待多長時間(以毫秒為單位)才能恢復水合作用。這個額外的超時是必要的,以避免標準的“阻塞”,我們需要向 Lighthouse 提供真正的空閒時間。

移動裝置的時間應始終高於桌面裝置,因為移動裝置的 CPU 容量通常會比桌面裝置低得多。

注意:預設值未來可能會根據進一步的基準測試進行調整。

除錯

除錯

  • 型別:boolean
  • 預設值:false

在控制檯中記錄水合作用何時被阻塞以及何時何地解除阻塞的詳細資訊。

基準

即時示例

鳴謝

贊助商

許可證

MIT 許可證 © 2022 - 至今 Harlan Wilton