Angular使用Plotly记录
项目管理的作业是完成一个图书管理管理系统。这是我第一次写前端界面,就且不说写得好不好看,确实遇到了很多问题,比如说之前的一篇博客Angular跨域访问豆瓣API。在昨天晚上基本上是把所有的功能都完成了,但是在部署的时候,发现有一个文件大小好像不是特别对。
情况简介
我们使用的是 Angular-cli
来新建和管理Angular项目,它会使用webpack将我们的项目进行打包以便部署。
至于部署的方式中,我们使用的是angular-cli-ghpages
这个工具。当然我们首先需要设置好github pages上的分支。
通过npm 可以进行安装
1 | npm i -g angular-cli-ghpages |
我们需要将我们的项目进行打包,指定我们给出的域名和子域名:
1 | ng build --prod --base-href "http://bibliosoft.ciaran.cn/" |
之后使用angular-cli-ghpages
提交到github上项目的一个分支里。因为在angular.json
中设置的"outputPath": "dist/frontend"
,所以--dir
的参数为dist\frontend\
1 | ngh --dir dist\frontend\ --cname bibliosoft.ciaran.cn |
然后经队友反应,我们的网页在部署上去之后几乎打不开,这令我非常惊讶。然后通过查看浏览器Dev Tools中的网络情况,我发现有个文件的大小,竟然高达4M,而就是这个文件,花了50+秒的时间来进行加载,给了一种几乎打不开网页的绝望。
在运行了ng build --prod
之后,出现了下面这个输出。
1 | C:\Users\ciaran\Desktop\Projects\BibliosoftFrontend>ng build --prod --base-href "http://bibliosoft.ciaran.cn/" |
可以看到的是,main.js
这个文件足有4MB。在之前的十几次部署中,基本都是800k左右的大小,这说明我们需要删减一些东西了。
分析问题
在Angular的 ng build --prod
中,main.js
这个文件是存放程序的代码的文件。这样的增长肯定是我引入了一些新的依赖导致的。在这个期间我们新加了一个绘图的功能尝试使用了plotly
,以及为了尝试更好的API而使用了material-angular
,当然我确定就是这两个东西让我的main.js
膨胀了起来。于是我使用了webpack-bundle-analyzer
来对我们webpack打包的文件进行分析。
首先安装它:
1 | npm install webpack-bundle-analyzer -g |
我们需要在编译的时候添加一个--stats-json
的参数,这样webpack在打包的时候会输出一个stats.js
文件作为这些文件中文件来源的信息。
1 | ng build --prod --base-href "http://bibliosoft.ciaran.cn/" --stats-json |
然后我们可以对这个文件使用webpack-bundle-analyzer
进行分析,这样我们就能得到一个产物文件夹的内容来源的分析报告。
1 | webpack-bundle-analyzer dist\frontend\stats.json |
这条命令会在8888端口启动一个分析报告的服务器并直接帮你打开这个网址。这样我们能看到这样的一个页面:
虽然在左上角那里勾选Show content of concatenated modules (inaccurate)
能显示更多的信息,但是单看图片就已经能发现:最大的部分来自于plotly.min.js
。
细看之下 material-angular
的部分占了700k,但是 plotly.min.js
的大小为2.73M。
这确实令人难以容忍。基本上去掉了plotly之后就是原来大小了,但是我又确实不希望整个plotly的部分都砍掉。
减小Plotly
在我们的项目中,使用了 angular-plotly.js
库来使用Plot.ly
,据称这是Plot.ly
绘图库的官方Angular wrapper,直接提供了一个plotly-plot
的组件,然后直接使用即可,这样确实非常舒服,但是很明显对我们来说这太沉重了。
首先分析一下我们能做到什么程度,我们在项目中所画的图只有 一张折线图和几张饼图,查阅文档后发现它们大概都来自于Plot.ly
的basic chart的部分,那么我们可以只要plotly的basic部分就足够了。
那样我们需要重写一个Plot.ly
的组件,不过这不算特别困难。首先是安装plotly.js
,这是一个完全必要的部分,即使是 angular-plotly.js
也会依赖于这个plotly.js
。
1 | npm install plotly.js --save |
在安装了依赖后,在使用Plotlyjs的组件的ts文件中添加它。
1 | import * as Plotly from 'plotly.js/dist/plotly-basic.min.js'; |
这样就能确保只引入了 plotly-basic
的部分。
在使用的时候,要画图我们需要调用:
1 | Plotly.plot(element, data, layout) |
其中 element 参数是 ElementRef<any>.nativeElement
,对于如何得到这样的参数,我们可以写出一个组件的示例:
1 | import {Component, OnInit, ViewChild} from '@angular/core'; |
当然有点让我觉得苦恼的是data
和layout
的类型,在使用angular-plotly.js
的时候,我可以指定它们的类型,这样能避免一些类型的错误。这种苦恼的情感一直持续到我看到angualr-plotly
的这段源码
1 | export namespace Plotly { |
居然是any…这样这段直接新建一个Service装下来就有了Plotly类型了。
最后我们将angular-plotly.js
彻底从项目中移除,然后重新编译并运行webpack-bundle-analyzer
。
可以见到,现在Plot.ly
的部分已经只有700k了,而整个main.js
的大小也减小到了2.26 MB。在通过github pages部署之后会使用gzip进行传输,这个大小会被压缩到500k,此时文件的加载时间已经是7秒左右了。
CDN 加速
但是这个速度依然不是非常顺畅,我们仍可以使用CDN对整个内容再进行一次加速。下面是加速前后的对比,来自于ping.chinaz.com
。
因为知道腾讯云的cdn有新用户的300G的流量赠送,所以就直接使用了腾讯云的服务。首先需要进行实名认证,和输入指定网站的类型和信息,这些略过不谈。
之后就是创建需要加速的域名了。在这里它就是 bibliosoft.ciaran.cn
。
之后是填写源站的信息,所谓的源站指的就是在没有CDN网络的情况下的源服务器。最好的方式当然是直接给出服务器的ip地址,这样就能避免有产生解析ip地址的消耗。但是我并不知道github pages的静态ip地址,即使是通过ping能获得ip地址,但是其ip地址也并非是静态的。所以还是填写这里的域名就好了,也就是ciaranchen.github.io
。
在完成了之后,经过一段时间的部署之后,腾讯云会返回一个cdn地址,我们要将它添加到域名的CNAME地址中,这样才是完成了整个CDN的过程。一般来说,腾讯云给出的都是以.cdn.dnsv1.com
结尾的一个地址,比如我所拿到的就是 bibliosoft.ciaran.cn.cdn.dnsv1.com
,然后将它添加到域名解析中去:(也是腾讯云的)
在腾讯云中我们可以设置境内与境外线路,在国外,访问github pages的话网络速度是很好的,而要是走国内的CDN的话,反而就是很愚蠢了,所以设置两条CNAME记录,一条直接走ciaranchen.github.io
的;另一条是走腾讯云CDN的。
还需要等待一段时间让路由生效。在生效后我们就能看到我们的加载时间被极大的缩短了。
现在我们的加载时间已经低到了一秒以下了,这是一个足以满意的结果。