اهتزاز شجرة جافا سكريبت ، مثل المحترفين

هذه ترجمة لمقال عن تحسين وتقليل حجم حزمة التطبيق. إنه أمر جيد لأن أفضل الممارسات موصوفة هنا ، ونصائح يجب عليك اتباعها لجعل عمل trishhing وإلقاء التعليمات البرمجية غير المستخدمة من التجميع. سيكون مفيدًا للكثيرين ، لأن الجميع يستخدم الآن أنظمة التجميع التي يوجد بها trishashing خارج الصندوق. ولكن لكي يعمل بشكل صحيح ، يجب عليك الالتزام بالمبادئ الموضحة أدناه.

صورة

يصبح Trichashing التقنية الرئيسية عندما تحتاج إلى تقليل حجم الحزمة وتحسين أداء التطبيق على JS.

كيف يعمل trichashing:

  1. تصرح الواردات والصادرات في كل وحدة.
  2. يقوم المُجمع (Webpack أو Rollup أو غيره) بتحليل شجرة التبعية أثناء التجميع.
  3. الكود غير المستخدم مستبعد من الباقة النهائية.

صورة
يصدر ملف الأداة المساعدة وظيفتين ،

صورة
ولكن يتم استخدام InitizeName فقط ، ويمكن حذف formatName.

لسوء الحظ ، من أجل التشغيل الصحيح للتريشينج ، فإن إعداد أحد المجمعات غير كافٍ. لتحقيق نتيجة أفضل ، من الضروري مراعاة العديد من التفاصيل ، بالإضافة إلى التأكد من عدم تخطي الوحدات أثناء التحسين.

من أين نبدأ؟


هناك عدد كبير من المبادئ التوجيهية لإعداد trishaking. من الأفضل بدء الغوص في الموضوع باستخدام وثائق Webpack الرسمية .

من الجدير بالذكر أنني قمت منذ بضع سنوات بإنشاء لوحة مرجعية مع تجميع تم تكوينه بالفعل وتريشاشينج. لذلك إذا كنت بحاجة إلى نقطة بداية لمشروع ، يمكن أن يكون المستودع الخاص بي مثالًا جيدًا على krakenjs / grumbler .

تتناول هذه المقالة العمل مع Webpack و Babel و Terser. ومع ذلك ، ستعمل معظم المبادئ المقدمة سواء كنت تستخدم Webpack أو التراكمي أو أي شيء آخر.

استخدم صيغة ES6 للاستيراد والتصدير


يعد استخدام واردات وصادرات ES6 الخطوة الأولى والأكثر أهمية في العمل بثلاث طرق.

معظم التطبيقات الأخرى لنمط "الوحدة النمطية" ، بما في ذلك Commonjs و request.js ، غير حتمية أثناء عملية البناء. لا تسمح هذه الميزة لهواة الجمع مثل Webpack بتحديد ما يتم استيراده بالضبط وما الذي تم تصديره ، ونتيجة لذلك ، ما هو الرمز الذي يمكن حذفه بأمان.

صورة
الخيارات الممكنة عند استخدام Commonjs.

عند استخدام وحدات ES6 ، تكون خيارات الاستيراد والتصدير محدودة أكثر:

  • يمكنك الاستيراد والتصدير فقط على مستوى الوحدة النمطية ، وليس داخل الوظيفة ؛
  • يمكن أن يكون اسم الوحدة فقط سلسلة ثابتة ، وليس متغيرًا ؛
  • يجب تصدير كل شيء تستورده إلى مكان ما.

صورة
تتميز وحدات ES6 بدلالات أبسط وقواعد استخدام.

تسمح القواعد المبسطة للمُجمِّعين بفهم ما تم استيراده وتصديره بالضبط ، ونتيجة لذلك ، حدد الرمز الذي لم يتم استخدامه على الإطلاق.

لا تسمح لبابل بنقل الواردات والصادرات


المشكلة الأولى التي قد تواجهها عند استخدام Babel لترجمة التعليمات البرمجية هي التحويل الافتراضي لوحدات ES6 إلى Commonjs. هذا يمنع المجمع من تحسين الكود ورمي الكثير.

لحسن الحظ ، في تهيئة Babel ، هناك طريقة سهلة لتعطيل transpilation الوحدة النمطية .

بعد القيام بذلك ، سيتمكن المحصل من نقل الواردات والصادرات.

اجعل صادراتك ذرية


عادة ما يترك Webpack الصادرات سليمة في الحالات التالية:

  • ;
  • ;
  • .

سيتم تضمين هذه الصادرات بالكامل في الحزمة ، أو سيتم إزالتها تمامًا. لذا ، في النهاية ، قد ينتهي بك الأمر مع حزمة تحتوي على رمز لن يتم استخدامه أبدًا.

صورة
سيتم تضمين كلتا الوظيفتين في الحزمة ، حتى إذا تم استخدام وظيفة واحدة فقط.

صورة
وهنا ستتم إضافة الفصل بالكامل إلى الجمعية.

حاول إبقاء صادراتك صغيرة وبسيطة قدر الإمكان.

صورة
فقط الوظيفة التي سيتم استخدامها ستدخل في الحزمة النهائية.

يتيح تنفيذ هذه النصيحة للمجمع إمكانية التخلص من المزيد من التعليمات البرمجية نظرًا لأنه يمكنك الآن أثناء عملية التجميع تتبع الوظيفة التي تم استيرادها واستخدامها ، وأيها لم يتم.

يساعد هذا التلميح أيضًا على كتابة التعليمات البرمجية بأسلوب أكثر وظيفية وقابل لإعادة الاستخدام ، وتجنب استخدام الفصول التي لا يوجد فيها ما يبررها.

إذا كنت مهتمًا بالبرمجة الوظيفية ، فراجع هذه المقالة .

