详解基于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 学习笔记二 字符串拼接
Mar 28 Javascript
jquery ajax实现下拉框三级无刷新联动,且保存保持选中值状态
Oct 29 Javascript
javascript刷新父页面的各种方法汇总
Sep 03 Javascript
在Node.js应用中读写Redis数据库的简单方法
Jun 30 Javascript
如何消除inline-block属性带来的标签间间隙
Mar 31 Javascript
浅谈React + Webpack 构建打包优化
Jan 23 Javascript
promise和co搭配生成器函数方式解决js代码异步流程的比较
May 25 Javascript
AngularJS发送异步Get/Post请求方法
Aug 13 Javascript
iView-admin 动态路由问题的解决方法
Oct 03 Javascript
highCharts提示框中显示当前时间的方法
Jan 18 Javascript
Echarts实现多条折线可拖拽效果
Dec 19 Javascript
Vue实现省市区三级联动
Dec 27 Vue.js
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多文件上传实例
2015/07/09 PHP
微信公众号开发之语音消息识别php代码
2016/08/08 PHP
学习thinkphp5.0验证类使用方法
2017/11/16 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
2019/11/19 PHP
JS判断移动端访问设备并加载对应CSS样式
2014/06/13 Javascript
TypeScript 学习笔记之基本类型
2015/06/19 Javascript
bootstrap网页框架的使用方法
2016/05/10 Javascript
微信页面倒计时代码(解决safari不兼容date的问题)
2016/12/13 Javascript
JavaScript实现的斑马线表格效果【隔行变色】
2017/09/18 Javascript
node.js中路由,中间件,ge请求和post请求的参数详解
2017/12/26 Javascript
JS扩展String.prototype.format字符串拼接的功能
2018/03/09 Javascript
利用js实现前后台传送Json的示例代码
2018/03/29 Javascript
jQuery 点击获取验证码按钮及倒计时功能
2018/09/20 jQuery
Vue一次性简洁明了引入所有公共组件的方法
2018/11/28 Javascript
element-ui组件table实现自定义筛选功能的示例代码
2019/03/15 Javascript
cordova+vue+webapp使用html5获取地理位置的方法
2019/07/06 Javascript
vue中动态select的使用方法示例
2019/10/28 Javascript
JS实现多选框的操作
2020/06/24 Javascript
Django中更新多个对象数据与删除对象的方法
2015/07/17 Python
使用python绘制常用的图表
2016/08/27 Python
利用Tkinter和matplotlib两种方式画饼状图的实例
2017/11/06 Python
Python程序包的构建和发布过程示例详解
2019/06/09 Python
python3实现带多张图片、附件的邮件发送
2019/08/10 Python
pycharm 更改创建文件默认路径的操作
2020/02/15 Python
HTML5在canvas中绘制复杂形状附效果截图
2014/06/23 HTML / CSS
HTML5+CSS3:3D展示商品信息示例
2017/01/03 HTML / CSS
使用canvas生成含有微信头像的邀请海报没有微信头像问题
2019/10/29 HTML / CSS
俄罗斯花园种植材料批发和零售网上商店:Беккер
2019/07/22 全球购物
会计专业自我鉴定范文
2013/10/06 职场文书
中学运动会广播稿
2014/01/19 职场文书
县优秀教师事迹材料
2014/01/31 职场文书
副总经理岗位职责
2014/03/16 职场文书
项目建议书范文
2014/05/12 职场文书
科技工作者先进事迹
2014/08/16 职场文书
员工三分钟演讲稿
2014/08/19 职场文书
导游词之澳门玫瑰圣母堂
2019/12/03 职场文书