详解基于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的gzip静态压缩方法
Jan 05 Javascript
JavaScript DOM 学习第五章 表单简介
Feb 19 Javascript
JS拖动技术 关于setCapture使用
Dec 09 Javascript
23个超流行的jQuery相册插件整理分享
Apr 25 Javascript
javascript权威指南 学习笔记之变量作用域分享
Sep 28 Javascript
div当滚动到页面顶部的时候固定在顶部实例代码
May 27 Javascript
JavaScript中的console.assert()函数介绍
Dec 29 Javascript
jqueryMobile 动态添加元素,展示刷新视图的实现方法
May 28 Javascript
浅谈js控制li标签排序问题 js调用php函数的方法
Oct 16 Javascript
如何使用angularJs
May 08 Javascript
解决antd 表单设置默认值initialValue后验证失效的问题
Nov 02 Javascript
ES6中的类(Class)示例详解
Dec 09 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
自动把纯文本转换成Web页面的php代码
2009/08/27 PHP
利用curl抓取远程页面内容的示例代码
2013/07/23 PHP
php页面,mysql数据库转utf-8乱码,utf-8编码问题总结
2015/08/27 PHP
PHP模板引擎Smarty自定义变量调解器用法
2016/04/11 PHP
php版微信公众平台接口参数调试实现判断用户行为的方法
2016/09/23 PHP
Yii2表单事件之Ajax提交实现方法
2017/05/04 PHP
php 的多进程操作实践案例分析
2020/02/28 PHP
超级强大的表单验证
2006/06/26 Javascript
javascript客户端解决方案 缓存提供程序
2010/07/14 Javascript
Node.js生成HttpStatusCode辅助类发布到npm
2013/04/09 Javascript
javascript抖动元素的小例子
2013/10/28 Javascript
jQuery插件开发详细教程
2014/06/06 Javascript
在NodeJS中启用ECMAScript 6小结(windos以及Linux)
2014/07/15 NodeJs
javascript中setTimeout使用指南
2015/07/26 Javascript
使用react-router4.0实现重定向和404功能的方法
2017/08/28 Javascript
vue项目常用组件和框架结构介绍
2017/12/24 Javascript
webpack打包node.js后端项目的方法
2018/03/10 Javascript
React 组件中的 bind(this)示例代码
2018/09/16 Javascript
JS实现十分钟倒计时代码实例
2018/10/18 Javascript
vue微信分享到朋友圈 vue微信发送给好友
2018/11/28 Javascript
使用Vue.set()方法实现响应式修改数组数据步骤
2019/11/09 Javascript
Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例
2014/06/10 Python
详解Python异常处理中的Finally else的功能
2017/12/29 Python
python 对给定可迭代集合统计出现频率,并排序的方法
2018/10/18 Python
在Python中获取两数相除的商和余数方法
2018/11/10 Python
python实现微信每日一句自动发送给喜欢的人
2019/04/29 Python
对Python 中矩阵或者数组相减的法则详解
2019/08/26 Python
python不同系统中打开方法
2020/06/23 Python
python如何使用腾讯云发送短信
2020/09/17 Python
Python字典取键、值对的方法步骤
2020/09/30 Python
CSS3混合模式mix-blend-mode/background-blend-mode简介
2018/03/15 HTML / CSS
创业计划书的内容步骤和要领
2014/01/04 职场文书
社区安全生产月活动总结
2014/07/05 职场文书
暑期社会实践证明书
2014/11/17 职场文书
小学四年级学生评语
2014/12/26 职场文书
违纪检讨书
2015/01/27 职场文书