angular2 学习笔记 ( server-side rendering, angular universal, 服务端渲染 )

更新 : 2018-01-10 

大半年过去了依然没有做 server side render 的冲动,但是一直有关注这方便的做法. 

今天领悟了一些道理, 这里做个记入. 

server side render 其实也不只是为了 SEO, 而且自从 Google 能渲染 js 之后更加不重要了. 

其它使用的地方比如 fb, whatsap, wechat 的爬虫都是可以用到 server side render 的 

ssr 有一个规则就是远离 dom, 其实应该说 "render" 的时候 "不依赖" browser. 

如果你写过后端渲染就应该很有这个 feel, 我们会用 html + css 实现所有的设计, 用 responsive 的 css 写法去做响应式. 

所以在 render 的时候, 是完全不需要以来任何 browser 元素的. 

 

 

 

更新 : 2017-05-03 

angular 4.0 把 universal 纳入自己的阵营, 有许多的改变, 目前已经有 githud starter 了 

https://github.com/angular/universal 

nodejs, asp.net core 都有. 

不过呢,我依然没有去使用它,等到 cli 支持了才用. 

目前接受一个临时方案给大家. 

https://prerender.io

它的做法是使用 js 引擎渲染你的页面然后收入起来,当发现蜘蛛访问时,返回这个 cache 页面.

页面被保存在另一台服务器上,你有 2 个选择,1是用 prerender.io 的服务器, 首 250 page 免费,之后的就要收费了. 

第 2 选择是自己建一个服务器来收藏, prerender 是开源项目有提供全部代码.

asp.net 网站服务器基本设置

https://github.com/greengerong/Prerender_asp_mvc 

angular 方面唯一要留意的是 import polyfills, 因为 prerender.io 的 js 引擎是 es5 的. 

如果有使用 ajax 或 lazyload module 记得使用 

参考 : https://prerender.io/documentation/best-practices

ngAfterViewInit() {
  window['prerenderReady'] = true;
}

像这样. 

如果运行不起来, prerender.io 还有一个很好的 support. 

support@prerender.io

即使你没有付费, 他依然用心的帮你调试找出问题,非常专业 ! 

 

 

 

2017-02-10

服务端渲染主要是为了 SEO 搜素引擎.

angular universal 为我们处理好这一切. 

从前需要特地写一个版本给 SEO 做两份工 /.\ 

 

refer : 

 
服务端没有任何 browser 的功能, 只有 javascript , 所以要很好的支持 server-side render 我们必须限制我们的代码.
比如 : 不可以直接调用 Dom/Bom api 
包括 Window, FileReader, xmlhttprequest, Navigator, document.queryselector 等等
 
 
第一次听起来觉得不可思议, 不过只要你依据下面我说的方式就可以了.
首先要明白, 服务端渲染, 只是为了 SEO,SEO 只是一个 reader, 它不会和你的界面有任何互动, 所以可以说整个过程中, 代码只会运行 ngOnInit 的部分.
其它的 onClick event 那些都是不会被运行的哦.
 
是不是觉得范围小了很多呢.. 呵呵
 
步骤 : 
1. 判断你的代码是否会被 server-side 运行.
2. 判断你的代码是否涉及了 Dom/Bom ( encodeURIComponent 是 javascript 哦 )
3. 如果涉及了, 那么看看 angular 有没有替代的方法, 比如 Renderer, Http, 都是用来替代 Dom/Bom 的,让你不直接接触, 在不同的场景下 , universal 会改变它们的执行. 
4. 如果 angular 没有替代方案, 那么判断你的代码是否真的需要在 server-side 运行, 如果不需要你可以使用 if(isBrowser) *ngIf="isBrowser" 来禁止它们运行. 
通过上面的步骤基本上可以让你安心的使用 universal 了 
 
 
比如这样写是 ok 的, 只要它不跑就不会有 error 
  <input type="text" #input (blur)="$event.target.className = 'haha';blur($event.target)" >
  {{ input.value }}
  <div (click)="click($event)" >click</div>

 

 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2017-02-10 10:47  兴杰  阅读(3566)  评论(0编辑  收藏  举报