关于vue.js:我是如何把vue项目启动时间从70s优化到7秒的

43次阅读

共计 4045 个字符,预计需要花费 11 分钟才能阅读完成。

可怕的启动工夫
公司的产品是一个比拟大的后盾管理系统,而且应用的是 webpack3 的 vue 模板我的项目,单次我的项目启动工夫达到了 70s 左右

启动个我的项目都够吃一碗豆腐脑了,可是没有豆腐脑怎么办,那就优化启动工夫吧!

思考到降级 webpack 版本的危险还是比拟大的,出了一点问题都得找我,想想还是先别冒险,稳当为主,所以我抉择了通过插件来优化构建工夫。

通过查阅材料,晋升 webpack 的构建工夫有以下几个方向:

多过程解决文件,同一时间解决多个文件
预编译资源模块,比方把长时间不变的库提取进去做预编译,构建的时候间接取编译后果就好
缓存,未修改的模块间接拿到处理结果,不用编译
缩小构建搜寻和解决的文件数量
针对以上几种优化方向,给出以下几种优化计划。

多过程构建
happypack
happypack 的作用就是将文件解析工作分解成多个子过程并发执行。

子过程解决完工作后再将后果发送给主过程。所以能够大大晋升 Webpack 的我的项目构件速度。

查看 happypack 的 github,发现作者曾经不再保护该插件,并且作者举荐应用 webpack 官网的多过程插件 thread-loader,所以我放弃了 happypacy,抉择了 thread-loader。

thread-loader
thread-loader 是官网保护的多过程 loader,性能相似于 happypack,也是通过开启子工作来并行解析文件,从而进步构建速度。

把这个 loader 放在其余 loader 后面。不过该 loader 是有限度的。示例:

loader 无奈收回文件。
loader 不能应用自定义加载器 API。
loader 无法访问网页包选项。
每个 worker 都是一个独自的 node.js 过程,其开销约为 600 毫秒。还有过程间通信的开销。在小型我的项目中应用 thread-loader 可能并不能优化我的项目的构建速度,反而会拖慢构建速度,所以应用该 loader 时须要明确我的项目构建形成中真正耗时的过程。

我的我的项目中我次要是用该 loader 用来解析 vue 和 js 文件,作用于 vue-loader 和 babel-loader,如下代码:

const threadLoader = {
loader: ‘thread-loader’,
options: {

workers: require('os').cpus().length - 1,

}
}

module.exports = {
module:{
rules: [

  {
    test: /\.vue$/,
    use: [
      threadLoader, // vue-loader 前应用该 loader
      {
        loader: 'vue-loader',
        options: vueLoaderConfig
      }
    ],
  },
  {
    test: /\.js$/,
    use: [
      threadLoader, // babel-loader 前应用该 loader
      {
        loader: 'babel-loader',
        options: {cacheDirectory: true}
      }
    ]
  }
]

}
}

复制代码
配置了 thread-loader 后,从新构建试试,如下图所示,大略缩短了 10 秒的构建工夫,还不错。

利用缓存晋升二次构建的速度
尽管应用了多过程构建我的项目使构建工夫缩短了 10 秒,然而一分钟的构建工夫仍然让人无奈承受,这种挤牙膏似的优化形式多少让人有点不爽,有没有比拟爽的办法来进一步缩短构建工夫呢?

答案是有的,应用缓存。

缓存,不难理解就是第一次构建的时候将构建的后果缓存起来,当第二构建时,查看对应缓存是否批改,如果没有批改,间接应用缓存,由此,咱们能够设想,当我的项目的变动不大时,大部分缓存都是可复用的,拿构建的速度岂不是会有质的飞跃。

cache-loader
说到缓存,当然百度一查,最先呈现的就是 cache-loader,github 搜寻下官网文档,失去如下后果:

该 loader 会缓存其余 loader 的处理结果,把该 loader 放到其余 loader 的后面,同时该 loader 保留和读取缓存文件也会有开销,所以倡议在开销较大的 loader 前应用该 loader。

文档很简略,思考到我的项目中的 vue-loader,babel-loader,css-loader 会有比拟大的开销,所以为这些 loader 加上缓存,那么接下来就把 cache-loader 加到我的项目中吧:

const cacheLoader = {
loader: ‘cache-loader’
}

