Less.js: يستخدم الإصدار 3.10.x ذاكرة أكبر بشكل ملحوظ وهو أبطأ بشكل ملحوظ من 3.9.0

تم إنشاؤها على ١٢ سبتمبر ٢٠١٩  ·  95تعليقات  ·  مصدر: less/less.js

بدأت تصميماتنا مؤخرًا بالفشل لأننا قمنا بتشغيل حوالي 80 إصدارًا أقل بالتوازي أثناء عملية بناء مشروعنا ، ويستخدم الإصدار الجديد من Less.js قدرًا كبيرًا من الذاكرة بحيث يتعطل Node. قمنا بتتبع العطل إلى الترقية من Less.js من 3.9.0 إلى 3.10.3.

لقد غيرت البرنامج النصي Less الخاص بنا لتجميع الملفات بالتسلسل (إنشاء ملفين في وقت واحد) وأخذ عينات من استخدام ذاكرة Node أثناء العملية وحصلت على النتائج التالية:

less graph

يبدو أن Less.js يستخدم ذاكرة أكثر بنسبة 130٪ الآن ويستغرق تجميعها وقتًا أطول بنسبة 100٪.

فقط أتساءل عما إذا كنت قد قمت بقياس Less.js وما إذا كنت ترى نتائج مماثلة

التعليق الأكثر فائدة

فريق طيب! سأقوم بنشر الإصدار 3.x ، وفي وقت لاحق ، ربما الأسبوع المقبل ، أنشر 4.0. يجب أن يحتوي كلاهما الآن على إصلاحات الأداء. شكرا لكل من ساعد في التصحيح!

ال 95 كومينتر

هذا غريب. ما هو إصدار Node الخاص بك؟

@ PatSmuk360 هل يمكنك اختبار والحصول على ملف تعريف للذاكرة 3.10.0 ومعرفة ما إذا كان يختلف؟

نقوم بتشغيل أحدث إصدار من 10 (10.16.3).

كومة لقطة من قبل:

image

لقطة الكومة بعد:

image

لقد جربت أيضًا Node 12.10.0 ويبدو أنه أسوأ كثيرًا ، حيث بلغت 587 ميغابايت من استخدام الذاكرة في نقطة واحدة في البناء المتسلسل.

ملف تعريف وحدة المعالجة المركزية قبل:
CPU-20190916T133934.cpuprofile.zip

image

ملف تعريف وحدة المعالجة المركزية بعد:
CPU-20190916T134917.cpuprofile.zip

image

@ PatSmuk360 لذا ، فإن

لكن ... أشك في أن بعض تحويلات Babel لأشياء مثل بناء جملة انتشار الكائن / المصفوفة أقل كفاءة من إصدارات ES5 الأكثر تفصيلاً. لهذا السبب كنت أسأل عما إذا كان بإمكانك اختبار 3.10.0 ، لأنني في الأصل كنت أقوم بتصدير حزمة مُترجمة متوافقة مع Node 6 وما فوق ، لكنها حطمت التكامل مع مكتبة معينة لا يمكنها التعامل مع بناء جملة الفصل. لذلك ذهبت إلى Node 4 بدون تراكيب صفية.

إذا تمكنا من معرفة بالضبط أي تحويل ES5 لا يعمل بشكل جيد ، فيمكننا نظريًا تعيين إعدادات تصدير Babel هذه على تصدير أكثر أداءً.

@ PatSmuk360 بالمناسبة ، ما هي وظيفة split التي تحصل على الكثير من الوقت؟

@ ماثيو دين يبدو أن هذا هو String.prototype.split . إذا فتحت ملف التعريف في أدوات تطوير Chrome الخاصة بك ، يمكنك رؤية جميع البيانات المشفرة بالألوان. أحاول تغيير الملف الشخصي للارتباط بـ https://cdn.jsdelivr.net/npm/[email protected]/dist/less.cjs.js كمصدر له حتى يسهل فحص الاختناقات. هل هناك خريطة مصدر متاحة للملف *.cjs.js إلى *.js الملف؟ و https://cdn.jsdelivr.net/npm/[email protected]/dist/less.min.js.map يبدو ملف لتعيين .min الملف إلى مصدر ES6. ربما يمكننا تغذية خريطة المصدر بأدوات التطوير حتى نتمكن من معرفة أين يسبب النقل الاختناقات.

يبدو أن هذا السطر المحدد https://github.com/less/less.js/blob/cae5021358a5fca932c32ed071f652403d07def8/lib/less/source-map-output.js#L78 يحتوي على قدر كبير من وقت وحدة المعالجة المركزية. لكن بالنظر إلى العملية التي تجريها لا يبدو لي في غير محلها.

ليس لدي خبرة كبيرة في ملفات تعريف الكومة ، ولكن الشيء الذي يميزني هو الزيادة في مبلغ (closures), (system), (array), system / Context . في محاولة لربط ذلك بملف تعريف وحدة المعالجة المركزية ، يبدو أن زيادة هذه الكائنات تؤدي إلى زيادة هائلة في الوقت الذي يقضيه في جمع القمامة.

kevinramharak بشكل عام ، يتضمن تحويل AST مثل Less بعمق _n_ إلى شجرة إخراج متسلسلة ومسطحة مثل CSS الكثير من إنشاء كائن مؤقت. لذا ، ما يمكن أن يحدث هو أنه مع تحويلات معينة ، فإنه يضيف كمية _x_ إضافية من الكائنات. حتى مؤقتًا ، يمكنك الحصول على تأثير أسي حيث تنشئ كل عقدة حتى 2-3x الكائنات ، مضروبة في عدد العقد مضروبًا في عدد المرات التي يتعين عليها فيها تسوية القواعد ... يمكنني رؤيتها وهي تجمع. ربما كنا من السذاجة بشكل عام أن نفكر أساسًا في بناء جملة ES6 على أنه سكر نحوي أساسًا لبناء جملة ES5. (من المحتمل أن يكون مطورو JavaScript مذنبين في هذا الأمر بشكل عام.) في الواقع ، يمكن أن يؤدي تحويل بناء الجملة الأحدث إلى إنشاء أنماط ES5 ليست عالية الأداء. بالنسبة لـ 99٪ من المطورين ، هذه ليست مشكلة كبيرة لأنهم لا يكررون هذا الرمز مئات أو آلاف المرات في الثانية. لكن هذا هو تخميني لما يحدث ، لأنه لم تكن هناك تغييرات رئيسية أخرى.

kevinramharak Re: خطوط المصدر - هذا لأن المحلل اللغوي الأقل الأصلي لا يتتبع خطوط / أعمدة المدخلات ، لذلك عند إضافة تعيين المصدر ، كان من الضروري تقسيم المدخلات إلى سطور لمعرفة كيفية تعيينها إلى الأصل مصدر. لن تكون هذه مشكلة في 4.x + ، ولكن هذا منطقي لماذا ستقضي الكثير من الوقت هناك الآن.

