详解基于Angular4+ server render(服务端渲染)开发教程


Posted in Javascript onAugust 28, 2017

目标:

1.更好的 SEO,方便搜索爬虫抓取页面内容

2.更快的内容到达时间(time-to-content)

影响:

1.用户:比原来更快的看到渲染的页面,提升用户体验

2.开发人员:某些代码可能需要特殊处理,才能在服务器渲染应用程序中运行(window,document, navigator等)

安装:

1.nodejs 建议6+

2.angular建议4.1+

理论实现:

详解基于Angular4+ server render(服务端渲染)开发教程

尽管这是一张来自vue官网服务器渲染的一张示意图,但是原理上和angular都是一样的,只是实现的代码不一致。

SSR 有两个入口文件,app-client.js 和 app-server.js, 都包含了应用代码(appmodule),webpack 通过两个入口文件分别打包成给服务端用的 server bundle 和给客户端用的 client bundle。

server bundle运行在node,所以代码里面若出现window,document等浏览器对象则会报错,可以引入jsdom解决,但是比较麻烦,还是建议用angular 官方推荐的方法

import { PLATFORM_ID } from '@angular/core';

import { isPlatformBrowser, isPlatformServer } from '@angular/common';

 

constructor(@Inject(PLATFORM_ID) private platformId: Object) { ... }

 

ngOnInit() {

 if (isPlatformBrowser(this.platformId)) {

   // Client only code.

   ...

 }

 if (isPlatformServer(this.platformId)) {

  // Server only code.

  ...

 }

}

通过PLATFORM_ID令牌注入的对象来检查当前平台是浏览器还是服务器,从而解决该问题。

client bundle运行在浏览器,所以在这用使用浏览器对象就完全没有问题,但若涉及到像fs等node里才有的对象也会报错,解决方案同上。

所以说白了,server bundle就像是一个HTML文件的字符串,通过node渲染好后发送到前端,这个HTML字符串是可以同时运行在node和浏览器的。

而 client bundle就像是一个js文件,我们前端里的所有事件都被包含在里面,我们可以在这里尽情地使用window对象。另外,尽管可以使用document对象,但是基于前端性能的考虑,还是不建议使用的。

 在使用angular这个项目中,开发环境用JIT,生产环境用AOT,这个应该是没有争论的。(具体AOT和JIT的区别 可参考https://angular.cn/docs/ts/latest/cookbook/aot-compiler.html#!#aot-jit)

所以你也猜到了,我这个项目开发环境是浏览器渲染+JIT,生产环境是服务端渲染+AOT。

所以主要步骤归纳如下:

1.  清除编译文件目录下的所有文件。

2.  执行ngc分别预编译客户端代码和服务端代码,然后用webpack打包,压缩

3.  node执行编译后的server bundle代码

具体代码实现:

1、建立nodejs服务器,采用express框架(koa也是可以的),监听端口

const express = require('express');
const desktop = express();

const port = process.env.NODE_PORT ? process.env.NODE_PORT : 4200;

desktop.listen(port + 1, () => {
 console.log(`Desktop Listening on: http://localhost:${port}`);
});

2、渲染页面,处理请求

import 'zone.js/dist/zone-node';
import { ngExpressEngine } from '@nguniversal/express-engine';
import { AppServerModuleNgFactory } from './app-server.module.ngfactory';

const ROOT = path.join(path.resolve(__dirname),'..','build');

 function response(req, res) {
  res.render(`index.html`, {
   req,
   res
  });
 }

 app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory
 }));

 app.set('view engine', 'html');
 app.set('views', ROOT);

 app.get('/', response);
 routes.forEach((r) => {
   app.get(r, response);
   app.get(`${r}/*`, response);
  }
 );

angular服务端渲染能一定程度上优化用户体验,但是还是有个小问题,用户首次加载时,仍然需要加载完整个网站的内容。

所以我目前考虑在angular4 ssr的基础上加入lazy load(懒惰加载,也称按需加载),懒惰加载模块可帮助我们减少启动时间。通过懒惰加载,我们的应用程序不需要一次加载所有内容,只需要加载用户在首次加载应用程序时看到的内容。

