2.大型库是否可以通过定制功能的方式减少体积。明显的一个例子是 echart, echart完全版的依赖压缩后也有几百k 之多,这显示是难以接受的。现实项目中,我们可能只需要少量或者部分的echart 功能,这时我们可以通过制定图表的形式,下载图表用到的功能,达到体积最优化。
3.某些不可优化的大型库是否可以通过外部引用的方式减少文件体积。例如像bootstrap,vue这类无法优化的第三方库,通过免费开源的cdn服务不但可以减少文件体积,还可以提高网站的加载速度,也是个优化性能的方法
3.7 按需加载前面提到依赖分析的方向中,如果大型库不可或缺,而且使用率也不算低的时候,我们可以通过按需加载的形式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。
webpack中利用require.ensure()实现按需加载,在不使用按需加载的情况下,首屏加载时会把所有的脚本同时加载出来,这往往会拖累首屏显示时间,带来不好的用户体验。例子来说。当项目需要使用大型的图表类库,而首页并不需要时,按需加载往往比同时加载在用户体验上好好得多。
当不需要按需加载的时候,我们的代码可能是这样的:
import test from './components/test.vue' import test2 from './components/test2.vue'开启按需加载时,我们的代码修改为:
const test = r => require.ensure([], () => r(require('./components/test.vue')), 'chunk1') const test2 = r => require.ensure([], () => r(require('./components/test2.vue')), 'chunk2')webpack 配置修改为
output: { ··· chunkFilename: '[name].[hash].js' }这时编译出来的文件会从原来的一个,变成了多个小文件。每个路由加载时会去加载不同的资源。特别在首屏的资源加载上进一步优化了应用的体验。
尽管如此,实际中我们需要根据项目的需求来衡量按需加载的可用性,尽管在首屏优化上取得较大的提升,但按需加载毕竟会将大的文件拆分成多个小文件,增加了http 的请求数。这又违背了性能优化的基础。所以实际中需要取舍,更需要权衡。
3.8 删除冗余代码代码体积优化到这一步,基本可以优化的地方已经优化完毕了。接下来可以抓住一些细节做更细的优化。比如可以删除项目中上下文都未被引用的代码。这就是所谓的 Tree shaking 优化。webpack 4.0中,mode 为production 默认启动这一优化。但是,如果在项目中使用到babel的 话,需要把babel解析语法的功能关掉。只需要
// .babelrc { "presets": [["env", { "modules": false }]] } 四,构建速度优化说完如何减少项目构建后的大小后,接下来简单的谈一下如何提高构建的速度。实际上webpack的 构建速度,只需要简单的修改配置便能大幅提高速度。常见的设置如下。
4.1 babel-loader构建时间过长 4.1.1 限定加载器作用范围由于babel-loader需要将语法进行转换,所耗费的时间较长,所以第一步需要限定babel-loader 作用的范围,让babel-loader 的搜索和转换准确的定位到指定模块。大幅提高构建速度。
例如:
正因为babel-loader在解析转换上耗时太长,所以我们希望能缓存每次执行的结果。webpack的loader中刚好有 cacheDirectory 的选项,默认为false 开启后将使用缓存的执行结果,打包速度明显提升。
// webpack.base.js module.exports = { module: { rules: [ { test: /\.js$/, include: [resolve('src')], use: { loader: 'babel-loader?cacheDirectory', }, },] } } 4.2 resolve 解析优化webpack 的resolve 做相关的配置后,也可以让项目的构建速度加快。具体看下文的配置:
当项目中出现 import 'react' 既不是绝对路径也不是相对路径时,指定好搜索的路径,可以不用过多的查询
尽可能少的使用 resolve.alias 来设置路径别名,因为会影响到tree shaking 的优化
后缀自动补全尽可能的少。减少路径查询的工作
当使用的第三方库过大,并且不包含import require define 的调用。可以使用noParse让库不被loaders 解析
// webpack.base.js module.exports = { resolve: { modules: [ path.resolve(__dirname, 'node_modules'), ], extensions: [".js"], // 避免新增默认文件,编码时使用详细的文件路径,代码会更容易解读,也有益于提高构建速度 mainFiles: ['index'], }, module: { noParse: function(content){ return /jquery/.test(content) } } } 五,结语