详解基于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中encodeURI和decodeURI方法使用介绍
May 06 Javascript
javascript数组去重的方法汇总
Apr 14 Javascript
jquery实现垂直和水平菜单导航栏
Aug 27 Javascript
微信小程序 slider 详解及实例代码
Jan 10 Javascript
js图片上传的封装代码
Aug 01 Javascript
JavaScript输入分钟、秒倒计时技巧总结(附代码)
Aug 17 Javascript
Node.js文件编码格式的转换的方法
Apr 27 Javascript
使用JavaScript实现node.js中的path.join方法
Aug 12 Javascript
关于node-bindings无法在Electron中使用的解决办法
Dec 18 Javascript
node静态服务器实现静态读取文件或文件夹
Dec 03 Javascript
js通过循环多张图片实现动画效果
Dec 19 Javascript
Node.js学习之内置模块fs用法示例
Jan 22 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
Search File Contents PHP 搜索目录文本内容的代码
2010/02/21 PHP
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
PDO::commit讲解
2019/01/27 PHP
TP5框架实现的数据库备份功能示例
2020/04/05 PHP
javascript正则匹配汉字、数字、字母、下划线
2014/04/10 Javascript
jQuery实现的一个tab切换效果内部还嵌有切换
2014/08/10 Javascript
JS实现的网页背景闪电闪烁效果代码
2015/10/17 Javascript
如何用JS判断两个数字的大小
2016/07/21 Javascript
React学习笔记之事件处理(二)
2017/07/02 Javascript
vue.js语法及常用指令
2017/10/29 Javascript
如何利用@angular/cli V6.0直接开发PWA应用详解
2018/05/06 Javascript
element ui table(表格)实现点击一行展开功能
2018/12/04 Javascript
JS检索下拉列表框中被选项目的索引号(selectedIndex)
2019/12/17 Javascript
vue实现商品列表的添加删除实例讲解
2020/05/14 Javascript
angular中的post请求处理示例详解
2020/06/30 Javascript
Python 学习笔记
2008/12/27 Python
Python中使用Beautiful Soup库的超详细教程
2015/04/30 Python
Python字符串格式化的方法(两种)
2017/09/19 Python
解读! Python在人工智能中的作用
2017/11/14 Python
Python 绘图库 Matplotlib 入门教程
2018/04/19 Python
python实现QQ邮箱发送邮件
2020/03/06 Python
Python响应对象text属性乱码解决方案
2020/03/31 Python
Python的Django框架实现数据库查询(不返回QuerySet的方法)
2020/05/19 Python
Python数据可视化图实现过程详解
2020/06/12 Python
python3中calendar返回某一时间点实例讲解
2020/11/18 Python
详解CSS中iconfont的使用
2015/08/04 HTML / CSS
欧洲领先的电子和电信零售商和服务提供商:Currys PC World Business
2017/12/05 全球购物
Ralph Lauren英国官方网站:Ralph Lauren UK
2018/04/03 全球购物
英国家居用品和家居装饰品购物网站:Cox & Cox
2019/08/25 全球购物
建筑经济管理专业求职信分享
2014/01/06 职场文书
村官学习十八大感想
2014/01/15 职场文书
经济纠纷起诉状
2015/05/20 职场文书
争做文明公民倡议书
2019/06/24 职场文书
Pytest中skip和skipif的具体使用方法
2021/06/30 Python
MySQL中utf8mb4排序规则示例
2021/08/02 MySQL
win10电脑老是死机怎么办?win10系统老是死机的解决方法
2022/08/05 数码科技