أنا أستخدم less.min.js في متصفح و 3.10.3 أبطأ مرتين من 2.7.3 كنت أستخدمها من قبل. في كل من Chrome و Firefox.

@ PatSmuk360 هل يمكنك التحقق من هذا الفرع؟ https://github.com/matthew-dean/less.js/tree/3.11.0

باختصار ، إن ترجمة Babel إلى ES5 مروع نوعًا ما ، ويستخدم أطنانًا من استدعاءات Object.defineProperty إلى فئات التحويل. لقد قمت بتحويل الترجمة إلى TypeScript ، والذي يحتوي على مخرجات أكثر دقة من النماذج الأولية للوظائف.

كل هذا جيد ورائع ، ولكن بعد القيام بذلك ، لن يتم تشغيل اختبارات متصفح Less لأنه يستخدم PhantomJS القديم جدًا والقديم ، وحتى الآن ، لم يتمكن أي شخص (بما فيهم أنا) من ترحيل الاختبارات بنجاح من PhantomJS على كروم مقطوع الرأس.

لكن ، مشكلة واحدة في كل مرة: إذا كان مصدر التوزيع في هذا الفرع لا يعاني من مشكلات الذاكرة ، فربما يمكننا معالجة الفوضى التي تختبر المتصفح.

لقد تمكنت من ترحيل اختبارات أقل للمتصفح إلى Chromeless Chrome ، ولكن فيما يتعلق بالأداء / الاستقرار ، أحتاج إلى الكثير من التعليقات من المستخدمين قبل أن يصبح الدمج آمنًا ، بسبب تغيير خط النقل بالكامل من Babel إلى TypeScript.

يمكن العثور على الفرع (الفروع) الحالي هنا: https://github.com/less/less.js/pull/3442

لا يزال أبطأ مرتين من 2.7.

alecpl هذه معلومات جيدة ، لكنني أريد حقًا معرفة ما إذا كان 3.11.0 يمثل تحسنًا عن 3.10.

الشيء الغريب في هذا هو أنه ، نظريًا ، تم تحويل رمز Less الأصلي باستخدام Lebab ، والذي يجب أن يكون عكس Babel. مما يعني أن ES5 -> ES6 -> ES5 يجب أن تكون متطابقة تقريبًا ، ولكن من الواضح أن هذا ليس هو الحال. لذلك سأحتاج إلى التحقيق (ما لم يكن لدى أي شخص آخر الوقت ، وهو دعم مرحب به) فقط كيف يختلف كود ES6-> ES5 عن كود ES5 الأصلي.

تضمين التغريدة

لذلك ، أجريت مجموعة متنوعة من الاختبارات ، وقضيت الوقت في إجراء قياس الأداء 3.11.0 مقابل 3.10.3 مقابل 3.9.0 مقابل 2.7.3 في Chromeless Chrome

لم أجد أي دليل على أن المترجم الأقل يكون أبطأ لأي إصدار ، ناهيك عن 2x أبطأ. يمكن أن يكون صحيحًا أن 3.10.0 تحتوي على قدر أكبر من الذاكرة بسبب إعدادات الترشيح ، وربما إذا كان النظام مقيدًا بالمساحة والقيام بمزيد من مقايضات الذاكرة أو المزيد من GC نتيجة لذلك ، فقد يؤدي ذلك إلى تباطؤ؟ لكن لا يمكنني التحقق من ذلك.

يمكنك اختبار نفسك بتشغيل grunt benchmark على الفرع 3.11.0. قد يبلغون عن أرقام مختلفة في سباق فردي ، ولكن إذا ركضت مرات كافية ، يجب أن ترى الأوقات متساوية تقريبًا. لذلك لا أعرف من أين تحصل على بياناتك.

@ PatSmuk360 هل تمكنت من اختبار سعة الذاكرة 3.11.0؟

أنا لا أقوم ببناء الكود الخاص بك بنفسي. أنا لا أستخدم nodejs. أنا فقط آخذ ملف less.min.js من مجلد dist لنسختين مختلفتين ذكرتهما واستخدمهما على صفحتي. ثم في وحدة التحكم أرى التوقيتات مطبوعة برمز أقل. يستخدم الكود الأقل ملفًا متعددًا ويكون ملف الإخراج حوالي 100 كيلو بايت من ملف css المصغر. هذا معيار "الحياة الحقيقية". أنا أتحدث عن كود Roundcube .

يعد Chrome أسرع بكثير من Firefox ، ولكن الفرق بين الإصدارين متشابه.

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

تم وضع علامة على هذه المشكلة تلقائيًا على أنها قديمة نظرًا لعدم وجود نشاط حديث لها. سيتم إغلاقه إذا لم يحدث أي نشاط آخر. شكرا لمساهماتكم.

أردت فقط نشر تحديث سريع: جربت 3.11.1 وكانت بطيئة مثل 3.10.3. سأرى ما إذا كان بإمكاني إعداد معيار تمثيلي لاختبار / تحديد هذا.

لقد قمت بالترقية إلى 3.11.1 ولدي نفس مشكلات استهلاك الذاكرة الآن.
يأخذ مشروع صغير الحجم حوالي 600 ميجابايت من ذاكرة الوصول العشوائي للبناء من خلال حزمة الويب و less-loader .

لقد اتخذت مخططًا زمنيًا لتخصيص الكومة مما أدى إلى ذلك ؛

heap-timeline

شيء ما يتسبب في عمليات تخصيص ضخمة مجنونة يتم الاحتفاظ بها على قيد الحياة بمقدار Ruleset .


[تعديل]
أقوم بالرجوع إلى 3.9 وأخذ مخططًا زمنيًا لتخصيص كومة من ذلك. سأحاول معرفة ما إذا كنت قد لاحظت أي شيء مختلف جذريًا.

@ ماثيو دين
وجدت تلميحًا لك.

في 3.11 أحد الخوادم المدرجة لـ RuleSet هو ImportManager.
في 3.9 _ليس هذا هو الحال _.

إذا تم الاحتفاظ بكل شيء على قيد الحياة من قبل ImportManager و ImportManager هو واحد عبر عملية التجميع بأكملها. نعم؛ من شأنه أن يضخم استخدام الذاكرة بشكل كبير لأنه لا يمكن جمع أي شيء. ولا حتى قواعد وسيط.

rjgotten Hmm ...... إذا كان الكائن يحتوي على إشارة إلى كائن آخر ، فلماذا يمنع ذلك GC؟ أعني ، من الناحية الفنية ، أن جميع الكائنات تحتفظ بمراجع لعقد API العامة عبر سلسلة النموذج الأولي. لن يمنع GC إلا إذا كان العكس صحيحًا ، أي أن بعض الكائنات تحتفظ بالإشارات إلى كل مثيل لمجموعة القواعد.