const threadLoader = {
loader: ‘thread-loader’,
options: {

workers: require('os').cpus().length - 1,

}
}

module.exports = {
module:{
rules: [

  {
    test: /\.vue$/,
    use: [
      cacheLoader,
      threadLoader, // vue-loader 前应用该 loader
      {
        loader: 'vue-loader',
        options: vueLoaderConfig
      }
    ],
  },
  {
    test: /\.js$/,
    use: [
      cacheLoader,
      threadLoader, // babel-loader 前应用该 loader
      {
        loader: 'babel-loader',
        options: {cacheDirectory: true}
      }
    ]
  }
]

}
}

复制代码
在 util.js 文件中,该文件次要是生成 css 相干的 webpack 配置,找到 generateLoaders 函数,批改如下:

const cacheLoader = {

loader: 'cache-loader'

}

function generateLoaders(loader, loaderOptions) {
// 在 css-loader 前减少 cache-loader

const loaders = options.usePostCSS ? [cacheLoader, cssLoader, postcssLoader] : [cacheLoader, cssLoader]

if (loader) {
  loaders.push({
    loader: loader + '-loader',
    options: Object.assign({}, loaderOptions, {sourceMap: options.sourceMap})
  })
}

// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
  return ExtractTextPlugin.extract({
    use: loaders,
    fallback: 'vue-style-loader',
    // 增加这句配置解决 element-ui 的图标门路问题
    publicPath: '../../'
  })
} else {return ['vue-style-loader'].concat(loaders)
}

}
复制代码
如上配置实现后,再次启动我的项目,能够发现,当初的启动工夫没什么变动,而后咱们二次启动我的项目,能够发现当初的启动工夫来到了 30s 左右,后面咱们曾经说过了,cache-loader 缓存只有在二次启动的时候才会失效。

尽管我的项目启动工夫优化了一半还多,然而咱们的欲望是无限大的,30 秒的工夫离咱们的预期还是有点差距的,持续优化!

hard-source-webpack-plugin
HardSourceWebpackPlugin 是一个 webpack 插件,为模块提供两头缓存步骤。为了查看后果,您须要应用此插件运行 webpack 两次:第一次构建将破费失常的工夫。第二次建设将大大放慢。

话不多说,间接配置到我的项目中:

const HardSourceWebpackPlugin = require(‘hard-source-webpack-plugin’);
module.exports = {

//...
plugins: [new HardSourceWebpackPlugin()
]

}
复制代码


二次构建时,咱们会发现构建工夫来到了个位数,只有短短的 7 秒钟。

在二次构建中,我发现了一个景象,构建的进度会从 10% 一下跳到 80%,甚至是一瞬间就实现了两头构建过程。这正验证了该插件为模块提供两头缓存的说法。

为模块提供两头缓存,我的了解是 cache-loader 缓存的是对应 loader 的处理结果,而这个插件甚至能够缓存整个我的项目全副的处理结果,间接援用最终输入的缓存文件,从而大大提高构建速度。

其余优化办法
babel-loader 开启缓存
babel-loader 自带缓存性能,开启 cacheDirectory 配置项即可,官网的说法是,开启缓存会进步大概两倍的转换工夫。

module.exports = {
module: {
rules: [

  {
    test: /\.js$/,
    use: [
      ...
      {
        loader: 'babel-loader',
        options: {cacheDirectory: true // 开启缓存}
      }
    ]
  }
]

}
}

复制代码
uglifyjs-webpack-plugin 开启多过程压缩
uglifyjs-webpack-plugin 或是其余的代码压缩工具都提供了多过程压缩代码的性能,开启可减速代码压缩。

总结
至此,咱们实现了我的项目构建工夫从 70s 到 7s 的优化过程,文中次要应用:

工具 作用 优化成果
thread-loader 多过程解析文件 70s -> 60s
cache-loader 缓存局部高开销的 loader 60s -> 30s
hard-source-webpack-plugin 缓存模块两头过程 30s -> 7s
最初
如果你感觉此文对你有一丁点帮忙,点个赞。或者能够退出我的开发交换群:1025263163 互相学习,咱们会有业余的技术答疑解惑

如果你感觉这篇文章对你有点用的话,麻烦请给咱们的开源我的项目点点 star: https://gitee.com/ZhongBangKe… 不胜感激!

正文完
 0