通过 100+ 条技巧学习 Nuxt!
发布·  

Nuxt 脚本介绍

Nuxt 脚本为第三方脚本提供更佳的性能、隐私、安全和开发者体验。

Nuxt 团队与 Google 的 Chrome Aurora 团队合作,很高兴地宣布公开发布 Nuxt Scripts 的公开 Beta 版本。

Nuxt Scripts 是使用第三方脚本的更佳方式,可提供改进的性能、隐私、安全和开发者体验。

Nuxt Scripts Banner

开始使用 Nuxt Scripts

一年多以前,Daniel 发布了最初的 Nuxt Scripts RFC。该 RFC 提议创建一个模块,该模块将“允许管理和优化第三方脚本,遵循高性能和合规网站的最佳实践”。

凭借解决与第三方脚本相关的性能问题的 个人经验,我知道这些性能优化可能有多么困难。尽管如此,我仍然热衷于解决这个问题并接管了这个项目。

以 RFC 作为想法的种子,我开始原型化它可能 看起来的样子,使用了 Unhead

在思考我究竟想构建什么时,我发现真正的问题不仅仅是如何加载“优化过的”第三方脚本,而是如何使使用第三方脚本的整体体验更好。

为何构建第三方脚本模块?

94% 的网站至少使用一个第三方提供商,平均每个网站有 五个第三方提供商

我们知道第三方脚本并不完美;它们拖慢了网页速度,导致隐私和安全问题,并且难以使用。

然而,它们从根本上是有用的,并且在短期内不会消失。

通过探索第三方脚本的问题,我们可以看到可以在哪些方面进行改进。

😒 开发者体验:全栈难题

让我们逐步了解如何使用一个虚构的 tracker.js 脚本将第三方脚本添加到您的 Nuxt 应用程序中,该脚本向 window 添加了一个 track 函数。

我们首先使用 useHead 加载脚本。

useHead({ scripts: [{ src: '/tracker.js', defer: true }] })

但是,现在让我们尝试在我们的应用程序中使脚本功能正常工作。

以下是在 Nuxt 中使用第三方脚本时的常见步骤

  • 一切都必须为了 SSR 安全性而包裹起来。
  • 脚本是否已加载的不可靠检查。
  • 为了类型而增强 window 对象。
<script setup>
// ❌ Oops, window is not defined! 
// 💡 The window can't be directly accessed if we use SSR in Nuxt.
// 👉 We need to make this SSR safe
window.track('page_view', useRoute().path)
</script>

🐌 性能:“为什么我的 Lighthouse 得不到 100 分?”

为了让访问者开始与您的 Nuxt 网站互动,需要下载应用程序包,并且 Vue 需要水合应用程序实例。

即使在使用 asyncdefer 时,加载第三方脚本也可能会干扰此水合过程。这会减慢网络速度并阻塞主线程,从而导致用户体验下降和较差的 Core Web Vitals

Chrome 用户体验报告显示,具有大量第三方资源的 Nuxt 网站通常具有较差的 交互到下次绘制 (INP)最大内容渲染 (LCP) 分数。

为了了解第三方脚本如何降低性能,我们可以查看 Web Almanac 2022。《报告》显示,前 10 大第三方脚本的平均中位数阻塞时间为 1.4 秒

🛡️ 隐私与安全:不做恶事?

在前 10,000 个网站中,有 58% 的网站的第三方脚本会交换存储在外部 Cookie 中的跟踪 ID,这意味着即使禁用了第三方 Cookie,它们也可以跨网站跟踪用户。

虽然在许多情况下,我们对使用的提供商无能为力,但我们应尽可能尝试最大限度地减少泄露最终用户的数据量。

当我们确实考虑隐私影响时,可能很难在我们的隐私政策中准确传达这些信息,并构建符合 GDPR 等法规所需的同意管理。

使用第三方脚本时的安全性也是一个问题。第三方脚本是恶意行为者的常见攻击媒介,大多数脚本不提供其脚本的 integrity 哈希值,这意味着它们可能随时被入侵并将恶意代码注入到您的应用程序中。

Nuxt Scripts 如何解决这些问题?

组合式函数:useScript

此组合式函数位于 <script> 标签和添加到 window.{thirdPartyKey} 的功能之间。