يبدو أنك قد أسأت الفهم.

عندما يكون "A هو تجنيب B" ، فهذا يعني أن A يحتفظ بالإشارات إلى B والتي تمنع جمع B المهملة. لذلك عندما كتبت ImportManager مدرجًا باعتباره مُثبّتًا لمجموعة القواعد ، فقد عبرت تمامًا عن ما استنتجته أيضًا: يحتفظ ImportManager بمراجع لمثيلات مجموعة القواعد ، مما يمنع GC لمثيلات مجموعة القواعد هذه.

rjgotten أوه ما يفعل؟ أتساءل كيف حدث هذا التغيير هناك. احتمالية قوية أن ألوم ، أو هناك شيء ما حول إعادة بناء ES6 الذي فعل ذلك. لكن نعم ، يمكن أن يفعل ذلك بالتأكيد! شكرا على التحقيق!

حسنًا ، ماذا عن هذه الفكرة المتطرفة.

لقد أنشأت فرعًا مع اختيار الكرز لكل شيء باستثناء تحويل ES6. لم يكن هذا بسيطًا ، وهذا من شأنه أن يؤدي إلى كل هذا العمل ، ولكن إذا كان ملف Babelified / Typescript'd لا يمكن أن يتفوق على JS الأصلي الحالي ، فلا يستحق كل هذا العناء.

ليس لدي أي فكرة عن كيفية التوفيق بين محفوظات git ، ولكن ها هو الفرع -> https://github.com/less/less.js/tree/release_v3.12.0-RC1. يعتبر التحويل النووي أمرًا مهمًا ، لذلك أعتقد أن هذا الفرع سيكون بعض المعايير القوية الحقيقية للمقارنة.

أتساءل كيف حدث هذا التغيير هناك. احتمالية قوية أن ألوم ، أو هناك شيء ما حول إعادة بناء ES6 الذي فعل ذلك. لكن نعم ، يمكن أن يفعل ذلك بالتأكيد! شكرا على التحقيق!

إنه أمر غريب بالتأكيد. من خلال ما تمكنت من فك تشفيره ، يبدو أن ImportManager ينتهي بطريقة ما بتوكيل القواعد من خلال gluecode / polyfill المضافة بواسطة تحويل ES6.

أتساءل ما إذا كان هناك حل هنا يلتقي في منتصف الطريق. أي يحتفظ ببناء ES6 لـ Node.js ولكن له أيضًا هدف مستعرض مُترجم. سيكون التخلص من وضوح الكود الذي يضيفه تحويل ES6 خسارة هائلة. 😢

تضمين التغريدة

سيكون التخلص من وضوح الكود الذي يضيفه تحويل ES6 خسارة هائلة.

قد لا يكون سيئًا كما يبدو لسببين:

  1. لا يزال التكوين التراكمي موجودًا ، ويمكن سحبه من الالتزام إذا أراد شخص ما البحث فيه.
  2. لقد كنت أعمل بنشاط على أقل 4.0 قائم على TypeScript لبعض الوقت. أفضل قضاء وقتي في ذلك بدلاً من تتبع تراجع الأداء هذا. إنه معيد بناء من الأرض ، لذا فهو ليس قريبًا بأي وسيلة ، ولكن بطبيعته ، من غير المحتمل أن يكون هناك طفرات كائن لمرة واحدة تمسك بالمراجع وتمنع GC. والكود أوضح كثيرًا عند اتباعه . لذلك هناك هذا.

يبدو أنه من الصعب إعادة كل شيء إلى ES5 فقط لإصلاح هذه المشكلة ، ولكن هذا أمر مفهوم نظرًا لأن إعادة الكتابة قيد التقدم. ومع ذلك ، يجب أن نفكر في المدة التي يجب أن نتعايش فيها مع هذا القرار. كما ذكر rjgotten ،

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

@ Matthew-dean ، في ملاحظة جانبية ، هل حاولت التجميع مع Babel في وضع فضفاض لمعرفة ما إذا كان ينتج أي رمز أكثر تعقيدًا؟

seanCodes أنا جميعًا لعدم اتخاذ الخيار النووي ، إذا كان لدى شخص ما الوقت الكافي للتحقيق في كيفية / سبب أداء إخراج Rollup / Typescript بشكل أسوأ ، وله تأثيرات ذاكرة إضافية. سيتعلق الأمر جزئيًا بالنظر في الكود الأصلي ، والمقارنة مع المخرجات ، والبحث عن أدلة.

أحد التخمينات لدي هو أن بعض منطق التدمير يحتوي على الكثير من نموذج إنشاء الكائنات.

في الأساس ، يجب أن يتطوع شخص ما لامتلاك هذه المشكلة.

@ Matthew-dean ، في ملاحظة جانبية ، هل حاولت التجميع مع Babel في وضع فضفاض لمعرفة ما إذا كان ينتج أي رمز أكثر تعقيدًا؟

seanCodes يتم تجميع التعليمات البرمجية باستخدام TypeScript وليس Babel. كانت فكرتي هي إضافة أنواع JSDoc تدريجيًا لجعل فحص النوع أقوى ، لكن TS في الإصدار 4 يكفي لإعادة الكتابة ، لست متأكدًا مما إذا كان ذلك ضروريًا. لذلك ، يمكن لشخص ما تجربة Babel v. TypeScript (وإعدادات مختلفة لكل منهما) لمعرفة ما إذا كان Babel ينتج تعليمات برمجية أكثر فاعلية. فقط كن مدركًا تمامًا لهذه المشكلة ، والتي نتجت عن إنتاج مبدئي لإصدار غير ES5 لـ Node.js: https://github.com/less/less.js/issues/3414

seanCodes أيضًا ، ما زلت أجد صعوبة في التحقق من اختلاف الأداء. لم يقم أحد بإنتاج علاقات عامة / خطوات لإثبات الاختلاف في الأداء بشكل نهائي. هناك عدد من الحكايات في هذا الموضوع ، ولكن بدون تعليمات برمجية أو خطوات قابلة للتكرار ، لست متأكدًا من كيفية قيام شخص ما بالتحقيق في هذا الأمر. من الناحية المثالية ، سيكون هناك علاقات عامة تطلق أداة تحديد ملامح (عبر مصحح أخطاء Chrome أو غير ذلك) لإخراج رقم على نظام ، بمتوسط ​​عدد من الاختبارات. لذلك لأن هذا ، حتى الآن ، ليس قابلاً للتكاثر بنسبة 100٪ ، بقدر ما كان أي شخص قادرًا على تقديم خطوات التكاثر ، وهذا جزئيًا هو سبب عدم رغبتي شخصياً في النزول إلى حفرة الأرنب تلك. (بعبارة أخرى ، التعليقات على "لقد استخدمت مصحح أخطاء Chrome" ليست مجموعة من خطوات إعادة الإنتاج. من المفيد معرفة ذلك ، لكنها لا تساعد أي شخص في التحقيق. نحتاج إلى معرفة ما نتتبعه ولماذا / ما هي النتيجة متوقع.)

