FrankKai / FrankKai.github.io

FE blog
https://frankkai.github.io/
362 stars 39 forks source link

前端webpack构建优化 #221

Open FrankKai opened 4 years ago

FrankKai commented 4 years ago

从0到1负责手上项目一年多了,webpack虽然是老生常谈的话题,但只有出现问题时,才会去思考怎么去优化。由于项目里引入了越来越多的依赖,所以本地开发编译过程越来越慢,因此才有了这一次的webpack优化。顺便对一些生产环境的静态资源也做了一些优化。

一.HappyPack多线程编译

Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz 8核16线程 

webpack 3.12.0 ThreadPool.size:16

本地构建速度:

51281ms(未引入happypack)

43750ms(引入happypack eslint-loader)

35862ms(引入happypack eslint-loader, vue-loader)

35476ms(引入happypack eslint-loader, vue-loader, babel-loader)

打包dist速度:

58192ms(未引入happypack)

49745ms(引入happypack eslint-loader)

46505ms(引入happypack eslint-loader, vue-loader)

43358ms(引入happypack eslint-loader, vue-loader, babel-loader)

从上面的实验数据可以得出:无论是本地构建还是打包dist,eslint-loader,vue-loader,babel-loader的happypack对编辑速度都是有提升的。

二.TinyPng优化静态图片资源

https://tinypng.com/

三.优化loader配置

cacheDirectory开启缓存,include去除无需处理文件。

// 配置前

{

    test: /\.js$/,

    loader: ‘babel-loader',

    include: [resolve('src'), resolve(’test'), resolve('node_modules/webpack-dev-server/client')],

},
// 配置后

{

    test: /\.js$/,

    loader: ‘babel-loader?cacheDirectory=true’,// 开启缓存加速

    include: [resolve('src'), resolve('node_modules/webpack-dev-server/client')], // 并无单测,去除test目录

},

四.优化包查找路径

使用绝对路径,只在给定目录中搜索,省去了查找依赖的时间损耗

因为默认设置是[node modules]。 从当前目录找node_modules,若没有,从../node_modules找,若是再没有,继续找../node_modules,直到找到为止。

我手上的项目是直接存在src,build目录同级的node_modules下的,所以可以按照下面这样修改。

// 配置前

resolve: {

    modules: ["node_modules”],

}
// 配置后

resolve: {

    modules: [path.join(__dirname, '..', "node_modules”)] // 这个路径根据构建文件所在位置去调整,此处是build/webpack.base.conf.js,node_modules目录与src目录同级

}

五.消除无更新的图片资源计算

由于项目中的一些图片资源是一直不变的,因此没有必要每次都通过url-loader或file-loader加载打包,消除转换base64url或者:hash:,所以图片资源尽可能使用绝对路径引入/static下的文件,而不是通过import去引入。

出于优化成本考虑,我这次仅仅将超过limit的图片进行转移。

转移前:vue.40add6f.png

转移后:vue.png

例如预发环境,若是不同环境的BASE_URL不一样,可以通过DefinePlugin和<=%BASE_URL%=>传入。

config.js

{

    dev:{

        BASE_URL:’/’,

    },

    build:{

        BASE_URL:’/foo/bar/’,

    }

}

webpack.dev.conf.js

plugins:{

    new webpack.DefinePlugin({

        BASE_URL:JSON.stringify(config.dev.BASE_URL),

    }),

},

webpack.prod.conf.js

plugins:{

    new webpack.DefinePlugin({

        BASE_URL:JSON.stringify(config.build.BASE_URL),

    }),

},

<link rel="icon" href=“<%=BASE_URL=%>static/favicon.ico">

favicon.ico的路径地址如下:

在开发环境是:localhost:9090/static/favicon.ico

在生产环境是:https://www.jsnb.com/foo/bar/static/favicon.ico

在单文件组件内该如何操作呢?

很简单,只要与src同级创建一个baseUrl.js,然后在文件中绑定到组件data函数上即可。

// eslint-disable-next-line no-undef

export default BASE_URL;

<img :src=“Logo" />

const Logo = `${baseUrl}static/logo.png`;

data(){

    return {

        Logo,

    }

}

优点:

1.迁移assets下大文件到static,减少计算hash时间,通过/static引入。

2.DefinePlugin,根据环境切换static引入路径统一引入。(若通过webpack的resolve.alias统一引入,还是会被url-loader加载,还是会去做计算)。

缺点:

1.构建提升速度收效甚微

2.有缓存文件不能用此方法,会有缓存

3.图片文件存放分散,不便于管理

建议:在没有遇到由于url-loader,file-loader加载图片,视频等本地资源慢的情况下,可以一直使用assets的方式,不用折腾。

六.提升开发环境rebuild速度

source map众所周知是为了webpack debug的一个配置,有7个配置。可以参考官方文档https://webpack.js.org/configuration/devtool/和我之前做的一个小实验https://github.com/FrankKai/FrankKai.github.io/issues/58做对比。

开发环境:

devtool:’source-map’->devtool: ‘eval-source-map’

rebuild速度从--slow提升到了+pretty fast。

提速原因是:SourceMap转换为DataUrl加载到eval()中。重新构建时速度更快,

官方文档介绍如下:

eval-source-map - Each module is executed with eval() and a SourceMap is added as a DataUrl to the eval(). Initially it is slow, but it provides fast rebuild speed and yields real files. Line numbers are correctly mapped since it gets mapped to the original code. It yields the best quality SourceMaps for development.

斯世浊清,全赖吾辈激扬!

期待和大家交流,共同进步,欢迎大家加入我创建的与前端开发密切相关的技术讨论小组:

努力成为优秀前端工程师!