Angular 2-如何使用Prerender.io以及懒惰的负载



由于Angular Universal不会在CLI中呆一段时间,因此我必须使用Prerender.io允许SEO正常工作。但是,经过一些测试后,它似乎并没有那么出色,因为它似乎没有等待懒惰的加载模块,因此SEO仍然失败。

在此位置的网站上,他们这样说:

您的页面只是部分渲染吗?

我们的Prerender Server尽力确定页面何时完成 通过计算飞行中的请求数来加载。一旦数字 在飞行中的请求达到零,我们等待一小段时间 然后保存HTML。如果这太早保存页面,您可以使用 我们的window.prerenderready标志通知服务器您的页面是 准备保存。

将其放入您的html:

<script> window.prerenderReady = false; </script>

当我们看到window.prerenderready设置为false时,我们将等到它 设置为true保存HTML。当您的页面是 准备就绪(通常在Ajax呼叫后):

window.prerenderReady = true;

这是我不明白该怎么做的地方。由于Angular从模板中删除脚本标签(不确定这只是CLI行为还是Angular本身),因此我无法设置初始脚本标签。我也无法弄清楚如何从组件类中的模板脚本标签中更新window属性prerenderReady,因为我不能仅使用window.prerenderReady = true并期望它可以正常工作,因为必须将脚本添加到模板中。

是否有人设法弄清楚这个问题或对我如何实现这一目标有任何想法?

remove: server.use(prerender.removeScriptTags());

prerender.io可以设置为留在脚本中,以便它们可以运行。

我的Meteor-Angular2设置给了我同样的悲伤。我的标题和页脚模块会呈现,但不会输出路由器输出。我放置:
<script> window.prerenderReady = false; </script>
在我的主index.html上(包含主<app></app>标签),并放置:
window.prerenderReady = true;
在我上次回调结束时。然后我评论了:
//server.use(prerender.removeScriptTags());
在我的Prerender Server的服务器中 - 最终正确渲染。

好吧,我做了这个工作,但是这似乎是一个相当复杂的解决方案,所以希望有人比我更聪明:)

首先, src/polyfills.ts中的所有浏览器polyfills(可能不是所有浏览器都需要,但我尚未一对一测试它们):

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

接下来,您需要在index.html<head>中获得prerenderReady标志。Angular不会剥离评论,因此在建造之前,我会在其中留一个旗帜:

<head>
    <!--prerender-->
</head>

现在,运行ng build后,您需要用实际的脚本标签替换该标志。我使用Shell脚本和sed命令来执行此操作。类似:

TPL="<!--prerender-->"
PRERENDER_SCRIPT="<script>window.prerenderReady = false;</script>"
# replace the comment with the actual script tag in the html file and save
# that file's contents as a string in the INDEX_HTML variable
INDEX_HTML=$(sed "s/$TPL/$PRERENDER_SCRIPT/g;" dist/browser/index.html);
# remove the original index.html file and create an empty one in its place
rm dist/browser/index.html
touch dist/browser/index.html
# echo the INDEX_HTML string into the new file
echo "$INDEX_HTML" > dist/browser/index.html

注意我对OSX上安装sed的安装有模糊的回忆,但我真的不记得这些步骤。如果您不在Linux上,并且sed对您不起作用,那么您只需要搜索解决方案即可。

最后,您需要将该prerenderReady标志设置为True某个地方。我在AppComponentOnInit实现中这样做:

export class AppComponent implements OnInit
{
    ngOnInit()
    {
        window.prerenderReady = true;
    }
}

它可能还提到要在打字稿应用中使用window,您需要在文件中使用类似的内容,我调用typings.d.ts

interface Window
{
    prerenderReady:boolean;
}

以及对我放在app.module.ts文件顶部的该输入文件的引用:

/// <reference path="../typings.d.ts" />

希望能帮助某人。

我建议在使用angular.json或编辑WebPack构建注入Angular JS文件之前,将第一个脚本放在页面顶部的index.html中。window.prerenderready = false

然后在主app.ts文件中,获取对窗口对象的引用,然后put window.prerenderready = true ngonviewinit hook:

 public ngAfterViewInit(): void {
        this.windowReference.prerenderReady = true;
    }

相关内容

最新更新