渐进式

渐进式是根据应用程序的需求下载代码,而不是急切地下载整个代码库。

这将我们连接到 Qwik 的核心原则,即尽可能延迟加载和执行 JavaScript。为了实现这一点,Qwik 需要将应用程序分解为许多可延迟加载的块。

当前的最新技术

现有的框架存在两个问题

  • 懒加载边界完全由开发人员委托
  • 框架只能懒加载不在当前渲染树中的组件。

问题在于框架需要将其内部状态与 DOM 进行协调。这意味着应用程序至少需要进行一次hydration(重新注入)。框架需要能够进行完整的渲染以重建框架的内部状态。在第一次渲染之后,框架可以更精确地进行更新,但已经造成了损害,代码已经被下载。因此,现在我们有了两个问题:

  • 框架需要下载和执行组件以在启动时重建渲染树。(参见hydration is pure overhead)这迫使所有组件急切地下载和执行。
  • 即使在渲染时不需要,事件处理程序也随组件一起下载。包含事件处理程序会强制下载不必要的代码。

解决方案

Qwik 的架构充分利用现代工具来自动化入口点生成的问题。开发人员可以正常编写组件,而 Qwik 优化器将这些组件拆分成块,并在需要时下载它们。

此外,框架运行时不需要下载不需要用于交互的代码,即使该组件是渲染树的一部分。

优化器

优化器是一种代码转换工具,将函数提取为可导入的顶级符号,使得 Qwik 运行时可以按需延迟加载 JavaScript。

优化器和 Qwik 运行时共同工作,以实现细粒度的懒加载。

如果没有优化器,要么:

  • 开发人员必须将代码拆分为可导入的部分。这对于编写应用程序来说是不自然的,会导致糟糕的开发体验。
  • 应用程序将不得不加载大量不必要的代码,因为没有懒加载的边界。

Qwik 运行时必须理解优化器的输出。这里需要理解的是,通过将组件拆分为可延迟加载的块,懒加载要求将异步代码引入框架中。框架必须以不同的方式编写,以考虑到异步性。现有的框架假设所有代码都是同步可用的。这个假设阻止了将懒加载轻松插入现有框架中的可能性。(例如,当创建一个新组件时,框架假设可以以同步方式调用其初始化代码。如果这是第一次引用组件,则需要懒加载其代码,因此框架必须考虑到这一点)。

懒加载

懒加载是异步的。Qwik 是一个异步框架。Qwik 理解到在任何时候,它可能没有回调的引用,因此可能需要懒加载它。(相比之下,大多数现有的框架假设所有的代码都是同步可用的,使得懒加载变得非常复杂)。

在 Qwik 中,一切都可以懒加载:

  • 渲染时的组件 - 初始化块和渲染块
  • 组件任务 - 副作用,仅在输入更改时下载
  • 监听器 - 仅在交互时下载
  • 样式 - 仅在服务器未提供时下载

懒加载是框架的核心属性,而不是事后的想法。

优化器和 $

让我们再次看一下我们的示例:

// `$` 后缀表示组件应该是
// 懒加载的。
export const Counter = component$(() => {
  const count = useSignal(0);
 
  // `$` 后缀表示处理程序的实现应该是
  // 懒加载的。
  return <button onClick$={() => count.value++}>{count.value}</button>;
});

注意代码中的 $ 的存在。$ 是一个标记,告诉优化器后面的函数应该是懒加载的。 $ 是一个单个字符,向优化器和开发人员暗示 异步懒加载发生在这里。

Contributors

Thanks to all the contributors who have helped make this documentation better!

  • adamdbradley
  • RATIU5
  • manucorporat
  • fleish80
  • msssk
  • mhevery