对于 <script> 标签,此组合式函数

  • 完全可见脚本的加载和错误状态
  • 默认情况下,在 Nuxt 水合应用程序时加载脚本,以获得稍微更好的性能。
  • 限制 crossoriginreferrerpolicy 以提高隐私和安全性。
  • 提供一种延迟加载脚本直到您需要它的方法。

对于脚本 API,它

  • 围绕脚本函数提供完全的类型安全
  • 添加代理层,允许您的应用程序在不安全的环境(SSR、脚本加载之前、脚本被阻止)中运行脚本函数
const { proxy, onLoaded } = useScript('/hello.js', {
  trigger: 'onNuxtReady',
  use() {
    return window.helloWorld
  }
})

onLoaded(({ greeting }) => {
  // ✅ script is loaded! Hooks into Vue lifecycle
})

// ✅ OR use the proxy API - SSR friendly, called when script is loaded
proxy.greeting() // Hello, World!

declare global {
  interface Window {
    helloWorld: {
      greeting: () => 'Hello World!'
    }
  }
}

脚本注册表

脚本注册表是常见第三方脚本的第一方集成的集合。截至发布时,我们支持 21 个脚本,未来还将推出更多。

Nuxt Scripts Registry

这些注册表脚本是围绕 useScript 进行微调的封装器,具有完整的类型安全性、脚本选项的运行时验证(仅限开发环境)和环境变量支持

例如,我们可以查看 Fathom Analytics 脚本。

const { proxy } = useScriptFathomAnalytics({
  // ✅ options are validated at runtime
  site: undefined
})
// ✅ typed
proxy.trackPageview()

外观组件

注册表包含几个外观组件,例如 Google 地图YouTube 播放器Intercom

外观组件是“假的”组件,在第三方脚本加载时会被水合。外观组件有其权衡之处,但可以极大地提高您的性能。有关更多信息,请参阅什么是外观组件?指南。

Nuxt Scripts 提供外观组件作为可访问但无头组件,这意味着它们默认情况下没有样式,但添加了必要的 a16y 数据。

点击加载

点击视频将加载 YouTube iframe 并开始播放视频。

useScript 组合式函数使您可以完全控制脚本的加载方式和时间,方法是提供自定义的 trigger 或手动调用 load() 函数。

在此基础上,Nuxt Scripts 提供了更高级的触发器,使其更加容易。

  • 同意管理 - 仅在用户同意后加载脚本,例如通过 Cookie 横幅。
  • 元素事件触发器 - 根据用户交互(例如滚动、点击或表单提交)加载脚本。
const cookieConsentTrigger = useScriptTriggerConsent()
const { proxy } = useScript<{ greeting: () => void }>('/hello.js', {
  // script will only be loaded once the consent has been accepted
  trigger: cookieConsentTrigger
})
// ...
function acceptCookies() {
  cookieConsentTrigger.accept()
}
// greeting() is queued until the user accepts cookies
proxy.greeting()

捆绑脚本

在许多情况下,我们从不受我们控制的域加载第三方脚本。这可能会导致许多问题

  • 隐私:第三方脚本可以跨网站跟踪用户。
  • 安全:第三方脚本可能被入侵并注入恶意代码。
  • 性能:额外的 DNS 查询将减慢页面加载速度。
  • 开发者体验:已同意的脚本可能被广告拦截器阻止。

为了缓解这种情况,Nuxt Scripts 提供了一种将第三方脚本捆绑到您的 public 目录中的方法,而无需任何额外的工作。

useScript('https://cdn.jsdelivr.net.cn/npm/js-confetti@latest/dist/js-confetti.browser.js', {
  bundle: true,
})

现在,该脚本将从您自己域名的 /_scripts/{hash} 提供。

未完待续

正如我们所见,有很多机会可以改进第三方脚本,从而为开发者和最终用户带来更好的体验。

Nuxt Scripts 的初始版本已经解决了一些问题,但我们仍然有很多工作要做。

路线图上的下一个项目是

我们欢迎您的贡献和支持。

开始使用

为了开始使用 Nuxt Scripts,我们创建了一个教程,以帮助您快速入门和运行。

鸣谢

并衷心感谢早期的贡献者。

Nuxt Scripts Contributors