乐趣区

关于前端:译Vuejs-Astro-比-Vue-SPA-更好吗

最近有很多开发者发表他们曾经将网站迁徙到 Astro。这通常随同着一张靠近完满的 Lighthouse 分数的截图和一系列火箭表情符号。

像大多数人一样,我发现无休止的新框架会让人感到厌倦。但我对 Astro 做了一些钻研,认为它真的值得一试。

在本文中,我将向您展现如何应用 Astro 构建基于 Vue 的应用程序,咱们将理解其独特的架构如何带来比单页应用程序 (SPA) 更好的性能。

SPA 架构回顾

在咱们看到 Astro 的理论利用之前,咱们须要理解它的架构。为此,让咱们首先揭示本人单页利用架构的优缺点。

SPA 将网站的所有性能和内容形象为 JavaScript 组件。这很棒,因为它使网站的开发变得容易。

这种办法的毛病是当网站投入生产时。所有这些 JavaScript 组件被捆绑在一起成为一个大的应用程序。因为体积太大,浏览器下载和运行的速度可能会很慢。

当然,你能够通过代码拆分来优化这个捆绑。然而,浏览器依然会有一些后期老本必须领取,只是为了启动网站。

<!-- 典型的 SPA 页面 -->
<head>
  <script src="/app.js"></script>
</head>
<body>
<!-- 在 app.js 加载之前,此页面没有有意义的内容 -->
<div id="app"></div>
</body>

Islands architecture

Islands 架构,Astro 应用的架构,也应用了组件。然而,与单页应用程序不同的是,这些组件并没有捆绑到一个 JavaScript 包中。

相同,每个组件都被视为一个独立的迷你应用程序,与所有其余组件隔离存在。

例如,如果您的页面有一个基于 JavaScript 的导航栏,那将是一个迷你应用程序。如果它还具备 JavaScript 驱动的图像轮播,那就是另一个迷你应用程序。等等。

然而,如果这些组件没有被捆绑,它们如何被蕴含在我的项目中?我将在下一节解释这个问题。

<!-- Islands architecture -->
<body>
<MyNavBar /> <!-- navbar mini app -->
<main>
  <MyCarousel /> <!-- carousel mini app -->
  <div class="content">
    <!-- more page content... -->
  </div>
</main>
</body>

服务器渲染的组件

Astro 次要是一个动态站点生成器。它实用于大多数反对服务器渲染组件的 UI 库,包含 Vue、Svelte、Preact、React 和 Lit。

因而,当 Astro 构建你的应用程序时,每个 JavaScript 组件都在服务器端加载,内容是”快照“。这个快照被增加到动态页面上。

服务器渲染不是 Astro 特有的性能,但在 SPA 中这是一个可选性能,而在 Astro 中,这是一个至关重要的性能,咱们将在上面看到。

<!-- 开发内容 -->
<body>
<MyForm /> <!-- JS component -->
</body>

<!-- 快照内容 -->
<body>
<form> <!-- Server rendered JS component -->
  <input type="text" >
  <!-- ... -->
</form>
</body>

Progressive hydration

这就是 Astro 的神奇之处——通过 islands 架构、服务器渲染组件和渐进式水合的组合。

因为咱们的页面被划分为服务器渲染的迷你应用程序,互动层(JS)能够独立加载,并且只在须要的时候加载。

例如,您可能有一个交互式表单。此表单位于页面下方,位于视口之外。

表单是服务器渲染的,所以咱们在页面上看到它。然而,在用户将其滚动到视图中之前,不须要加载低廉的 JavaScript。

这就是 Astro 中“渐进式水合作用”的含意——咱们只在须要时加载 JavaScript。

建设一个 Vue + Astro 我的项目

当初实践曾经讲完了,让咱们来看看它的实际效果吧!

要开始创立 Astro 我的项目,咱们将首先创立一个目录:

$ mkdir vue-astro

而后运行 ​​Astro 装置向导:

$ npm init astro

装置向导将容许咱们抉择“Vue”作为咱们抉择的框架。这将创立一个蕴含 Vue 组件的样板我的项目。

Astro 组件

Astro 页面保留在 src/pages 目录中。在默认装置中,咱们看到一个文件 index.astro,如下所示。

src/pages/index.astro

---
import VueCounter from '../components/VueCounter.vue';
let title = 'My Astro Site';
---
<html lang="en">
<head>
  <!-- ... -->
  <title>{title}</title> 