تجنب الآثار الجانبية على مستوى الوحدة


عند كتابة الوحدات النمطية ، يفتقد العديد من الأشخاص عاملاً مهمًا ولكنه خبيث جدًا - تأثير الآثار الجانبية.

صورة
لا يفهم Webpack ما يفعله window.memoize ، وبالتالي لا يمكنه إلقاء هذه الوظيفة.

لاحظ أنه window.memoizeسيتم استدعاء المثال أعلاه في وقت استيراد الوحدة النمطية.

كما يراه Webpack:

  • حسنًا ، يتم إنشاء وظيفة إضافة خالصة وتصديرها هنا - ربما يمكنني إزالتها إذا لم يتم استخدامها لاحقًا ؛
  • ثم يتم استدعاء window.memoize ، ويتم تمرير الإضافة ؛
  • لا أعرف ما تفعله window.memoize، لكنني أعلم أنها ستدعو على الأرجح إضافة وإنشاء تأثير جانبي.
  • من أجل الأمان ، سأترك وظيفة الإضافة في الحزمة ، حتى لو لم يكن أحد يستخدمها .

في الواقع ، نحن على يقين من أنها window.memoizeوظيفة خالصة لا تخلق أي آثار جانبية وتضيف المكالمات إذا استخدمها شخص ما memoizedAdd.

لكن Webpack لا يعرف ذلك ، ومن أجل السلام ، يضيف وظيفة الإضافة إلى الحزمة النهائية.

لنكون صادقين: أحدث إصدارات Webpack و Terser جيدة بشكل غير عادي في اكتشاف الآثار الجانبية.

صورة
نعطي Webpack مزيدًا من المعلومات ونحصل على حزمة مُحسّنة.

الآن لدى جامع المعلومات الكافية للتحليل:

  • تسمى هنا memoizeعلى مستوى الوحدة ، يمكن أن يكون هذا محفوفًا بالمشاكل ؛
  • لكن الدالة memoizeجاءت من استيراد ES6 ، تحتاج إلى إلقاء نظرة على الوظيفة في util.js؛
  • في الواقع ، يبدو التذكير وظيفة نقية ، ولا توجد آثار جانبية ؛
  • إذا لم يستخدم أحد الوظيفة add، يمكننا استبعادها بأمان من الحزمة النهائية.

عندما لا تتلقى Webpack معلومات كافية لاتخاذ قرار ، فإنها ستأخذ المسار الآمن وتترك الوظيفة.

استخدم الأدوات لتحديد المشاكل المحتملة


لقد وجدت أداتين لتحديد المشاكل.

الأداة الأولى هي تسلسل الوحدة النمطية ، وهو مكون إضافي لـ Webpack ، والذي يسمح لك بتحقيق زيادة كبيرة في الأداء. لديها خيار التصحيح. من الجدير بالذكر أن العوامل التي تمنع التسلسل والثلاثي هي نفسها: على سبيل المثال ، الآثار الجانبية على مستوى الوحدة. تعامل مع تحذيرات المكوّن الإضافي على محمل الجد ، لأن أي مشكلة من المحتمل أن تزيد من حجم الحزمة.

والثاني هو البرنامج المساعد لللينت https://www.npmjs.com/package/eslint-plugin-tree-shaking . لم أقوم بدمجها في لوح الغلاية الخاص بي حتى الآن ، لأنها لم تدعم التدفق عندما قمت بتجربتها. ومع ذلك ، فقد حدد جيدًا المشكلات المتعلقة بالثلاثي.

كن حذرا مع المكتبات


حاول استخدام المكتبات المُحسّنة للتدرج. إذا قمت باستيراد مجموعة كبيرة من التعليمات البرمجية المصغرة ، على سبيل المثال jquery.min.js، هناك احتمال أن هذه الوحدة لن يتم تحسينها. من الأفضل البحث عن وحدة يمكن استيراد الوظائف الذرية منها ، وللتجميع والتصغير ، استخدم Webpack أو Rollup.

في بعض الأحيان يمكنك استيراد مكتبة كاملة. على سبيل المثال ، عند استخدام بناء إنتاج React ، لا تحتاج إلى التخلص من أي شيء - كل شيء موجود فيه محسن بالفعل.

إذا كنت تستخدم مكتبة تقوم بتصدير الوظائف الفردية ، على سبيل المثال ، Lodash ، فحاول استيراد الوظائف الضرورية فقط وتأكد من استبعاد الوظائف الأخرى من الحزمة النهائية.

استخدم علامات البناء


يحتوي البرنامج الإضافي DefinePlugin لـ Webpack على ميزة رائعة ، ولكن ليس الأكثر شهرة - القدرة على التأثير على الرمز الذي سيتم استبعاده أثناء عملية البناء.

صورة

إذا قمنا بتمريرها __PRODUCTION__: trueإلى المكوّن الإضافي ، فلن يتم فقط استدعاء الوظيفة validateOptions، ولكن أيضًا سيتم استبعاد تعريفها من الحزمة النهائية .
هذا يبسط إنشاء حزم مختلفة للتطوير والإنتاج ، ويساعد أيضًا على ضمان عدم دخول التعليمات البرمجية المخصصة لتصحيح الأخطاء إلى الإنتاج.

ابدأ التجميع


من الصعب جدًا تحديد كيفية تحسين Webpack لوحدة معينة.

لذا قم بتشغيل البنية ، وتحقق من الحزمة النهائية وشاهد ما سيحدث. ألق نظرة على كود JavaScript وتأكد من عدم ترك أي شيء فيه كان يجب التخلص منه بواسطة trichashing.

شيء آخر؟


إذا كنت تعرف نصائح مفيدة أخرى ، فيرجى الكتابة عنها في التعليقات.

All Articles