5

我正在开发一个静态站点生成器,我希望能够同时支持响应式 JavaScript 交互和标准的 load-a-fresh-page-into-the-browser 超链接。我突然想到,像 Svelte 这样的东西可能很适合这个。我可以使用服务器端渲染支持为我的所有页面生成 HTML,然后我可以编译和发布 JavaScript 组件hydratable: true以支持动态功能。

我用这种方法想到的一个问题是,我的项目的大部分组件都是完全静态的内容:只有 HTML 和超链接,没有任何状态或事件处理程序,而且我不会更改道具,除非我生成一个新的 HTML 文件不同的页面。如果我在页面加载时天真地生成 JavaScript 来补充所有这些组件,我最终可能会得到一个比我实际需要的更大的包(并且在运行时完成更多的工作)。

Svelte 是否提供任何方法来优化这种情况?我可以以某种方式检查一个组件是否是其 props 的纯函数,以便在不需要时避免给它补水?还是编译器足够聪明,可以为我做到这一点?

4

1 回答 1

9

这是一个很好的问题,我们目前没有简单的答案。

可以确定单个组件是否具有可以更改的值 -返回svelte.compile(...)具有vars属性的对象,该属性是组件内所有值的数组。检查此数组将告诉您哪些值永远不会重新分配或变异。(它不会告诉您组件是否具有具有副作用但影响状态的事件处理程序,这也是确定组件是否完全静态所必需的。这是我们可以在未来添加的信息 3 .x 版本。)

但这只是故事的一半。考虑一个声明一个属性的组件name......

<script>
  export let name;
</script>

<h1>Hello {name}!</h1>

...并且在您的应用程序中使用如下:

<Greeting name="world"/>

就编译器而言,在编译<Greeting>组件时,name值可能随时更改,因此将其视为完全静态是不安全的。但如果它能够更全面地理解你的应用程序,它就可以替换{name}world,这将带来各种好处。

补水时,Svelte 假设现有 DOM 与应该存在的 DOM 之间可能存在差异。在许多情况下,假设其他情况是安全的,并且跳过检查它知道是静态的子树,这将避免将它们包含在生成的 JS 中的需要。

作为编译器,Svelte 非常适合利用这些技术,但这是我们尚未开展的工作。理想情况下,我们将能够升级编译器,使您的应用程序变得更小而无需进行任何更改。如果您热衷于在此期间开始尝试可能发生的事情,那么从vars返回svelte.compile(...)的属性(我想也是ast属性)就是开始的地方。

于 2019-04-29T02:33:42.517 回答