优化vue build后的部署项目加载速度
1. 关于vue 打包后的项目运行逻辑
首先要明白vue打包后的项目加载时依赖的谁,打开dist文件包,从js文件中可以看到一个manifest.开头后面跟着一长串随机码的.js文件, 这个就是整个vue项目的加载工具,
从这个地方可以看到, 加载的方式是script标签加载需求文件, 什么时候加载就需要看app开头的后面一串随机码的文件了。
如图所示,在app文件中包含了咱们的项目核心,路由配置,从这一段可以看出来,他是在进入路由加载后进行的加载,这里的g.e就是上面的script加载的方法。
那么,可想而知,跳入到路由才会加载路由所需要的模块文件,这是大家经常做的懒加载优化。目的是降低页面初始化的依赖文件大小,不然路由依赖文件和主要文件合在一起加载会导致单个文件体积过大完成时间被拉长导致项目出现慢,但是分开的话又会导 致现在这种情况,一旦某个路由的依赖文件过大,也会照成加载过慢
这个图就是整个优化思路的核心,将过大的文件同步加载,以减少时间。
接下来说说如何实现 先上代码
/** * 优化加载类 * 将webpack异步加载得文件提前加载用在调用使用 */ class Preload { constructor (){ // url this.url = null; // 文件内容 this.body = null; // 状态 this.state = 0; // 添加到全局 this.constructor.Maps.push(this); } load (url){ this.url = url; // 新建一个缓存对象 fetch(url).then(function(response) { return response.text() }).then((body) => { // 缓存文件内容 this.body = body; if( this.state == 2 ){ this.run(); }else { // 修改状态 this.state = 1; } }) } goonLoad (){ this.onload && this.onload(); this.onload = null; } run (fn){ fn && (this.onload = fn); if( this.state == 1 ){ eval(this.body), this.goonLoad(); }else { this.state = 2; } } static Maps = []; static get (url){ return this.Maps.find((Pro)=>{ return Pro.url === url; }); } static url (url){ (new this()).load(url); } static run (url){ const pro = this.get(url); pro && pro.run(); } static appendChild (script){ const url = script.getAttribute("src"); const pro = this.get(url); if( pro ){ pro.run(script.onload); }else { document.head._appendChild(script); } } } // Preload.url("./static/js/app.a5eb45e01a814e58c58f.js"); // Preload.url("./static/js/0.b1ab96be57c754c737b4.js"); // Preload.url("./static/js/11.c98ac5bee35902600d66.js"); // 预加载 // Preload.url("http://10.168.11.225:8081/baidumap/bmapgl/sty/fs.js?udt=20190618&v=001"); // fetch("http://10.168.11.225:8081/baidumap/bmapgl/mapstyle/DarkColorMapStyle.json") document.head._appendChild = document.head.appendChild; document.head.appendChild = function(script){ // if( ) // this._appendChild.apply(this,arguments); Preload.appendChild(script); }
很简单易懂的代码, 核心思路就是接管head的appendChild方法。然后在配置中找到最大的几个路由依赖文件,提前加载,
Preload.url("./static/js/11.c98ac5bee35902600d66.js");
在加载中采用fetch的方式将代码以字符串的形式保存下来,当检测到文件被script加载的时候 用eval来执行模拟标签自动加载, 触发script的load事件维持原来的流程;
是不是很简单,一旦想清楚整个结构,就可以在不改变原来流程的前提下进行我们想要的优化了!~~~