angular 支持客户端对服务器中注入的Web组件进行水分补充,

ne5o7dgx  于 5个月前  发布在  Angular
关注(0)|答案(5)|浏览(65)

哪个@angular/*包是bug的来源?

platform-browser, platform-server

这是一个回归吗?

描述

首先,非常感谢您在不断努力改进SSR和这个新的非破坏性填充功能。
我们一直在探索这个新功能,并看到了有希望的结果。然而,当我们试图将其与Web组件的服务器填充集成时,特别是与Stencil一起,我们遇到了一个巨大的挑战。
我们的Angular组件主要由来自我们的Stencil组件库的元素组成。为了提高渲染效果并减轻Web组件的 Flink ,我们使用Stencil的renderToString方法进行服务器端填充。这种方法一直有效,但似乎与Angular的非破坏性填充不兼容。该方法需要整个生成的HTML(来自Angular SSR渲染的结果),并渲染Web组件,生成一个新的完整HTML页面,这无疑会修改DOM并触发NG0500 Hydration错误。
我们理解理想的情况是避免DOM操作,为此,需要在Stencil中实现某种类型的每个组件填充方法,我认为目前还不可用,而且实现起来也不容易。
我在想一个潜在的解决方案可能涉及到在Stencil Angular Package 器中实现特定的填充方法,允许通过Angular的DOM渲染器函数而不是直接生成HTML进行填充。然而,我认为这并不容易,而且本质上可能就像实现一个完整的Stencil到Angular编译器,而不仅仅是一个 Package 器。
如果这些解决方案不可能,我们将不得不跳过所有使用ngSkipHydration填充的所有Web组件,但我认为这并不能解决问题,而且这样做的话,我们将失去大部分客户端填充的优势。
这是我们现在遇到的主要问题之一,阻止我们启用带有provideClientHydration的非破坏性填充。
虽然我理解这可能不是Angular和新填充功能的直接问题,但任何关于如何解决或减轻这个问题的建议将非常有价值。此外,我在想是否有办法促进与Stencil或其他Web组件库的合作以提出解决方案。实际上,您是否知道这个问题在Lit中是否以某种方式得到解决,或者有可能与该团队合作吗?
我创建了这个Sandbox来重现问题,它对于探索潜在解决方案非常有用,因为它在同一环境中托管了Stencil组件。
(它应该在第一次加载时运行良好,或者也可以下载并使用./start.sh脚本运行。基本上,它安装和构建Stencil组件和Angular Package 器,然后是Angular SSR服务器)
感谢您考虑这个问题,我们期待您的任何见解或建议。

5kgi1eie

5kgi1eie1#

关于这个问题,我们非常依赖Web组件,而新的Angular hydration方法并没有充分支持Web组件的渲染。正如@dchicurel提到的,用户体验确实如此。这个问题阻止我们拥抱新的非破坏性渲染特性,并将阻止我们升级到默认使用新渲染方法的Angular 17。

虽然旧的破坏性渲染方法似乎可以工作,但它会导致较差的用户体验。用户短暂地看到整个页面,然后在一段时间内变空白,或者在最终渲染之前经历页面 Flink 。这种行为也对我们的Web性能指标产生负面影响。我真诚地希望我们能在这方面得到一些指导,并找到解决这个问题的最佳方法。谢谢。

taor4pac

taor4pac2#

+1
我正在为低级跨框架兼容性投资更多的web组件设计系统。
我还没有对web组件进行服务器端渲染,但我希望能够这样做。我正在使用Lit和Stencil web组件的混合。
为了解决CLS问题,我正在为web组件设置预处理的CSS尺寸。
设计系统组件关注样式而不是行为。例如,一个按钮组件可能只需要:

html`<slot @onclick="this.handleClick"></slot>`

并添加一些构造好的插槽样式。
以下是预期的使用方式:

  • my-button.component.ts*
@Component({
  selector: 'some-button',
  template: `
    <design-system-button> // provided by the design system
      <button onClick="handleClick()"></button>
    </<design-system-button>
  `,
    standalone: true,
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class SomeButtonComponent {
  public handleClick() {}
}

另一个例子是一个用于在所有页面上添加全局页眉和页脚的web组件。Angular应用程序被插槽到页眉/页脚组件中:

  • index.html*
<page-wrapper> <!-- global header and footer applied -->
  <my-angular-app-root></my-angular-app-root> <!-- angular app is projected via a <slot> -->
</page-wrapper>

两种消费模式:

Web组件可以是构建时依赖项或运行时依赖项。运行时对于大部分静态或独立管理的组件很有用,这些组件调用自己的服务;例如,一个“微前端”。通过不需要升级这些组件的npm依赖项来获取这些MFE的更新,从而使应用程序与它们几乎没有交互。上面的page-wrapper就是一个很好的例子。
或者,web组件可以从npm像今天的Material Design那样进行构建时集成。

最后的想法

今天,随着web组件在我的应用中进行CSR,Angular SSR似乎只是忽略了自定义元素,因此,主要的缺点在于闪现内容,因为web组件在SSR发生后在客户端进行预处理。

dgenwo3n

dgenwo3n3#

你好,

请问你能帮我吗?我有一个带有Cyberpanel的VPS,已经上传了dist文件夹,但是SEO不起作用,源代码中没有HTML标签。

谢谢!

omtl5h9j

omtl5h9j4#

这个问题阻止我们采用新的非破坏性水合特性,并阻止我们升级到Angular 17,因为我相信在默认情况下新的方法将被使用。我非常确定你可以移除provideClientHydration()来坚持使用旧的机制,所以这不应该阻止升级到v17。启用非破坏性水合并不需要使用v17。

为了获得额外的上下文,我认为Web组件目前没有为SSR定义一个明确的模型,而且我认为每个框架在这里基本上都在做自己的事情。有一个提议的社区协议用于SSR,它可以定义一个可互操作的协议,但现在还处于相当早的阶段。

llmtgqce

llmtgqce5#

一个潜在的解决方案可以是添加配置,用于选择一组组件(以及/或一组选择器的正则表达式),并调用相关函数来执行该组件的SSR渲染。然后,也许可以添加一个标志以启用对组件及其传递的属性进行缓存的性能优化。

相关问题