4 نصائح لتحسين تطبيق Webpack الخاص بك

مرحبا بالجميع!

خلال عملي مع حزمة الويب ، جمعت بعض النصائح الشيقة التي ستساعدك في إعداد تطبيق محسن تمامًا. دعنا نبدأ!

قط أمامي ينظر إلى حقيبة الويب ويقول "Belissimo"



1. استخدم المزامنة السريعة بدلاً من وقت تشغيل المُجدد


عادة ، يستخدم المطورون @ babel / preset-env لتحويل جميع القواعد الحديثة إلى ES5.

مع هذا الإعداد المسبق ، يبدو خط أنابيب تحويلات الدالات غير المتزامنة كما يلي:
الوظيفة غير المتزامنة المصدر -> المولد -> الوظيفة باستخدام وقت تشغيل المُولد

مثال
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); }); }; 


ونتيجة لذلك ، ليس لدينا الآن وقت تشغيل المُجدد على العميل وأغلفة إضافية من التحويلات.

لجلب التزامن السريع إلى مشروعك ، يجب عليك:

1. تثبيته

 npm i fast-async 

2. تحديث التكوين بابل

 // .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. تكوين شبيبة شبيبة والتصغير 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. استخدام محمل فارغ لإزالة التبعيات غير الضرورية


لدى مطوري gsap مكتبة رائعة لإنشاء الرسوم المتحركة. ولكن بسبب حقيقة أنها نشأت من عام 2008 ، بقيت بعض الميزات فيه.

وهي هذه . بفضل ذلك ، يقوم TweenMax بسحب 5 مكونات إضافية و easyPack ، وهي اختيارية تمامًا.

لاحظت ثلاثة مكونات إضافية زائدة في داخلي وقمت بقصها باستخدام محمل فارغ :

 // 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 كيلو بايت تتحول إلى 86. نعم!

لا يزال من الممكن استخدام أداة تحميل Null لإزالة الرقائق غير الضرورية التي زرعها مؤلفو المكتبة بعناية لنا.

Source: https://habr.com/ru/post/ar425215/


All Articles