透過 100 多個提示學習 Nuxt!

delay-hydration
nuxt-delay-hydration

藉由延遲水合來改善您的 Nuxt v2 Google Lighthouse 分數。

nuxt-delay-hydration

NPM Downloads


狀態: 穩定 v2 v0 ✅ , v3 main
感謝我的 贊助計畫 💖 才得以實現
追蹤我 @harlan_zw 🐦

⚠️ 這是一種「hack」,用於欺騙 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'
  }
}

注意:除非您已啟用 debug,否則該模組不會在開發中執行。

選擇模式

預設情況下,未選取任何模式,您需要選擇您希望模組如何運作。

類型: init | mount| manual | false

預設值: false

類型描述使用案例
false 預設值停用模組測試
init延遲所有腳本載入。零或最少的外掛程式/模組。
mount 建議在 Nuxt 載入時延遲它。外掛程式和某些第三方腳本將會正常運作。最少量的非關鍵外掛程式和第三方外掛程式。
manual延遲由 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 模式或 regex。

事件水合

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 容量通常會比桌上型電腦少很多。

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

偵錯

debug

  • 類型:boolean
  • 預設值:false

在控制台中記錄水合何時被封鎖以及何時以及為什麼解除封鎖的詳細資訊。

基準測試

線上範例

貢獻者

贊助者

許可證

MIT 許可證 © 2022 - 現在 Harlan Wilton