常见问题解答
@QwikDev 是一个有感知能力的 AI 吗?
是的,而且我非常有趣!关注我
为什么叫 Qwik?
最初它被称为 qoot,但我们认为它太难搜索了。一位社区成员,@PatrickJS__,提出了 Qwik,在 builder.io 的内部投票之后,我们更改了它!
Qwik 与其他框架有什么不同?
Qwik 是第一个在编写组件时拥有类似于 React、Vue 或 Svelte 的 DX(开发者体验)的框架。它提供实时 HTML,该 HTML 立即具有交互性,Qwik 通过完全消除对水合的需要来实现此属性。现在,Qwik 应用程序在用户交互时立即执行事件处理程序,而无需引导所有应用程序状态。这种技术被称为 可恢复性。
结果是,开发人员默认编写了极其高效的应用程序,甚至无需担心。使用 Qwik 构建的应用程序无论组件数量或复杂程度如何,都很快,它们在 JS 负载方面是 O(1)(恒定时间)。
为什么还要另一个框架?
简而言之,Qwik 解决了一个其他框架无法解决的问题。Qwik 具有即时启动性能,无论应用程序多么复杂。Qwik 应用程序无论组件数量多少,都会提供相同数量的初始 JS。 Qwik 是第一个开源 O(1) 框架。
什么是 Qwik City?
Qwik City 只是在 Qwik 之上的一组额外的 API。可以将其视为 Qwik 作为核心,而 City 作为额外的 API(路由、数据加载、端点等)。我们称之为 Qwik 的元框架。Qwik City 之于 Qwik,就像 Next.js 之于 React,Nuxt 之于 Vue,或者 SvelteKit 之于 Svelte。
Qwik 难学吗?
Qwik 是针对 React(和其他基于 JSX 的框架)设计的,确保它 易于学习 并促进快速生产力。开发组件与 React 几乎相同,路由灵感来自 Nextjs 等。
但是,有一些基本 新概念 需要学习,例如 可恢复性 和细粒度反应性,但我们认为学习曲线并不陡峭。
我们还有一个交互式 教程 来帮助你入门。
$
符号是什么?
所有这些 你可能已经注意到,在 Qwik 应用程序中,$
符号比平时更多,例如:component$()
、useTask$()
和 <div onClick$={() => console.log('click')} />
。它用作延迟加载边界的标记。Qwik 将你的应用程序分解成小块;这些块比组件本身更小。对于事件处理程序、钩子等。$
向 优化器 和开发人员发出信号,表明它正在发生。
示例
import { component$ } from '@builder.io/qwik';
export default component$(() => {
console.log('render');
return <button onClick$={() => console.log('hello')}>Hello Qwik</button>;
});
由于 $
语法,上面的组件被拆分为
import { componentQrl, qrl } from '@builder.io/qwik';
const App = /*#__PURE__*/ componentQrl(
qrl(() => import('./app_component_akbu84a8zes.js'), 'App_component_AkbU84a8zes')
);
export { App };
import { jsx as _jsx } from '@builder.io/qwik/jsx-runtime';
import { qrl } from '@builder.io/qwik';
export const App_component_AkbU84a8zes = () => {
console.log('render');
return /*#__PURE__*/ _jsx('p', {
onClick$: qrl(
() => import('./app_component_p_onclick_01pegc10cpw'),
'App_component_p_onClick_01pEgC10cpw'
),
children: 'Hello Qwik',
});
};
export const App_component_p_onClick_01pEgC10cpw = () => console.log('hello');
注意:
$
与jQuery
、Svelte 或任何其他框架无关。
在用户交互时请求 JS 不慢吗?
只有在你下载它时才慢。相反,Qwik 通过 服务工作者 在后台线程中预取当前页面的 JS 模块,并在用户与应用程序交互时从浏览器的 缓存 中检索这些模块。
这种策略被称为 推测性模块获取,它由可恢复性启用。水合框架必须在页面加载时急切地下载和执行代码以检索事件处理程序,因此无法利用推测性模块获取。
Qwik 如何知道要预取什么以及预取顺序?
在生产环境中,Qwik 使用在 SSR(服务器端渲染)期间生成的大量信息,尽早开始填充缓存,只包含当前页面上可用的交互部分。这样,当用户点击或交互时,JS 已经在缓存中。
此外,Qwik 见解 可用于在不太重要的部分之前优先考虑交互的重要部分。
例如,“立即购买”按钮比“添加到购物车”按钮更重要,因此 Qwik 将首先预取“立即购买”按钮,然后预取“添加到购物车”按钮。
Qwik 应用程序在网络速度慢的情况下会慢吗?
恰恰相反。
Qwik 不需要预先获取所有内容才能开始运行,而其他框架需要下载整个关键路径才能变得交互,因为 水合。
事实上,由于 Qwik 能够 减少网络瀑布,在交互时,请求的模块很可能已经下载并存储在浏览器的缓存中。即使它们还没有被缓存,Qwik 也可以 避免重复请求,而是继续获取正在请求的模块,以便尽快开始执行它们。
因此,Qwik 应用能够更快地响应,尤其是在网络速度慢的情况下。
Qwik 会生成太多的小文件吗?
在开发模式下,Qwik 会生成很多小文件,因为它使用的是 Dev Vite.js 服务器,但在生产模式下,Qwik 会更有效地捆绑文件。
为什么 Qwik 使用 JSX?它是在 React 的基础上构建的吗?
不,Qwik 完全没有使用 React。Qwik 使用 JSX 作为模板语法。
请注意,JSX 不是 React。事实上,JSX 只是语法,没有语义。我们选择 JSX 有几个原因。
- 熟悉的语法:它没有重新发明轮子,而是利用现有的 JS 进行循环、条件等操作。 JSX 规范的阅读量出奇地少
- 生态系统:得到 IDE、linter、安全审计工具、调试工具和高亮显示工具的良好支持。
- 类似于 HTML:JSX 在视觉上和概念上类似于 HTML,是一棵树。其他模板系统,如html 模板(lit-html)不是树,而是令牌数组,这使得在上面构建和转换变得更加困难。
- 流行:毫无疑问,JSX 是世界上使用最广泛的模板语法。
Qwik 使用 vDOM(虚拟 DOM)吗?
Qwik 有时使用 vDOM,有时它会做 SolidJS 做的事情(直接 DOM 更新)。
思考这个问题的方式如下
如果状态的改变没有结构上的改变,那么 Qwik 很可能不会使用 vDOM。例如
export const NoStructuralChange = component$(() => {
const count = useSignal(0);
return (
<>
{/* This will not cause vDOM to activate. (No DOM structure change, only update text value) */}
<div>Count: {count.value}</div>
<button onClick$={() => count.value++}>+1</button>
</>
);
});
当有结构性变化时,Qwik 会利用虚拟 DOM(vDOM)。在下面的例子中,DOM 结构需要更新(用<button>
替换<h1>
),因此将使用 vDOM 进行渲染
export const StructuralChange = component$(() => {
const isLoggedIn = useSignal(false);
return (
<div>
{isLoggedIn.value ? <h1>you are logged in!</h1> : <button>Log in</button>}
</div>
)
});
需要理解的重要一点是,vDOM 不会在 Qwik 中造成性能问题。然而,在 React 中,使根组件失效会导致整个树的 vDOM 被创建。在 Qwik 中,这个决定是在每个组件的基础上做出的。并且只针对那些有结构性变化并且正在改变其结构的组件。如果一个组件是结构性的(vDOM),但没有检测到结构变化,那么 Qwik 会跳过该组件。你可以把它想象成所有组件的自动记忆化,这意味着 vDOM 只有在视图结构发生变化时才会被使用。这种情况很少见,因为在大多数情况下,视图只改变其值。
简而言之,Qwik 使用 vDOM,但在可比情况下,它比 React 使用得少得多。
为什么在 vDOM 声誉不佳的情况下还要使用它?
是否使用 vDOM 的问题可以看作是一个频谱
- 一个极端是 React,它始终为所有内容使用 vDOM。(可以有力地争论 vDOM 很慢。)
- 另一个极端是 SolidJS,它根本不使用 vDOM。(这导致了非常令人印象深刻的性能。)
另一方面,Qwik 谨慎地使用 vDOM,有两个原因
- 因为非 vDOM 解决方案需要在启动时至少执行一次代码才能了解组件结构。(Qwik 明确避免了这种情况。)
- 因为 vDOM 具有吸引人的 DX 属性,尤其是在需要动态组件时。
例如
const DynamicList = [ CompA, CompB, ...];
export const DynamicExample = component$(() => {
const idx = Math.floor(Math.random() * DynamicList.length);
const Component = DynamicList[idx];
{/* Dynamically chose which component to render */}
return <Component/>;
})
上面的代码<Component/>
非常容易理解。我们正在动态地选择一个组件放在那里。但在 Solid、Svelte、Vue 和 Angular 中,这变得很复杂(参见链接)。
通过谨慎地使用 vDOM,我们拥有了两个世界的最佳之处。在创建过程中,我们使用 SSR,大多数客户端更新是非结构性的。当需要结构性更新时,它们会局限于特定的组件,不会影响其子组件,从而抑制了 vDOM 可能造成的任何潜在的减速。
Qwik 有路由器吗?
有!Qwik City 包含一个基于目录的路由器,灵感来自 Next.js 和其他路由器。
我需要服务器才能部署 Qwik 应用吗?
你可以轻松地将 Qwik 应用部署到任何 无服务器环境,这要归功于我们的适配器。我们还支持 基于 Node.js 的服务器的 vanilla-node 适配器,例如 Express。
如果没有 SSR 的需要,你可以使用我们的 SSG(静态站点生成)适配器 将 Qwik 应用部署为静态站点。
哪一个更快:SPA(单页应用程序)还是 MPA(多页应用程序)?
这取决于。对于 SPA 来说,大部分成本是在会话开始时预先支付的,通过在会话开始时下载所有内容。因此,当用户与应用程序交互时,成本很低。
MPA 加载速度非常快,因为它们不需要像 SPA 那样下载那么多 JS。但是,当用户导航时,通常需要完全重新加载页面。完全重新加载页面通常非常快,因为浏览器在下载和解析 HTML 方面非常快。但是,由于有时最好在导航之间保持状态,因此 MPA 方法并不适合所有项目。在这种情况下,SPA 就可以很好地做到这一点。
Qwik 是一个独特的框架,它同时是 MPA 和 SPA。
Qwik 可以做 SPA 吗?
当然可以!Qwik City 包含<Link>
组件,它会触发 SPA 导航。使用 Qwik,开发人员不需要在 SPA 和 MPA 之间进行选择,每个应用程序都是同时存在的。
MPA 与 SPA 不再是项目开始时做出的架构决策,而是针对每个链接做出的决策。
Qwik 可以做静态站点生成(SSG)吗?
可以!它是所有 Qwik City 启动器的组成部分。了解如何进行 静态站点生成。
我不能用其他框架创建 MPA 或 SPA 吗?
不完全是,其他框架建议删除根目录中的所有<Scripts>
以生成 MPA,实际上是删除了所有交互性以及 SPA 导航。
如果脚本没有被删除,那么每次完全重新加载页面都会变得非常昂贵,因为每次重新加载页面都意味着框架需要重新水合整个页面。然而,Qwik 不会为每次页面加载产生 水合成本。
迁移到 Qwik 需要很多努力吗?
这取决于。如果你来自 React,将你的组件移植到 Qwik 应该很简单。但除此之外,由于 Qwik React
,你可以使用整个 React 生态系统,因此你可以在 Qwik 应用中使用任何 React 组件和任何 React 库。
我可以享受丰富的 React 生态系统吗?
可以!Qwik 可以原生运行 React 组件,查看文档。
你会感到惊讶的!
Qwik 做部分水合吗?
不。部分水合(或岛屿架构),由 Astro 推广,是关于将应用程序分解成交互性岛屿,以避免 全页面水合,其中页面中所有现有的组件都需要下载并执行。
为了使这能够工作,开发人员需要手动定义岛屿,然后手动描述它们应该在哪些情况下被水合。岛屿之间也不能相互通信。
相反,Qwik 组件根本不会水合。Qwik 通过一个强大的序列化系统实现了这一点,该系统只序列化反应图中必要的 state。这样,应用程序就可以在不急切地运行任何 JS 的情况下恢复。
我们认为,可恢复性在没有部分水合的负面权衡的情况下可以扩展。
Qwik 用什么语言编写?
Qwik 的大部分代码是用 TypeScript 编写的,TypeScript 是 JavaScript 的超集,它添加了可选的静态类型和其他功能。但是,Qwik 编译器(或优化器)是用 Rust 编写的,Rust 是一种非常快且内存效率高的语言。
Qwik 有社区吗?
有!在 Discord 和 GitHub 上,有一个不断壮大的 Qwik 开发人员社区。他们正在为框架做出惊人的贡献,构建大规模的网站,并互相帮助。 加入我们。
Qwik 是“Alex Russell 认可”的框架吗?
是的!Alex Russell(@slightlylate),以其对 PWA、W3C TAG、WC、TC39 & ES6、Chrome Frame、Dojo 等的贡献而闻名,经常对 JavaScript 框架持高度批评态度。尽管如此,他认可 Qwik。
Qwik 准备好投入生产了吗?
是的!Qwik 已经发布了 1.1 版本。Qwik 已经开发了 3 年了。我们相信 Qwik 已经准备好投入生产,并且没有预期的重大更改。
Builder.io 和许多团队已经在生产中使用 Qwik,所以你不会孤单。
Qwik 在 HTML 中序列化了太多数据,这是真的吗?
错误。Qwik 只序列化当前页面所需的数据。如果一个页面有 1000 个组件,但只有一个是交互式的,那么序列化的数据量与交互性的大小成正比,而不是与组件的数量成正比。
谁构建了 Qwik?
来自世界各地的惊人贡献者团队,他们生活在 Discord 上,以及 Builder.io 的一些全职开发人员:Misko、Adam 和 Manu Almeida。
Qwik 是开源的吗?
是的,MIT 并且 无依赖,安装 Qwik 不会使你的 node_modules 膨胀,也不会使你的律师膨胀。
Qwik 有什么缺点吗?
是的。每个框架都有自己的优缺点,都涉及权衡取舍。
- 作为一款相对较新的 JS 框架,Qwik 的社区和生态系统仍在发展中,虽然发展迅速,但您可能还没有找到所有您从更流行的框架中习惯的社区项目、模式和最佳实践。
- Qwik 可以即时加载任何规模的 JS 应用程序,因此它相对于当前技术的最大优势在于初始页面加载和交互时间。如果您的用例是单页应用程序,并且您不介意应用程序加载所需的时间,那么在当前阶段采用 Qwik 可能不会给您带来直接的益处。
我们一直在努力改进开发人员体验和功能,使 Qwik 更加易于用于任何用例,敬请期待。