优化Webpack应用程序的4个技巧

大家好!

在使用webpack的过程中,我积累了一些有趣的技巧,它们将帮助您准备完美优化的应用程序。 让我们开始吧!

前端猫看着webpack并说“ Belissimo”



1.使用快速异步而不是再生器运行时


通常,开发人员使用@ babel / preset-env将所有现代语法转换为ES5。

使用此预设,异步功能的转换管道如下所示:
源异步函数-> 生成器 ->使用regenerator-runtime的 函数

例子
1.原始异步功能

const test = async () => { await fetch('/test-api/', { method: 'GET' }); } 

2.发电机

 function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } const test = (() => { var _ref = _asyncToGenerator(function* () { yield fetch('/test-api/', { method: 'GET' }); }); return function test() { return _ref.apply(this, arguments); }; })(); 

3.使用再生器运行时的功能

 'use strict'; function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } var test = function () { var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() { return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return fetch('/test-api/', { method: 'GET' }); case 2: case 'end': return _context.stop(); } } }, _callee, undefined); })); return function test() { return _ref.apply(this, arguments); }; }(); 


使用快速异步,管道可以简化为:
源异步功能->使用约定的功能

例子
1.原始异步功能

 const test = async () => { await fetch('/test-api/', { method: 'GET' }); } 

2.履行承诺

 var test = function test() { return new Promise(function ($return, $error) { return Promise.resolve(fetch('/test-api/', { method: 'GET' })).then(function ($await_1) { try { return $return(); } catch ($boundEx) { return $error($boundEx); } }, $error); }); }; 


因此,现在我们在客户端上没有regenerator-runtime,也没有来自转换的额外包装器。

要将快速异步引入您的项目,您必须:

1.安装

 npm i fast-async 

2.更新babel的配置

 // .babelrc.js module.exports = { "presets": [ ["@babel/preset-env", { /* ... */ "exclude": ["transform-async-to-generator", "transform-regenerator"] }] ], /* ... */ "plugins": [ ["module:fast-async", { "spec": true }], /* ... */ ] } 

对我而言,此优化将js文件的大小减少了3.2%。 一件小事,但很好:)

2.使用宽松的转换


如果没有特殊配置, @ babel / preset-env会尝试生成尽可能接近规范的代码。

但是,很可能您的代码并没有那么糟糕,并且没有使用ES6 +规范的所有可能的极端情况。 然后,可以通过对预置环境启用宽松的转换来消除所有额外的开销:

 // .babelrc.js module.exports = { "presets": [ ["@babel/preset-env", { /* ... */ "loose": true, }] ], /* ... */ } 

有关如何工作的示例,请参见此处

在我的项目中,这使捆绑包大小减少了3.8%。

3.用手配置js和CSS最小化


缩小器的默认设置仅包含程序员无法中断的那些转换。 但是我们喜欢引起问题吗?
尝试阅读js缩小器和CSS缩小器的设置(我使用cssnano )。

研究了基座之后,我进行了以下配置:

 // webpack.config.js const webpackConfig = { /* ... */ optimization: { minimizer: [ new UglifyJsPlugin({ uglifyOptions: { compress: { unsafe: true, inline: true, passes: 2, keep_fargs: false, }, output: { beautify: false, }, mangle: true, }, }), new OptimizeCSSPlugin({ cssProcessorOptions: { "preset": "advanced", "safe": true, "map": { "inline": false }, }, }), ], }, }; /* ... */ 

结果,js文件的大小减少了1.5%,而css-减少了2%。

也许你可以做得更好?

UPD 01/11/2019:不推荐使用UglifyJsPlugin ,webpack现在使用TerserWebpackPlugin 。 使用它。

4.使用null-loader删除不必要的依赖项


gsap开发人员拥有一个很棒的库来创建动画。 但是由于它起源于2008年,因此仍然保留了某些功能。

这个 。 多亏了它,TweenMax提取了5个插件和easyPack,它们是完全可选的。

我注意到我内部有三个多余的插件,并使用null-loader删除了它们:

 // webpack.config.js const ignoredGSAPFiles = ['BezierPlugin', 'DirectionalRotationPlugin', 'RoundPropsPlugin']; const webpackConfig = { /* ... */ module: { rules: [ /* ... */ { test: /\.js$/, include: ignoredGSAPFiles.map(fileName => resolve('node_modules/gsap/' + fileName)), loader: 'null-loader', }, ] }, }; /* ... */ 

106 kb变成86。是的!

Null-loader仍可用于删除图书馆作者为我们精心种植的不必要的polyfill。

Source: https://habr.com/ru/post/zh-CN425215/


All Articles