Blazor中RenderComponentAsync必须用@await显式等待,因Razor视图默认同步执行,不await会导致任务丢弃、渲染为空或报错;正确写法为@await Html.RenderComponentAsync<T>(RenderMode.Server)。

Blazor中RenderComponentAsync必须用@await显式等待
在 Razor 视图里调用 Html.RenderComponentAsync 时不加 @await,组件内容大概率为空或直接报错。Razor 视图默认是同步执行上下文,而 RenderComponentAsync 返回的是 Task,不 await 就等于扔掉任务、继续往下走。
- 错误写法:
@{ Html.RenderComponentAsync<MyComponent>(RenderMode.Server); }—— 任务被创建但从未执行 - 正确写法:
@await Html.RenderComponentAsync<MyComponent>(RenderMode.Server) - 若在
@functions块或后台方法中调用,需确保该方法本身标记为async,且返回类型为Task<IHtmlContent> - 在布局页(
_Layout.cshtml)或分部页(_Partial.cshtml)中使用时,更要确认父视图已启用异步支持(ASP.NET Core 6+ 默认开启,旧版本需检查Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation配置)
HTML模板引擎里if判断只在构建/服务端阶段生效
像 EJS、Go 的 html/template 或 html-webpack-plugin 的 templateParameters,它们的条件逻辑发生在构建时或服务端响应生成前,不是运行时行为。打包完的 HTML 就固定了,用户刷新页面也不会再重新判断。
-
<script src="devtools.js"><% } %></script>—— 这段只在 Node.js 渲染时起作用,前端 JS 拿不到env - 字符串比较务必用全等:
if (status === 'active'),避免'1' == 1这类隐式转换导致误判 - 不要把复杂业务逻辑塞进模板:比如
u.active).map(...)%>,应提前在控制器或路由层处理好数据 - 变量为
null或undefined时,if (data.value)会跳过;如需区分空字符串和未定义,得写if (data.value !== undefined)
原生 HTML 的 hidden 属性在异步组件中会闪一下
直接给异步插入的元素写 hidden 属性,几乎一定会触发 FOUC(Flash of Unstyled Content),因为 DOM 插入和属性生效之间存在微小时间差,浏览器先渲染再隐藏。
- 必须加 CSS 兜底:
[hidden] { display: none !important; },且这条规则要放在<head>最早加载的样式中 - JS 控制时,别用
el.setAttribute('hidden', '')—— 它不更新el.hidden的布尔值,后续el.hidden = false可能失效 - 推荐时机:用
requestAnimationFrame(() => el.hidden = true)确保 layout 完成后再设 - 显示前记得清空内联样式:
el.style.display = '',否则el.hidden = false无效
自定义元素按需注册的关键是延迟调用customElements.define()
把所有 customElements.define() 写在全局脚本开头,等于强制加载所有组件代码,哪怕页面根本没用到。真正按需,是指用户触发动作后才 import 并 define。
立即学习“前端免费学习笔记(深入)”;
- 首屏组件:放在
<script defer>或<script type="module" defer>中,确保 DOM 解析完立即升级,不闪HTMLUnknownElement - 非首屏组件(如弹窗、设置面板):监听点击事件,在回调里
await import('./xxx.js')后再customElements.define() - import 路径必须是静态字符串,不能拼接变量,否则 Webpack/Vite 无法自动拆包
- 重复 define 同一名字会抛
DOMException,可在 define 前加守卫:if (!customElements.get('my-button')) { customElements.define('my-button', ...); }



















