Angular 7 SSR首次加载两次

时间:2019-03-12 16:52:12

标签: angular angular-universal ssr

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

ngIf的所有条件都可能会被隐藏,而这些条件可能会隐藏在组件的ngOnInit部分中评估的组件,而以opacity = 0开头的动画会隐藏HTML元素也显示了。

那是说我在不同的论坛,帖子,github问题等中读到了很多,但是我还没有找到任何解决方案。

我尝试将main.ts更改为:

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

代替经典的引导机制,毫无乐趣。我已经尝试过在initialNavigation中启用AppRouting的选项,但仍然无法使用:

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

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

我不确定是否可以在这里尝试其他任何方法或设置任何“特殊”功能,但最好不要延迟或隐藏实际呈现的页面,而这会导致导航失败不太友好。

请注意,这仅在首次加载,首次加载或硬刷新时进行。其余的导航绝对没问题。

2 个答案:

答案 0 :(得分:1)

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

要实现,请将您的主要组件包装在标记中,并向其添加条件显示子句。我建议您仅在目标网页上执行此操作。使用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) {

  }
}

就像我提到的那样,它实际上是一种解决方法。

答案 1 :(得分:0)

我遇到了同样的问题,我的解决方案是只为爬虫(谷歌、雅虎、脸书...)启用 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'));
  }
});