接入Angular Universal后页面加载两次,修改后Google能否抓取网页内容?
你当前使用的修复代码如下:
<section *ngIf="this.isBrowser" style="background-color: rgb(202, 202, 202);" > <div class="container" style="background-color: #fff;"> <router-outlet (activate)="onActivate($event)"></router-outlet> </div> </section>
该调整会导致Google无法正常读取页面内容
这个修复方案本质是直接关闭了服务端渲染(SSR)对页面核心内容的渲染能力:Angular Universal在服务端生成静态HTML时,isBrowser的取值为false,因此被<section>包裹的整个路由出口内容都不会被写入服务端返回的HTML中。Google爬虫抓取页面时会优先读取服务端返回的静态HTML,此时拿到的页面主体内容为空,完全无法识别你的网页实际展示的内容,会导致站点SEO效果大幅下降。
「页面加载两次」的根因
你观察到的加载两次是Angular Universal默认水合(Hydration)流程的异常表现,正常流程如下:
- 服务端先返回已经渲染好完整内容的静态HTML,用户可以快速看到页面内容
- 浏览器下载完Angular客户端脚本后,会对现有静态DOM做水合,绑定交互事件、同步应用状态
如果出现服务端和客户端渲染的内容不一致、客户端重复发起服务端已经完成的接口请求等情况,就会出现页面闪一下、整体重新渲染的视觉效果,也就是你所说的「加载两次」。
不影响SEO的正确修复方案
不要对整个路由出口加浏览器端渲染限制,参考以下步骤修复:
- 首先去掉你在
<section>标签上添加的*ngIf="this.isBrowser"判断,恢复路由内容的服务端渲染能力 - 排查项目中是否存在服务端、客户端渲染内容不一致的逻辑:比如直接调用
window、document等仅浏览器存在的API、或者服务端和客户端请求返回的数据不一致,这是导致水合闪烁的最常见原因。如果确实有组件只能在浏览器端运行,仅对对应的单个组件加isBrowser判断即可,不要全局限制路由内容的服务端渲染 - 如果你使用的是Angular 16及以上版本,开启官方自带的水合能力,在根配置中添加
provideClientHydration(),同时开启HTTP请求缓存withHttpTransferCacheOptions({includePostRequests: true}),可以让客户端直接复用服务端已经请求过的数据,避免客户端重复发请求拉取页面数据导致的二次渲染 - 对于服务端获取的动态数据,使用Angular自带的
TransferState把数据从服务端传递到客户端,客户端直接复用数据不需要二次请求,也能解决二次加载问题
内容的提问来源于stack exchange,提问作者Vichakshan Technologies
相关产品推荐
相关产品推荐

