Angular 2 - 如何使用prerender.io以及延迟加载

时间:2017-03-14 07:42:24

标签: javascript angular typescript seo prerender

由于Angular Universal不会在CLI中使用很长一段时间,我必须使用prerender.io来让SEO正常工作。但是,在经过一些测试之后,似乎它并没有那么好用,因为它似乎没有等待延迟加载的模块,所以SEO仍然失败。

他们在this location的网站上说:

  

您的网页是否仅部分呈现?

     

我们的Prerender服务器会尽力确定页面何时完成   通过计算飞行中的请求数量来加载。一旦数量   在飞行中的请求达到零,我们等待一小段时间   然后保存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并期望它可以工作,因为脚本必须添加到模板中。

有没有人设法解决这个问题,或者对如何实现这一目标有任何想法?

2 个答案:

答案 0 :(得分:0)

删除: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的server.js中 - 它最终正确呈现。

答案 1 :(得分:0)

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

首先,取消注释fstream & const中的所有浏览器polyfill(可能并非所有浏览器polyfill都需要,但我还没有对它们进行逐个测试):

src/polyfills.ts

接下来,您需要在/** 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'; prerenderReady的脚本标记中获取<head>标记。在我建立之前,Angular并没有删除评论,我在那里留下了一面旗帜:

index.html

现在,在运行<head> <!--prerender--> </head> 之后,您需要将该标志替换为实际的脚本标记。我使用shell脚本和ng build命令执行此操作。类似的东西:

sed

我对OSX上安装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 有一个模糊的回忆,但我不记得这些步骤。如果您不在Linux上并且sed不能为您工作,那么您只需向谷歌寻求解决方案。

最后,您需要在某处将sed标志设置为true。我是在prerenderReady AppComponent实施中执行此操作的:

OnInit

可能还要提到的是,为了在TypeScript应用程序中使用export class AppComponent implements OnInit { ngOnInit() { window.prerenderReady = true; } } ,我需要在文件中调用window这样的内容:

typings.d.ts

除了我对interface Window { prerenderReady:boolean; } 文件顶部的那个打字文件的引用:

app.module.ts

希望能帮助别人。