【问题标题】:Angular 7 SSR loading first time twiceAngular 7 SSR第一次加载两次
【发布时间】:2019-08-03 05:43:57
【问题描述】:

我在Angular 7 中构建了几个站点,其中SSR 用于SEO 的改进。所有应用程序本身都很好,但是总是会发生 第一次 或当您执行 硬刷新 时会出现这个小 blip内容显示出来后,网站本身突然“重新加载”。

ngIf 的所有可能隐藏在组件的 ngOnInit 部分中评估的组件的条件似乎都被忽略了,并且可能以 opacity = 0 开头以隐藏 HTML 元素的动画也被显示。

也就是说,我在不同的论坛、帖子、github 问题等中阅读了很多关于此的内容,但是我无法找到任何解决方案。

我尝试将main.ts 更改为:

document.addEventListener('DOMContentLoaded', () => {
    platformBrowserDynamic().bootstrapModule(AppModule);
});

而不是经典的引导机制,没有乐趣。我已经尝试在AppRouting 中启用initialNavigation 的选项,但仍然不起作用:

@NgModule({
    exports: [ RouterModule ],
    imports: [ RouterModule.forRoot(routes, {enableTracing, scrollPositionRestoration: 'enabled', initialNavigation: 'enabled'}) ],
})
export class AppRoutingModule {}

我在这里阅读了我认为可能相关的问题: https://github.com/angular/angular-cli/issues/7477 但它最终引用了对我不起作用的 initialNavigation 标志。

我不确定我是否可以在这里尝试其他任何东西或设置任何“特殊”的东西,但是没有延迟或隐藏导致导航的实际呈现页面真的很好有点不友好。

请注意,这仅适用于首次加载、首次加载或硬刷新。导航的其余部分都很好。

【问题讨论】:

  • 你使用 TransferState 了吗?
  • 我在app.module中配置了TransferHttpCacheModule,在app.server.module中配置了ServerTransferStateModule。是这个意思吗?
  • 是的,该模块正在使用 TransferState。使用它解决了我的闪烁问题,所以我认为它对你来说可能是一样的
  • 我也是这么想的……还是谢谢你。它确实解决了重复的 http 调用
  • 嗨@EliyaCohen,我尝试了不同的方法,例如 initialNavigationEnabled: true 并确保正确设置了 ServerTransferState 和 BrowserTransferState 模块。除此之外,我不时看到这种情况发生,我一直在更新到最新版本的 angular/universal 但没有运气。我想您可以默认执行类似“显示:无”的操作,然后在一段时间后将其删除(虽然还没有尝试过),但我不确定它对 SEO 的影响。老实说,在大多数情况下,我最终都接受了它——而且感觉从未像现在这样好过!

标签: angular angular-universal server-side-rendering


【解决方案1】:

我遇到了同样的问题,我的解决方案是只为爬虫(google、yahoo、facebook...)启用 ssr。

// server.ts
// All regular routes use the Universal engine
server.get('*', (req, res) => {
  // serve ssr only to web crawlers
  if((/(google|bing|yahoo|slurp|facebot|duckduck)/gi).test(req.headers['user-agent'])){
      res.render(indexHtml, {
        req,
        providers: [{provide: APP_BASE_HREF, useValue: req.baseUrl}]
    });
  }
  else{
    res.sendFile(join(distFolder, 'index.html'));
  }
});

【讨论】:

  • 非常感谢!我只需要爬虫的 SSR,这是完美的解决方案。
【解决方案2】:

实际上闪烁的发生是因为您的应用程序的服务器端首先由浏览器加载,然后客户端随后加载。因此,我实施的一个快速解决方法是仅在服务器端的登录页面上添加“显示:无”。

要实现,请将您的主要组件包装在标签中,并向其添加条件显示子句。我建议您仅在您的目标网页上执行此操作。使用 bootstrap 4,你的主布局应该是这样的:

app.layout.html

<div  [className]="!display?'d-none':''">
    <app-navbar current_page="post"></app-navbar>
    <router-outlet ></router-outlet>
    <app-footer></app-footer>
</div>

注意 [className]="!display?'d-none':''"

在component.ts文件中:

app.component.ts

import {Component, Inject, OnInit, PLATFORM_ID} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';

@Component({
  selector: 'app-layout',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  display = true;
  constructor( @Inject(PLATFORM_ID) private platformId: Object) {
    if (!isPlatformBrowser(this.platformId)) {
      this.display = false;
    }
  }

  ngOnInit() {
  }
  onActivate(event) {

  }
}

就像我提到的,它是一种真正有效的解决方法。

【讨论】:

  • 谢谢。我想知道对实际 SEO 有什么影响,因为该网站将呈现为 display:none ?我说的对吗?
  • 是的,你可能是对的。这就是为什么我建议只在登陆页面上这样做。您可以进一步仅在流行的浏览器上隐藏它(例如,通过检查用户代理),因此可能不会对爬虫机器人隐藏。您还可以设置超时,以便页面的内容在一段时间(例如 10 秒)后变得可见。我认为这些应该会限制对 SEO 的影响。
  • 这是最糟糕的事情,你实际上是在与 SSR 的目的作斗争
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
  • 2020-01-24
  • 1970-01-01
  • 2012-08-03
  • 2020-09-12
  • 1970-01-01
相关资源
最近更新 更多