问题描述
我在 Angular 7
中构建了多个站点,并带有 SSR
用于 SEO
改进.所有应用程序本身都很好,但是总是发生第一次或当您执行硬刷新时出现这个小blip内容被显示,网站本身突然重新加载".
ngIf
的所有条件可能隐藏在组件的 ngOnInit
部分评估的组件似乎都被忽略了,动画可能以 开头opacity = 0
隐藏 HTML 元素也会显示.
也就是说,我在不同的论坛、帖子、github 问题等中阅读了很多关于此的内容,但是我还没有找到任何解决方案.
我尝试将 main.ts
更改为:
document.addEventListener('DOMContentLoaded', () => {platformBrowserDynamic().bootstrapModule(AppModule);});
而不是经典的引导机制,没有乐趣.我已经尝试了在 AppRouting
中启用的 initialNavigation
选项,但仍然不起作用:
@NgModule({出口:[路由器模块],进口:[ RouterModule.forRoot(routes, {enableTracing, scrollPositionRestoration: 'enabled', initialNavigation: 'enabled'}) ],})导出类 AppRoutingModule {}
我在这里通读了我认为可能相关的问题:https://github.com/angular/angular-cli/issues/7477 但它以对我不起作用的 initialNavigation 标志结尾.
我不确定我是否可以在这里尝试其他任何东西或设置任何特殊"的东西,但没有延迟或隐藏导致导航的实际呈现页面真的很好不太友好.
请注意,这只是在第一次加载、第一次加载或硬刷新时.其余的导航完全没问题.
实际上出现闪烁是因为您的应用程序的服务器端首先由浏览器加载,然后客户端随后加载.因此,我实施的一个快速解决方法是仅在服务器端的登录页面上添加display: none".
要实现,请将您的主要组件包装在一个标签中,并向其添加一个条件显示子句.我建议您只在着陆页上执行此操作.使用 bootstrap 4,您的主要布局应该是这样的:
app.layout.html
<app-navbar current_page="post"></app-navbar><路由器插座></路由器插座><app-footer></app-footer>
注意 [className]="!display?'d-none':''"
在 component.ts 文件中:
app.component.ts
import {Component, Inject, OnInit, PLATFORM_ID} from '@angular/core';从@angular/common"导入 {isPlatformBrowser};@成分({选择器:'应用程序布局',templateUrl: './app.component.html',styleUrls: ['./app.component.scss']})导出类 AppComponent 实现 OnInit {显示 = 真;构造函数(@Inject(PLATFORM_ID)私有平台ID:对象){如果 (!isPlatformBrowser(this.platformId)) {this.display = false;}}ngOnInit() {}onActivate(事件){}}
就像我提到的,这是一种实际可行的解决方法.
I have several sites built in Angular 7
with SSR
for SEO
improvements. All apps themselves are fine however it always happens that either the very first time or when you perform a hard refresh there is this small blip whereby all content is shown and suddenly the site itself "reloads".
All conditions for ngIf
's that may hide components that are evaluated in the ngOnInit
section of the components seem to be ignored and animations that may start with opacity = 0
to hide HTML elements are also shown.
That said I read a lot regarding this in different forums, posts, github issues etc however I haven't been able to get to any solution.
I tried changing the main.ts
to have:
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic().bootstrapModule(AppModule);
});
instead of the classic bootstrap mechanism for no joy. I have tried the option for the initialNavigation
enabled in the AppRouting
but still doesn't work:
@NgModule({
exports: [ RouterModule ],
imports: [ RouterModule.forRoot(routes, {enableTracing, scrollPositionRestoration: 'enabled', initialNavigation: 'enabled'}) ],
})
export class AppRoutingModule {}
I read through the issue here which I thought it may be related:https://github.com/angular/angular-cli/issues/7477 but it ends referring to the initialNavigation flag which hasn't worked for me.
I'm not sure if there is anything else that I could try here or anything "special" to be set up but it would be really nice to have no delay or hide the actual rendered page which is causing the navigation to be a bit less friendly.
Note that this is JUST on the first load, first time load or hard refresh. The rest of the navigation is absolutely fine.
Actually the flicker occurs because the server side of your app is first loaded by the browser and the client then subsequently loaded. Therefore, a quick workaround I implemented was to add a "display: none" on the landing page for the server side only.
To implement, wrap your main component in a tag and add a conditional display clause to it. I will suggest you do this only on your landing page. Using bootstrap 4, this is what your the main layout should look like:
app.layout.html
<div [className]="!display?'d-none':''">
<app-navbar current_page="post"></app-navbar>
<router-outlet ></router-outlet>
<app-footer></app-footer>
</div>
Take note of the [className]="!display?'d-none':''"
and in the component.ts file:
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) {
}
}
Like I mentioned, its a workaround that actually works.
这篇关于Angular 7 SSR 第一次加载两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!