只有当用户导航到他们的路由时,才会加载懒惰加载的模块。以进一步优化用户体验,待完成后再写一遍随笔记录心路历程。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 实现父窗口引用弹出窗口的值的脚本
Aug 07 Javascript
js中判断文本框是否为空的两种方法
Jul 31 Javascript
JQuery+JS实现仿百度搜索结果中关键字变色效果
Aug 02 Javascript
jquery限制输入字数,并提示剩余字数实现代码
Dec 24 Javascript
JavaScript加强之自定义callback示例
Sep 21 Javascript
JQuery与Ajax调用新浪API获取短网址的代码
Feb 07 Javascript
javascript自定义的addClass()方法
May 28 Javascript
浅谈javascript回调函数
Dec 07 Javascript
JavaScript  cookie 跨域访问之广告推广
Apr 20 Javascript
微信小程序 欢迎界面开发的实例详解
Nov 30 Javascript
VUE项目初建和常见问题总结
Sep 12 Javascript
基于VUE的v-charts的曲线显示功能
Oct 01 Javascript
JS实现图片手风琴效果
Apr 17 #Javascript
vue服务端渲染的实例代码
Aug 28 #Javascript
jQuery 1.9版本以上的浏览器判断方法代码分享
Aug 28 #jQuery
使用react-router4.0实现重定向和404功能的方法
Aug 28 #Javascript
vue.js路由跳转详解
Aug 28 #Javascript
jQuery Collapse1.1.0折叠插件简单使用
Aug 28 #jQuery
解决IE7中使用jQuery动态操作name问题
Aug 28 #jQuery
You might like
php使用多个进程同时控制文件读写示例
2014/02/28 PHP
CodeIgniter与PHP5.6的兼容问题
2015/07/16 PHP
PHP中COOKIES使用示例
2015/07/26 PHP
又拍云异步上传实例教程详解
2016/04/19 PHP
PHP实现mysqli批量执行多条语句的方法示例
2017/07/22 PHP
PHP+Mysql分布式事务与解决方案深入理解
2021/02/27 PHP
javascript的键盘控制事件说明
2008/04/15 Javascript
js自动查找select下拉的菜单并选择(示例代码)
2014/02/26 Javascript
Js获取下拉框选定项的值和文本的实现代码
2014/02/26 Javascript
网页运行时提示对象不支持abigimage属性或方法
2014/08/10 Javascript
分析了一下JQuery中的extend方法实现原理
2015/02/27 Javascript
jQuery实现dialog设置focus焦点的方法
2015/06/10 Javascript
详解微信小程序开发—你期待的分享功能来了,微信小程序序新增5大功能
2016/12/23 Javascript
JS正则RegExp.test()使用注意事项(不具有重复性)
2016/12/28 Javascript
AngularJS中控制器函数的定义与使用方法示例
2017/10/10 Javascript
防止页面url缓存中ajax中post请求的处理方法
2017/10/10 Javascript
JavaScript中Require调用js的实例分享
2017/10/27 Javascript
Vue-Router实现组件间跳转的三种方法
2017/11/07 Javascript
javascript+css3开发打气球小游戏完整代码
2017/11/28 Javascript
[01:08:32]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第二场 1月18日
2021/03/11 DOTA
Python代理抓取并验证使用多线程实现
2013/05/03 Python
python排序函数sort()与sorted()的区别
2018/09/18 Python
Python并行分布式框架Celery详解
2018/10/15 Python
python 遗传算法求函数极值的实现代码
2020/02/11 Python
Django CSRF认证的几种解决方案
2020/03/03 Python
Python自带的IDE在哪里
2020/07/01 Python
Python变量格式化输出实现原理解析
2020/08/06 Python
基于python实现图片转字符画代码实例
2020/09/04 Python
python实现计算图形面积
2021/02/22 Python
推荐10个HTML5响应式框架
2016/02/25 HTML / CSS
Gucci法国官方网站:意大利奢侈品牌
2018/07/25 全球购物
NBA欧洲商店(英国):NBA Europe Store UK
2018/07/27 全球购物
会计电算化专业毕业生自荐信
2013/12/20 职场文书
中学生自我鉴定
2014/02/04 职场文书
考生诚信考试承诺书
2014/05/23 职场文书
教研活动主持词
2015/07/03 职场文书