لذا ، إذا أراد الناس تحسين أداء أقل باستخدام قاعدة الشفرة الحالية ، فمن المحتمل أن يتطلب الأمر عدة متطوعين وشخص واحد لامتلاك هذه المشكلة.

أنا شخصياً لم أرَ فرقًا كبيرًا في الأداء كما هو الحال في _speed_ ولكن الاختلاف في استهلاك الذاكرة مذهل ويبدو أنه يرتبط بكمية الواردات ، والتي يبدو أن تحليل كومة الذاكرة المؤقتة الخاص بي يشير إلى أنها مرتبطة بالمشكلة أيضًا.

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

تضمين التغريدة

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

"أنت" هو الجزء المهم هنا. 😉

"أنت" هو الجزء المهم هنا. 😉

اختيار الكلمات مؤسف. أعني ذلك بالمعنى العام - أي "أي شخص".
كنت سأحفر أكثر بنفسي ، لكن لدي بالفعل الكثير من اللوحات التي تدور حاليًا.

rjgotten هل يمكن أن تعطيني فكرة أفضل عن "الكثير من الملفات المستوردة"؟ هل سيفعل ذلك 100 ملف منفصل أم أننا نتحدث عن 1000؟

أيضًا ، كيف لاحظت المشكلة لأول مرة؟ هل فشل بناء بسبب استهلاك الذاكرة أم أنك تنظر إلى استخدام الذاكرة؟ أو هل لاحظت أن جهازك يتباطأ؟

لم أحاول تكرار هذا حتى الآن ، لكنني ما زلت آمل في معرفة ما يجب البحث عنه بالضبط حتى لا أضطر إلى اللجوء إلى التخمين والتحقق.

100 أو حتى يفعل ذلك. هذا يقارب حجم مشروع الحياة الواقعية الذي لاحظت فيه المشكلة.

لقد لاحظت ذلك لأول مرة عندما بدأ بناء يعمل على بيئة CI الخاصة بشركتنا بالفشل. نقوم بتشغيل تلك الموجودة داخل حاويات Docker مع تكوين قيود الذاكرة.

rjgotten هل ما زلنا نعاني من مشكلة الذاكرة في الإصدار 3.11.3؟ لقد أزلت أي تخزين مؤقت (مرجعي) لـ AST داخل الواردات في إصدار سابق ، لذلك إذا تم تعليق عمليات الاستيراد ، وتم تعليق أشجار AST داخل ذلك ، فسيؤدي ذلك إلى زيادة استخدام الذاكرة ، ولكن إذا قمنا بإسقاط الأشجار من الحجز ، هل هذا يحلها؟

@ Matthew-dean نعم ، لا تزال المشكلة موجودة في 3.11.3.

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

@ ماثيو دين أريد اختبار هذا في مشروع كبير نسبيًا ، والذي كان يفشل سابقًا. أي شيء أريد أن أعرفه؟ هل يجب علي استخدام هذا الفرع ، https://github.com/less/less.js/tree/release_v3.12.0-RC1 ؟

nfq يمكنك تجربتها ، لكن الحكمة السائدة في هذا الموضوع هي عدم تفجير تحويل ES6 ، وهو ما يفعله هذا الفرع ، وبدلاً من ذلك الحصول على مزيد من المعلومات لتشخيص المشكلة بشكل صحيح.

بالمناسبة ، حاولت فحص الكائن less أثناء التجميع في محاولة للعثور على أي كائنات ثابتة ، ولم أتمكن من العثور على أي منها. 🤷‍♂️

أواجه مشكلات في الأداء أيضًا. لنفس مجموعة الاختبار:

| الإصدار | الوقت |
| - | - |
| الإصدار 3.9.0 | ~ 1.6 ثانية |
| v3.10.0 ~ v3.11.1 | ~ 3.6 ثانية |
| الإصدار 3.11.2 + | ~ 12 ثانية |

بصرف النظر عن 3.9.0 → 3.10.0 التي تمت مناقشتها هنا ، يبدو أن هناك تدهورًا ملحوظًا في الأداء عند v3.11.2 . يبدو أن هذا التغيير في التغيير مريب:

