详解基于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 相关文章推荐
jQuery中文入门指南,翻译加实例,jQuery的起点教程
Feb 09 Javascript
优化网页之快速的呈现我们的网页
Jun 29 Javascript
setTimeout的延时为0时多个浏览器的区别
May 23 Javascript
js通过location.search来获取页面传来的参数
Sep 11 Javascript
JavaScript中return false的用法
Mar 12 Javascript
jquery事件的ready()方法使用详解
Nov 11 Javascript
jQuery实现的给图片点赞+1动画效果(附在线演示及demo源码下载)
Dec 31 Javascript
jQuery fadeOut 异步实例代码详解
Aug 18 Javascript
js实现String.Fomat的实例代码
Sep 02 Javascript
JavaScript中访问id对象 属性的方式访问属性(实例代码)
Oct 28 Javascript
使用Angular.js实现简单的购物车功能
Nov 21 Javascript
轻松学习JavaScript函数中的 Rest 参数
May 30 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仿discuz分页效果代码
2008/10/02 PHP
PHP 字符串正则替换函数preg_replace使用说明
2011/07/15 PHP
php 按指定元素值去除数组元素的实现方法
2011/11/04 PHP
经典PHP加密解密函数Authcode()修复版代码
2015/04/05 PHP
Thinkphp和onethink实现微信支付插件
2016/04/13 PHP
thinkphp5实现微信扫码支付
2019/12/23 PHP
在网页里看flash的trace数据的js类
2009/01/10 Javascript
jquery幻灯片插件bxslider样式改进实例
2014/10/15 Javascript
理解js回收机制通俗易懂版
2016/02/29 Javascript
javascript数据类型详解
2017/02/07 Javascript
javascript设计模式之策略模式学习笔记
2017/02/15 Javascript
利用javascript如何随机生成一定位数的密码
2017/09/22 Javascript
解决html-jquery/js引用外部图片时遇到看不了或出现403的问题
2017/09/22 jQuery
微信小程序配置服务器提示验证token失败的解决方法
2019/04/03 Javascript
使用vue-cli3 创建vue项目并配置VS Code 自动代码格式化 vue语法高亮问题
2019/05/14 Javascript
解决vue组件中click事件失效的问题
2019/11/09 Javascript
[02:23]2016国际邀请赛中国区预选赛wings晋级之路
2016/06/29 DOTA
Python新手入门最容易犯的错误总结
2017/04/24 Python
老生常谈Python startswith()函数与endswith函数
2017/09/08 Python
转换科学计数法的数值字符串为decimal类型的方法
2018/07/16 Python
python发送告警邮件脚本
2018/09/17 Python
浅谈Python采集网页时正则表达式匹配换行符的问题
2018/12/20 Python
python图形工具turtle绘制国际象棋棋盘
2019/05/23 Python
Python实现串口通信(pyserial)过程解析
2019/09/25 Python
python+tifffile之tiff文件读写方式
2020/01/13 Python
python自动化测试三部曲之unittest框架的实现
2020/10/07 Python
python tkinter实现下载进度条及抖音视频去水印原理
2021/02/07 Python
一套C++笔试题面试题
2012/06/06 面试题
大学生关于奋斗的演讲稿
2014/01/09 职场文书
安全承诺书范文
2014/03/26 职场文书
县委党的群众路线教育实践活动工作情况报告
2014/10/25 职场文书
戒赌保证书
2015/05/11 职场文书
新员工辞职信范文
2015/05/12 职场文书
2019年聘任书的写作格式及范文!
2019/07/03 职场文书
深入详解JS函数的柯里化
2021/06/09 Javascript
Zabbix对Kafka topic积压数据监控的解决方案
2022/07/07 Servers