本文转自:https://blog.csdn.net/itest_2016/article/details/80048398css
Angular是一个比较完善的前端MVC框架,包含了模板,数据双向绑定,路由,服务,过滤器,依赖注入等等全部的功能。在Web开发先后端流行的今天,咱们在某个项目中也尝试使用该框架。前端
很快按照官网上的例子搭建了一个标准工程,在项目初期工程文件不是不少的时候,编译、打包、而后运行,访问项目的各个页面都很快。和传统的模板引擎相比这种先后端分离不只工程化更加成熟(前端、后端开发人员专一本身的领域),并且各个页面加载速度很快,但是说第一次尝到了这种先后端彻底分离所带来的好处。但渐渐的咱们发现了一个问题,就是首页加载速度愈来愈慢了以下图:nginx
耗时居然已经达到了10s,但进入首页后各个页面加载速度依然很快。这时候就不得不分析缘由了,其实答案很明显,有2个文件特别大分别是:main.bundle.js(2.3M)、vendor.bundle.js(4M)。并且这2个文件在第一次访问时必须会加载,为何进入后访问就很快了?进一步分析,看看编译后这2个文件的源码,就能发现main. bundle .js是把咱们全部模块本身编写的js都打包到一块了,而后vendor.bundle.js包含了angular的公共库。这样随着咱们编写的js代码愈来愈多,引用的公共库愈来愈多的时候,页面的加载速度就会愈来愈慢。因为浏览器自己会缓存这些静态资源文件,而全部的文件都在第一次访问页面的时候都加载了,这样就致使第一次访问特别慢,后续各个页面都很快的奇怪现象。web
咱们传统web开发时css、js文件,有一个全局和各个模块单独这样划分的。这样等到须要的时候在加载对应css、js文件,加载时间被分摊到各个页面因此就不会出现某个页面加载慢的现象。其实能够类比,在angular中也有相似的优化方法。多模块懒加载即可以达到咱们说的这种效果。后端
优化前咱们工程就一个主模块文件(app.module.ts),路由跳转各页面其实都属于该模块一部分浏览器
以下图(路由对应各页面其实都是子组件,因此编译时都会被打包到同一个文件):缓存
进行多模块拆分后以下图:tomcat
能够看到写法明显不一样,每一个路由页面其实都是一个单独模块,而后在编译时每一个模块都会单独编译成一个文件。并且路由到某个页面时,才会加载该模块js文件。app
多模块拆分以前,编译以下图:框架
拆分后:
关注main.bundle.js文件变成了605kb,而后多了不少chunk.js。这些chunk.js其实就是各个模块编译文件。
具体进行多模块拆分方法以下:
【step1】在工程src/app 目录下新建2个文件,root.module.ts、share.module.ts。
在root.module.ts放一些其它全部模块都要引用的component、service、pipe。对于service须要在providers中对外暴露,其它公共组件、模块在exports中暴露(注意:相同组件、模块不能在多个模块中重复引用,不然编译会报错,能够经过以下方法对外暴露一次)
而后在share.module.ts模块中import root.module.ts。此外该模块会存放一些公共component、service、pipe等会被除了app.module.ts在外其它模块引用。这样作的目地是减小app.module.ts引用公共库大小,在上面编译图中能够发现vendor.bundle.js文件也很是大,这样作的目的是减小该文件的大小(此处大概能优化个10%)。
【step2】
对各个路由模块作以下改造:
以job-record模块为例,以下图:
改造前:
改造后:
能够明显看到增长了2个新文件,job-record-routing.module.ts、job-record.module.ts。这2个文件的用途就是把job-record变成一个真正的子模块。
job-record-routing.module.ts内容以下(该模块路由配置):
job-record.module.ts内容以下(具体模块配置):
job-record目录下其它文件无须修改,对应其它页面都用相似方法作模块拆分。(注意:对于父子页面,因为子页面依赖父页面加载,因此不能这样作拆分。)
【step3】
app.module.ts作以下改下(和原来该模块编写方式对比提到)
进行了多模块拆分后发现,main.bundle.js文件确实变小了不少,已经达到咱们预期,并且也不会随着咱们本身编写js增长而愈来愈大了,这时候发现首页访问速度大概加快了30%。此时加载速度以下:
但仍是很慢,几乎还须要5s时间,缘由是vendor.bundle.js文件仍是很大。
vendor.bundle.js都是angular自己依赖的一些公共库,不是咱们本身编写的,因此刚刚的多模块优化对它的大小变化几乎没有影响。这是打开该文件能够看到明显没有通过压缩优化。查了一些官网文档和百度发现angular编译果真有优化方式。经过增长编译参数:--prod –aot
编译后发现,居然报了一堆错误。不过不要惊慌,那是优化编译时对ts语法检查比较严谨,咱们代码中不少地方写的不够严谨,只能硬着头皮一行行修改了,此外别无它法。
好不容易解决了上面优化报错地方。这时优化编译也过了,而后首页加载速度也是很是快了。但是访问其它页面时会报以下错误:
进一步分析是代码种以下地方报错(压缩后的)
原始报错代码位置以下图。
但仔细分析了此处代码,没有看错有问题地方。结合上面报错,进一步调试发现map相关代码在优化时被压缩没了天然报错,咱们优化编译方式都是官方的,并且此处代码也并没有问题,猜测多是该模块没有显示引入。引入以下模块:
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
优化编译后发现问题果真解决了,如今首页访问速度提高了,各个页面访问也没有问题了(若是发现通过优化编译后,还会有其它相似问题,那么极可能就是某些依赖模块没有显示引入致使)。
优化后首页加载速度以下图:
最后部署在正式环境如nginx或tomcat下经过开启gzip压缩会发现静态文件大小还会进一步变小,页面访问速度还会提高。