</head>
<body>
  <main>
    <!-- ... -->
    <VueCounter client:visible />
  </main>
</body>
</html>

Astro 具备单文件组件款式,与 Vue 相似,但有一些重要区别。

首先,在文件的顶部,咱们看到仿佛是前端内容,即用 --- 划定的内容。这是在服务器端运行的 JavaScript。这不会被发送到客户端。

在这里咱们能够看到两件重要的事件:首先,咱们正在导入一个 Vue 组件(你能够从任何反对的框架中导入组件)。另外,咱们正在设置一个值:title

这里申明的所有变量在模板中都是可用的。你会留神到 title 在模板中以相似 JSX 的语法进行插值。

src/pages/index.astro

---
...
let title = 'My Astro Site';
---
<html lang="en">
<head>
  <!-- ... -->
  <title>{title}</title> 
</head>
<!-- ... -->

接下来,留神模板中申明的组件。

默认状况下,组件在客户端是不交互的,只是由 Astro 进行服务器渲染。

如果咱们想让组件交互,即加载 JavaScript,咱们须要给它一个指令通知客户端何时加载它。

在这种状况下,client:visible 指令通知 Astro 当组件在页面中可见时使 VueCounter 交互。

如果产生这种状况,Astro 将从服务器申请该组件的 JS 并对其进行水合。

---
import VueCounter from '../components/VueCounter.vue';
...
---
<html lang="en">
<head><!-- ... --></head>
<body>
  <main>
    <!-- ... -->
    <VueCounter client:visible />
  </main>
</body>
</html>

加载 Astro

当初让咱们运行 Astro 的开发服务器来查看咱们的我的项目。

npm run dev

在页面的源代码中,你会看到在文档中没有任何的 JavaScript 捆绑! 不过,咱们的确看到了服务器渲染的 Vue 组件。

咱们还看到 Astro 在文档注释的底部增加了一个脚本。在这里,它加载了一个模块来水合 Vue 组件。

该模块将下载 Vue 组件和依赖项(Vue 框架),而不会阻塞渲染。

index.html

<!-- Page source -->
<body>
<!-- server rendered component -->
<div id="vue" class="counter">
  <button>-</button>
  <pre>0</pre>
  <button>+</button>
</div>

<!-- 增加的代码片段以水合 Vue 组件 --> 
<script type="module">
import setup from '/_astro_frontend/hydrate/visible.js';
// ...
</script>

为什么 Vue + Astro 可能比 Vue SPA 更好

要理解为什么 Astro 在 UX 方面能够击败单页应用程序,让咱们对网站加载时产生的状况进行简化合成。

  1. index.html 曾经加载。它没有 JS 捆绑,但它包含你的服务器渲染的组件,所以用户曾经能够看到你的网站内容 – 只是还没有互动。
  2. 组件所需的任何 JS 当初将以一系列独立脚本的模式异步下载。
  3. 下载这些脚本后,它们将被解析并运行。当初能够进行交互了。

当初让咱们设想一下,咱们把这个网站从新建成一个单页的应用程序。它当初会如何加载?

  1. index.html 被加载。因为该页面不蕴含任何内容,用户无奈看到任何货色。浏览器将开始下载捆绑程序。
  2. 下载 JS 包后,浏览器就会对其进行解析。用户依然看不到任何货色。
  3. 一旦 JS 包被解析并运行,页面内容就生成了。用户当初能够查看应用程序并与之交互。

简略的说:Astro 网站简直能够立刻提供可见的内容,不像 SPA 须要先下载并运行 JS 包。

(Astro 利用也会稍早提供互动性,因为它可能不须要下载那么多 JS,因为没有 SPA 外壳、路由器等)

最初的想法

Astro 的架构可能是比单页应用程序更好的抉择,因为它无需 JavaScript 即可使内容可见,并且仅在须要时加载 JS。

从实践上讲,单页应用程序能够通过预渲染和代码拆分的组合来实现相似的成果。不同之处在于,Astro 网站默认以这种形式进行优化,因为您须要抉择退出交互性和 JS。

当然,并不是每个应用程序都会从​​这种架构中受害,因为 SPA 更适宜某些类型的应用程序,例如高度动静和交互式的应用程序。所以咱们不会冀望 SPA 架构会隐没。

退出移动版