3498 إزالة التخزين المؤقت الشجري في مدير الاستيراد (# 3498)

نفس الشيء بالنسبة لي.

توقيت البنيات المتطابقة (كل ذلك في العقدة 10.19.0):

  • الإصدار 3.9: 29.9 ثانية
  • الإصدار 3.10: 76.0 ثانية
  • الإصدار 3.12: 89.3 ثانية

@ jrnail23

هل لديك ريبو يمكن أن يبرهن على هذه النتائج؟

@ ماثيو دين لدي واحد لـ https://github.com/less/less.js/issues/3434#issuecomment -672580467: https://github.com/ecomfe/dls-tooling/tree/master/packages/ less-plugin-dls (إنه monorepo ، والذي يتضمن مكوِّنًا أقل.)

آسف ، @ ماثيو دين ، لا أفعل. هذه النتائج من منتج صاحب العمل.

هذه النتائج من منتج صاحب العمل.

نفس السبب لا يمكنني تقديم أي ملفات أيضًا. 😞

rjgotten @ jrnail23Justineo - عادل الغريب، هل لديك عدد من الحالات التي يتم استيراد نفس استيراد عدة مرات في ملفات مختلفة؟

في حالتي ، لدينا مكون إضافي يضخ عبارة @import ويوفر مجموعة من الوظائف المخصصة. يستورد الملف المستورد أجزاء أخرى من المشروع والتي ستنتج في النهاية أكثر من 1000 متغير أقل.

@ Matthew-dean ، لدينا ملف base.less يستورد الأشياء الشائعة (على سبيل المثال ، متغيرات الألوان ، والطباعة ، وما إلى ذلك).
يُظهر بعض الالتقاط السريع لتطبيقنا أنه يتم استيراد مرجع base.less (على سبيل المثال ، <strong i="8">@import</strong> (reference) "../../../less/base.less"; ) بواسطة 66 ملفًا آخر خاصًا بالمكون / الميزة less ، وبعض هذه الملفات قد قم أيضًا باستيراد ملفات أقل من مكونات أخرى / خاصة بالميزات (والتي قد تشير بدورها إلى base.less ).
ومن المثير للاهتمام ، أنه من الواضح أن لدينا أيضًا ملفًا آخر من less يستورد نفسه كمرجع (ربما عن طريق الخطأ؟).

rjgotten @ jrnail23Justineo - عادل الغريب، هل لديك عدد من الحالات التي يتم استيراد نفس استيراد عدة مرات في ملفات مختلفة؟

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

في الأساس؛ تم إعداد كل تابع لاستيراد تبعياته بشكل صارم ونعتمد على أقل مترجم لإلغاء الخداع وتسلسل الواردات بالترتيب الصحيح وضمان إخراج CSS الصحيح.

تضمين التغريدة

لقد قمت بنشره وحذفه (لأنني اعتقدت أنني اكتشفته ، لكنني ما زلت لا أستطيع تكراره) ، لا تزال هناك أي خطوات لإعادة إنتاجه في ما يبلغ عنه الأشخاص ، بما في ذلك العملية.

حتى شيء بسيط مثل هذا:

في 3.11 أحد الخوادم المدرجة لـ RuleSet هو ImportManager.

لا يمكنني العثور على دليل على ذلك ، لكنني أيضًا لا أعرف كيف تمكنت من تحديد ذلك. لست على دراية كافية بـ Chrome DevTools لمعرفة كيف يمكن للمرء أن يحدد شيئًا مثل ما يتم الاحتفاظ به بواسطة ماذا ، وهذا موضوع غامض بدرجة كافية لم تساعدني Google فيه. مثل ، هل يرتبط الأشخاص بعملية العقدة؟ تشغيله في المتصفح وتحديد نقاط التوقف؟ ما هي الخطوات؟

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

Justineo في الريبو الخاص بك ، ما هي الخطوات التي اتخذتها لتحديد حجم الذاكرة أو وقت التجميع؟ ماذا كنت تستخدم للقياس؟

Justineo منذ أن الإنشاء لديك؟ https://github.com/less/less.js/tree/cache-restored

فقط لإعطاء بعض التحديثات عن التجربة / الاختبار اليوم:

Grunt's shell:test مرة

  • أقل من 3.9 - 1.8 ثانية
  • أقل 3.12 (Babel-transpiled إلى ES5) - 9.2s
  • أقل 3.12 (Babel-transpiled إلى ES6) - 3.1s
  • أقل 3.12 (TypeScript-transpiled إلى ES5) - 3.2 ثانية

لذلك ، أعتقد أن الخط الطويل والقصير هو أن الشفرة المنقولة دائمًا ما تكون أبطأ ، وكنا ساذجين في التفكير بطريقة أخرى. أنا مندهش نوعًا ما لأن الترجمة أصبحت الآن "قياسية" في عالم JavaScript. هل هناك أي بحث آخر يدعم هذا؟

Justineo في الريبو الخاص بك ، ما هي الخطوات التي اتخذتها لتحديد حجم الذاكرة أو وقت التجميع؟ ماذا كنت تستخدم للقياس؟

سينتج npm run test إجمالي الوقت المنقضي. وفي مشاريع أخرى ، نشهد OOM عند التبديل إلى 3.12.

إذا نظرنا إلى التعليمات البرمجية التي تم إنشاؤها بواسطة TypeScript ، فسنحصل على شيء مثل:

Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var node_1 = tslib_1.__importDefault(require("./node"));
var variable_1 = tslib_1.__importDefault(require("./variable"));
var property_1 = tslib_1.__importDefault(require("./property"));
var Quoted = /** <strong i="6">@class</strong> */ (function (_super) {
    tslib_1.__extends(Quoted, _super);
    function Quoted(str, content, escaped, index, currentFileInfo) {
        var _this = _super.call(this) || this;
        _this.escaped = (escaped == null) ? true : escaped;
        _this.value = content || '';
        _this.quote = str.charAt(0);
        _this._index = index;
        _this._fileInfo = currentFileInfo;
        _this.variableRegex = /@\{([\w-]+)\}/g;
        _this.propRegex = /\$\{([\w-]+)\}/g;
        _this.allowRoot = escaped;
        return _this;
    }

ضد:

var Node = require('./node'),
    Variable = require('./variable'),
    Property = require('./property');

var Quoted = function (str, content, escaped, index, currentFileInfo) {
    this.escaped = (escaped == null) ? true : escaped;
    this.value = content || '';
    this.quote = str.charAt(0);
    this._index = index;
    this._fileInfo = currentFileInfo;
    this.variableRegex = /@\{([\w-]+)\}/g;
    this.propRegex = /\$\{([\w-]+)\}/g;
};

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

تحديث:

إذا حاولت وضع الاختبارات 3.9 على قدم المساواة مع ما هو في 3.12 ، فأنا سأحصل أساسًا على 1.2 ثانية مقابل 1.3 ثانية. لذلك لست متأكدًا بعد الآن من هذا الاختلاف لأن الاختبارات قد تغيرت. يجب أن يتم تشغيله مقابل نفس الملفات الأقل بالضبط.

Justineorjgotten لقد دفعت بضعة تعديلات نسخة مطبوعة على الآلة الكاتبة لربما جعل بناء أكثر كفاءة. هل تريد بناء هذا الفرع وتجربته؟ https://github.com/less/less.js/tree/cache-restored

@ ماثيو دين 👍 شكرا! سأحاول في وقت لاحق اليوم.

لقد اختبرت الفرع cache-restored وهو أسرع بكثير من الإصدار v3.11.2 + ، بنفس سرعة الإصدار 3.1.0 ~ 3.11.1 تقريبًا.

تضمين التغريدة

لقد اختبرت الفرع الذي تمت استعادته من ذاكرة التخزين المؤقت وهو أسرع بكثير من الإصدار 3.11.2 + ، بنفس سرعة الإصدار 3.1.0 ~ 3.11.1 تقريبًا.

حسنًا ، هذا واعد. دعنا نحصل على بعض التعليقات من rjgotten @ jrnail23 وغيرها في هذا الموضوع. تمت إزالة ذاكرة التخزين المؤقت هذه بعد نشر هذا الموضوع (3.11.2) ؛ في الواقع ، كانت هذه محاولة لإزالة جزء من الذاكرة العلوية ، ولكن في الحالات التي تقوم فيها باستيراد نفس الملف عدة مرات ، كان من الممكن بالتأكيد أن يجعل الأمور أسوأ.

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

@ Matthew-dean ، أواجه بعض المشاكل أثناء محاولة استخدام الفرع cache-restored (لست واضحًا تمامًا بشأن ما يجب فعله لاستخدامه محليًا ، حيث فشل npm link أنا).
هل يمكنك نشر إصدار كناري / ما قبل الإصدار يمكنني تجربته؟

@ jrnail23

أعتقد أن هذا نجح. حاول إزالة Less والتثبيت بـ npm i [email protected]+84d40222

@ ماثيو دين ، لقد جربت هذا الإصدار للتو ، وما زال سيئًا بالنسبة لي.
بالنسبة إلى إصدارات webpack الحديثة (بدون تخزين مؤقت) ، يستغرق الأمر 62.4 ثانية للإصدار 3.9 ، ولكن يستغرق 121 ثانية للإصدار 3.13.1.
بالنسبة للإصدارات المخزنة مؤقتًا ، يستغرق الإصدار v3.9 30 ثانية ، بينما يستغرق الإصدار v3.13.1 83-87 ثانية.

@ jrnail23 هل يمكنك محاولة إزالة كافة الوحدات النمطية للعقدة وتثبيت [email protected]+b2049010

أقل من 3.9 المعيار المرجعي:
Screen Shot 2020-12-05 at 2 36 09 PM

أقل 4.0.1-alpha.0:
Screen Shot 2020-12-05 at 1 12 26 PM

أقل 4.0.1-alpha.2:
Screen Shot 2020-12-05 at 2 35 20 PM

Justineorjgotten هل جربت هذا أيضا؟

@ jrnail23Justineorjgotten

لاحظ أن هذا الإصدار 4.0 لذا فقد تواجه أخطاء إذا كانت التعليمات البرمجية الخاصة بك تحتوي على هذه التغييرات العاجلة:

  • الأقواس مطلوبة لمكالمات mixin (على سبيل المثال ، .mixin; غير مسموح به)
  • وضع Less الحسابي الافتراضي هو الآن تقسيم بين أقواس ، لذلك يجب أن تكون الشرطة المائلة (المقصود بها الرياضيات) بين قوسين

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

نتيجة نفس مجموعة الاختبار مثل https://github.com/less/less.js/issues/3434#issuecomment -672580467:

| الإصدار | الوقت |
| - | - |
| الإصدار 3.9.0 | ~ 1.6 ثانية |
| v3.10.0 ~ v3.11.1 | ~ 3.6 ثانية |
| الإصدار 3.11.2 + | ~ 12 ثانية |
| 4.0.1-alpha.2 + b2049010 | ~ 1.6 ثانية |

يمكنني أن أؤكد أنه بالنسبة لمجموعة الاختبار الخاصة بي ، فقد تحسن مستوى الأداء إلى v3.9.0. في غاية الامتنان مات! بينما لست متأكدًا من تغيير الاستراحة في وضع الرياضيات. قد يؤدي تغيير هذا إلى تعطل العديد من تطبيقاتنا ، لذلك قد نكون عالقين في الإصدار 3.9.0 حتى يتم حل مشكلة الأداء.

تضمين التغريدة

بينما لست متأكدًا من تغيير الاستراحة في وضع الرياضيات.

يمكنك التحويل البرمجي بشكل صريح في الوضع math=always للحصول على السلوك الرياضي السابق. إنه مجرد افتراضي مختلف.

تفصيل القضية

TL ؛ DR - احذر من نمط الفصل

كانت المشكلة في ترشيح الأصناف في كل من Babel و TypeScript. (بعبارة أخرى ، كان كلاهما يعاني من نفس مشكلات الأداء مع الشفرة المنقولة ، مع كون Babel أسوأ قليلاً.) الآن ، منذ سنوات ، عندما تم تقديم نمط الفصل الدراسي ، قيل لي - وحتى هذه المشكلة ، اعتقدت - تلك الفئة الميراث في JavaScript هو سكر نحوي للوراثة الوظيفية.

باختصار ، ليس كذلك. _ (تعديل: حسنًا .... إنه كذلك وليس كذلك. يعتمد ذلك على ما تعنيه بـ "الميراث" وكيف حددته كما سترى قريبًا .... أي هناك عدة أنماط إنشاء "ميراث" في سلسلة النموذج الأولي في JavaScript ، وتمثل الفئات نمطًا واحدًا فقط ، ولكن هذا النمط يختلف إلى حد ما عن جميع الأنماط الأخرى ، ومن ثم فإن TS / Babel بحاجة إلى رمز مساعد "لتقليد" هذا النمط باستخدام وظائف متخصصة.) _

بدا رمز أقل مثل هذا:

var Node = function() {
  this.foo = 'bar';
}

var Inherited = function() {
  this.value = 1;
}
Inherited.prototype = new Node();

var myNode = new Inherited();

لنفترض الآن أنك تريد إعادة كتابة هذا باستخدام JS "الحديثة". في الواقع ، يمكنك أتمتة هذه العملية ، وهو ما فعلته ، لكن في كلتا الحالتين كنت سأكتبها بنفس الطريقة ، والتي كانت:

class Node {
  constructor() {
    this.foo = 'bar';
  }
}
class Inherited extends Node {
  constructor() {
    super();
    this.value = 1;
  }
}
var myNode = new Inherited();

نفس الشيء ، صحيح؟ في الواقع لا. الأول سينشئ كائنًا بخاصية { value: 1 } ، وفي سلسلة النموذج الأولي الخاص به ، يحتوي على كائن { foo: 'bar' } .

الثانية ، لأنها ستستدعي المُنشئ على كل من Inherited و Node ، ستنشئ كائنًا بهيكل مثل { value: 1, foo: 'bar' } .

الآن ، بالنسبة إلى _user_ ، هذا لا يهم حقًا ، لأنه يمكنك الوصول إلى كل من value و foo من myNode في كلتا الحالتين. _ وظيفيًا_ ، يبدو أنهم يتصرفون بالطريقة نفسها.

هذا هو المكان الذي أدخل فيه التكهنات البحتة

مما أتذكره في المقالات حول محركات JIT مثل V8 ، فإن هياكل الكائنات مهمة جدًا في الواقع. إذا قمت بإنشاء مجموعة من الهياكل مثل { value: 1 } ، { value: 2 } ، { value: 3 } ، { value: 4 } ، فإن V8 ينشئ تمثيلًا ثابتًا داخليًا لهذا الهيكل. أنت تقوم بشكل أساسي بتخزين البنية + البيانات مرة واحدة ، ثم البيانات 3 مرات أخرى.

ولكن إذا أضفت خصائص مختلفة إلى هذا في كل مرة ، مثل: { a: 'a', value: 1 } ، { b: 'b', value: 2 } ، { c: 'c', value: 3 } ، { d: 'd', value: 4 } ، فهذه هي 4 هياكل مختلفة مع 4 مجموعات بيانات ، حتى لو تم إنشاؤها من نفس مجموعة الفئات الأصلية. تعمل كل طفرة في كائن JS على تحسين عمليات البحث عن البيانات ، ويؤدي نمط الفئة الذي يتم تحويله إلى وظائف (ربما) إلى حدوث طفرات أكثر تميزًا. (بصراحة ليس لدي أي فكرة عما إذا كان هذا ينطبق على دعم الطبقة الأصلية في المتصفحات.)

AFAIK ، ما هو صحيح أيضًا هو أنه كلما زاد عدد الخصائص التي لديك على كائن ، زادت مدة البحث عن خاصية فردية.

مرة أخرى للمستخدمين النهائيين ، نادرًا ما يكون هذا مهمًا لأن محركات JS سريعة جدًا. يقول Buuuuut أنك تقوم بصيانة محرك يقوم بإنشاء خصائص / طرق والبحث عنها في الكثير من الكائنات بأسرع ما يمكن. (Ding ding ding.) فجأة تضيف هذه الفروق الصغيرة بين طريقة "تمديد" TypeScript / Babel للكائنات وبين وراثة النماذج الوظيفية الأصلية بسرعة كبيرة.

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

ضع في اعتبارك الآن أن بعض العقد ترث من العقد الأخرى. هذا يعني أن التمثيل في الذاكرة للفئات يبدأ في التكاثر ، كما تفعل مثيلاتها الموروثة.

مرة أخرى ، هذه تكهنات

يجب أن أؤكد على أخذ كل هذا بحذر ، لأنني لم أسمع أبدًا عن التحول إلى الفصول الدراسية باعتباره كارثيًا على الأداء. ما أعتقد أنه يحدث هو أن هناك مجموعة خاصة من عمليات البحث عن الكائن / المثيل التي يستخدمها Less والتي تعمل على إلغاء تحسين JIT بشكل جدي. _ (إذا كان بعض خبراء محرك JavaScript يعرف سبب أداء الفئات المترجمة بشكل أسوأ بكثير من طرق وراثة JS الأصلية في هذه الحالة ، فأنا أحب أن أعرف.) _ حاولت إنشاء مقياس أداء لإنشاء آلاف الكائنات الموروثة باستخدام كلتا الطريقتين ، و لم أستطع أبدًا أن أرى فرقًا ثابتًا في الأداء.

لذا ، قبل أن تبتعد عن عبارة "الفئات في JavaScript سيئة" ، قد يكون نمطًا مؤسفًا آخر في قاعدة الكود الأقل مقترنًا بالاختلاف في الفئات المنقولة مقابل JS الأصلية التي أدت إلى هذا الانخفاض في الأداء.

كيف اكتشفت ذلك في النهاية

بصراحة ، لم أشك أبدًا في نمط الفصل. كنت أعلم أن كود ES5 الأصلي يعمل بشكل أسرع من الشفرة المعكوسة ، لكنني اشتبهت في وجود شيء ما حول وظائف السهم أو نشر بناء الجملة في مكان ما. لا يزال لدي فرع ES5 محدث ، لذلك قررت يومًا ما تشغيل lebab مرة أخرى ، واستخدام هذه التحويلات فقط: let,class,commonjs,template . هذا عندما اكتشفت أنه كان يعاني من مشاكل في الأداء مرة أخرى. كنت أعلم أنه لم يكن قالب سلسلة أو اسمحوا لفر. اعتقدت أن طلب الاستيراد قد فعل شيئًا لذا لعبت به لفترة من الوقت. أن ترك الطبقات. لذا ، على حدس ، أعدت كتابة جميع الفئات الموسعة إلى الوراثة الوظيفية. بام ، الأداء عاد.

حكاية تحذيرية

وبالتالي! الدرس المستفاد. إذا كان مشروعك على كود ES5 القديم ، وكنت ترغب في الحصول على جودة Babel-ified أو TypeScripted "الحديثة" ، فتذكر أنه كل ما تقوم بنقله ، فأنت لم تكتبه.

كنت لا أزال قادرًا على إعادة كتابة الفصول إلى شيء يشبه الفصل بدرجة أكبر ،

يمكنك التحويل البرمجي صراحة في الرياضيات = الوضع دائمًا للحصول على السلوك الرياضي السابق. إنه مجرد افتراضي مختلف.

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

شكرا لك على التفاصيل التفصيلية!

لقد رأيت استخدام Object.assign في الإخراج المترجم ، مما يعني أنه يعمل فقط في المتصفحات التي تدعم بناء جملة ES class الأصلي ما لم تكن polyfills مطلوبة الآن. فهل يمكننا فقط استخدام البنية الأصلية دون الانتقال إلى ES5 إذا كنا نعتزم إسقاط الدعم للبيئات القديمة (على سبيل المثال. IE11 ، Node 4 ، ...)؟

في الوقت نفسه ، أعتقد أنه من الأفضل أن نتمكن من فصل إصلاح تدهور الأداء والتغييرات المعطلة ، مما يعني تثبيت إصلاح الأداء في الإصدار 3 وتضمين التغييرات المعطلة فقط في الإصدار 4.

@ ماثيو دين
حقيقة أن فصول ES هي الجاني مخيفة بشكل جنوني .
شكرا لتفصيل التفاصيل.

يذهب لإظهار: _ التكوين على الميراث_ 😛

على الرغم من لمعلوماتك ؛ إذا كنت تريد سلسلة وراثة أولية أنظف ، فعليك فعلها بطريقة مختلفة قليلاً عن مثالك.
إذا كنت تستخدم Object.create مثل هذا:

var Node = function() {
  this.foo = 'bar';
}
Node.prototype = Object.create();
Node.prototype.constructor = Node;

var Inherited = function() {
  Node.prototype.constructor.call( this );
  this.value = 1;
}
Inherited.prototype = Object.create( Node.prototype );
Inherited.prototype.constructor = Inherited;

var myNode = new Inherited();

ثم تقوم بتسطيح الخصائص على المثيلات نفسها والتي تشترك بعد ذلك في نفس الشكل ؛ النماذج الأولية تشترك في الشكل ؛ _و_ تتجنب الاضطرار إلى الزحف إلى سلاسل النماذج الأولية لكل وصول إلى الممتلكات. 😉

تضمين التغريدة

لقد رأيت استخدام Object.assign في الإخراج المترجم ، مما يعني أنه يعمل فقط في المتصفحات التي تدعم بناء جملة فئة ES الأصلي ما لم تكن هناك حاجة الآن إلى polyfills. فهل يمكننا فقط استخدام البنية الأصلية دون الانتقال إلى ES5 إذا كنا نعتزم إسقاط الدعم للبيئات القديمة (على سبيل المثال. IE11 ، Node 4 ، ...)؟

لا أعتقد أن هذا صحيح تمامًا ، فقد هبطت Object.assign قبل وقت قصير من تنفيذ الفصول الدراسية ولكن تم أخذ وجهة نظرك. كنت أتمنى فقط تجنب كتابة [Something].prototype.property مرارًا وتكرارًا: /

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

في الوقت نفسه ، أعتقد أنه من الأفضل أن نتمكن من فصل إصلاح تدهور الأداء والتغييرات المعطلة ، مما يعني تثبيت إصلاح الأداء في الإصدار 3 وتضمين التغييرات المعطلة فقط في الإصدار 4.

لقد كنت أفكر في ذلك ، وأعتقد أن هذه أيضًا نقطة عادلة. أحاول فقط أن أجعل رأسي لا ينفجر في بناء / صيانة 3 إصدارات رئيسية من Less.

rjgotten AFAIK هذا ما يفترض أن يفعله نمط الفصل ، تمامًا كما حددته. إلا إذا كنت لا أرى فرقا حرجا. إذن 🤷‍♂️. لن أحاول تغيير نمط وراثة عقدة Less's مرة أخرى إذا كان يعمل جيدًا (بخلاف أنني قد أزيل مكالمة Object.assign كما اقترح @ Justineo .)

Justineorjgotten هل جربت هذا: [email protected]+b1390a54

جربته للتو:

| الإصدار | الوقت |
| - | - |
| الإصدار 3.9.0 | ~ 1.6 ثانية |
| v3.10.0 ~ v3.11.1 | ~ 3.6 ثانية |
| الإصدار 3.11.2 + | ~ 12 ثانية |
| 4.0.1-alpha.2 + b2049010 | ~ 1.6 ثانية |
| 3.13.0-alpha.10 + b1390a54 | ~ 4.7 ثانية |

ملاحظة. تم الاختبار مع Node.js v12.13.1.

أنا ماذا.

لم يكن لديك الوقت لإعداد معايير منفصلة.
ولكن من منظور اختبار التكامل ، إليك بعض الأرقام الواقعية: النتائج التراكمية لمشروع Webpack الخاص بدرجة الإنتاج والذي يستخدم أقل.

الإصدار | الوقت | ذاكرة الذروة
: ------------------------ | --------: | ------------:
3.9 | 35376ms | 950 ميغا بايت
3.11.3 | 37878ms | 920 ميغا بايت
3.13.0-alpha.10 + b1390a54 | 34801ms | 740 ميغا بايت
3.13.1-alpha.1 + 84d40222 | 37367ms | 990 ميغا بايت
4.0.1-alpha.2 + b2049010 | 35857ms | 770 ميغا بايت

بالنسبة لي 3.13.0 يعطي _أفضل_ النتائج ... 🙈

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

3.13.1 الذي استعاد ذاكرة التخزين المؤقت لا يساعد في تحسين أوقات الترجمة في العالم الحقيقي ويؤدي فقط إلى تضخيم استخدام الذاكرة.

rjgotten نعم ، أعتقد أن المشكلة تكمن في أن الأشخاص في هذا الموضوع يقيسون أشياء مختلفة ، وحتى الآن يمتلك كل شخص بشكل أساسي بيانات خاصة يستحيل تكرارها (دون

فيما يلي تصميم منشور مع تغييرات التوريث على الشجرة ، ومع استعادة ذاكرة التخزين المؤقت لشجرة التحليل: [email protected]+e8d05c61

حالة اختبار

https://github.com/ecomfe/dls-tooling/tree/master/packages/less-plugin-dls

نتائج

| الإصدار | الوقت |
| - | - |
| الإصدار 3.9.0 | ~ 1.6 ثانية |
| v3.10.0 ~ v3.11.1 | ~ 3.6 ثانية |
| الإصدار 3.11.2 + | ~ 12 ثانية |
| 4.0.1-alpha.2 | ~ 1.6 ثانية |
| 3.13.0 ألفا .10 | ~ 4.7 ثانية |
| 3.13.0 ألفا 12 | ~ 1.6 ثانية |

إصدار Node.js

الإصدار 12.13.1


بالنسبة لي يبدو أن هذا الإصدار يعمل بشكل مثالي. سأطلب من زملائي المحاولة والتحقق.

يعمل بشكل أسوأ قليلاً من alpha.10 بالنسبة لي ، ولكن يمكن أيضًا أن يكون مجرد تباين:

الإصدار | الوقت | ذاكرة الذروة
: ------------------------ | --------: | ------------:
3.9 | 35376ms | 950 ميغا بايت
3.11.3 | 37878ms | 920 ميغا بايت
3.13.0-alpha.10 + b1390a54 | 34801ms | 740 ميغا بايت
3.13.0-alpha.12 + e8d05c61 | 36263 مللي ثانية | 760 ميغا بايت
3.13.1-alpha.1 + 84d40222 | 37367ms | 990 ميغا بايت
4.0.1-alpha.2 + b2049010 | 35857ms | 770 ميغا بايت

@ Matthew-dean ، يبدو أن الكود الخاص بي غير متوافق بعد مع التغييرات 4.0.1-alpha.2+b2049010 . سأرى ما إذا كان بإمكاني حل مشاكلي وتجربتها.

rjgotten نعم ، يبدو الاختلاف طفيفًا في حالة الاختبار الخاصة بك.

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

العنصر الآخر الذي سأفعله هو فتح مشكلة لأي شخص للاستيلاء عليها وهي وضع خط أنابيب CI يفشل أقل إذا كان أقل من عتبة معيارية معينة.

@ jrnail23 سيكون رائعًا إذا كان بإمكانك التعديل لتشغيل 4.0 alpha ، ولكن هل يمكنك في هذه الأثناء تجربة [email protected]+e8d05c61 ؟

@ ماثيو دين ، أحصل على ما يلي من أجل بنائي:

  • الإصدار 3.9: 98 ثانية
  • v3.10.3: 161 ثانية
  • الإصدار 3.13.0-alpha.12: 93-96 ثانية

لذلك يبدو أنك عادت إلى حيث تريد أن تكون! عمل جيد!

عمل جيد!

نعم ، سأذهب إلى المركز الثاني ؛ الثالث؛ ورابع ذلك.
كان هذا تراجعاً سيئاً في الأداء استغرق الكثير من الجهد لتنظيفه.

عمل جيد جدا.

فريق طيب! سأقوم بنشر الإصدار 3.x ، وفي وقت لاحق ، ربما الأسبوع المقبل ، أنشر 4.0. يجب أن يحتوي كلاهما الآن على إصلاحات الأداء. شكرا لكل من ساعد في التصحيح!

بالمناسبة ، أنا حاليًا بصدد تحويل قاعدة الشفرة Less.js إلى TypeScript ، وأخطط لاستغلال الفرصة للقيام ببعض ضبط / إعادة بناء الأداء. أنا منفتح للمساعدة إذا كان أي شخص مهتم! https://github.com/matthew-dean/less.js/compare/master...matthew-dean : التالي

أي شيء محدد حيث تفضل بعض العيون الزائدة؟ العلاقات العامة كبيرة جدًا ، لذلك لا أعرف حقًا من أين أبدأ

kevinramharak هذا سؤال عادل. لأكون صادقًا ، واجهت حواجز غير متوقعة مع التحويل إلى TypeScript (الأخطاء التي أصبح من الصعب حلها) ، وأنا الآن أعيد التفكير في القيام بذلك على الإطلاق. القليل يعمل بشكل جيد كما هو ، والكثير من الأسباب التي أردت تحويلها (لجعل إعادة البناء / إضافة ميزات لغة جديدة أسهل) أصبحت الآن غير ذات صلة حيث قررت نقل أفكاري لميزات اللغة الجديدة إلى ما قبل- لغة المعالجة. لا أريد المبالغة في الترويج لنفسي ، لذا أرسل رسالة مباشرة على Twitter أو Gitter إذا كنت تريد التفاصيل.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات