أولاً ، شكرًا جزيلاً لك على مكتبة المكونات الرائعة هذه! انه لشيء رائع!
لقد أضفت درجًا في تطبيقي الجديد. في الغالب ، قمت بطباعة مثال درج. فقط من أجل PoC أنا تضاعفت
<Divider />
<List>{mailFolderListItems}</List>
الجزء.
بعد ذلك ، يبدو الأمر بطيئًا للغاية ، خاصة على الجهاز المحمول (nexus 4 ، cordova with crosswalk 20). أستخدم وضع dev ، لكن وضع prod لا يسرع كثيرًا.
من خلال أدوات تطوير التفاعل ، لاحظت أن المكونات الموجودة في mailFolderListItems يتم عرضها على كل نقرة على رابط في جهاز التوجيه التفاعلي أو حتى فتح القائمة. يستغرق الأمر ما يصل إلى 50-60 مللي ثانية لإعادة عرض ONE {mailFolderListItems}
. أنا أستعمل
const modalProps = {
keepMounted: true, // Better open performance on mobile.
};
للتخلص من عدم اليقين مع مكونات التطبيق الأخرى ، قمت بتحويل mailFolderListItems
إلى مكون وقمت بتعطيل العرض:
class MailFolderListItems extends React.Component<{}, {}> {
shouldComponentUpdate() {
return false;
}
render() {
return (
<List>
<Link to={Routes.Startpage.path}>
<ListItem>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
[...]
<Divider />
<MailFolderListItems />
بعد ذلك يبدو هذا الجزء على ما يرام.
لقد وجدت https://github.com/mui-org/material-ui/issues/5628 . أقترح إعادة النظر فيه . يعد تحسين shouldComponentUpdate
خطوة أساسية وأهم للحصول على الأداء. PureComponent
هو الاختصار الأكثر شيوعًا.
علاوة على ذلك ، لاحظت أنه يتم إنفاق الكثير من الوقت (1-2 مللي ثانية وأكثر لكل مكون من مكونات واجهة المستخدم المادية) في WithStyles
.
أتوقع الحصول على معظم أداء التفاعل المحتمل لهذه المكتبة الرائعة.
يصبح التطبيق أبطأ مع كل مكون من مكونات واجهة المستخدم المادية.
لا أقدم إعادة إنتاج المثال حتى الآن ، لأنني قمت فقط بنسخ نسخة من صفحة العرض التوضيحي للمكون ، ولكن إذا لزم الأمر ، يمكنني تقديم عرض الكود وعلبة العرض. بالنسبة للمتصفح ، يكون ذلك ملحوظًا ، إذا تباطأ المتصفح حسب العامل> = 5x في إعداد الأداء.
| التقنية | الإصدار |
| -------------- | --------- |
| واجهة المستخدم المادية | 1.0.0 بيتا 38 |
| أيقونات واجهة المستخدم المادية | 1.0.0 بيتا 36 |
| رد فعل | 16.2.0 |
| متصفح | كوردوفا معبر 20 (يساوي أندرويد كروم 50) |
أتوقع الحصول على معظم أداء التفاعل المحتمل لهذه المكتبة الرائعة.
سيكون أداء Bessonov @ إصدارًا بؤريًا بعد الإصدار 1. لقد حاولنا الحفاظ على جوهر المكتبة بأسرع ما يمكن. يجب أن تكون جيدة بما يكفي لأكثر من 90٪ من الحالات. على الأقل ، إنها تجربتي في استخدام المكتبة حتى الآن. لم تقدم أي مرجع خارجي ، بصرف النظر عن إثارة انتباهنا حول حقيقة أن الأداء مهم ، لا يمكننا جعل هذه المشكلة قابلة للتنفيذ. إذا كنت قادرًا على تحديد قيود جذر الأداء لـ Material-UI التي يمكننا التحقيق فيها (باستخدام رموز الاستنساخ وصندوق أو مستودع) ، فيرجى رفعه. حتى ذلك الحين ، أغلق المشكلة.
oliviertassinari أشكركم على ردكم السريع! أنا سعيد جدًا لسماع ذلك ، سيكون التركيز على الأداء بعد الإصدار.
يجب أن تكون جيدة بما يكفي لأكثر من 90٪ من الحالات. على الأقل ، إنها تجربتي في استخدام المكتبة حتى الآن.
على سطح المكتب - نعم ، هو كذلك. لكنها بطيئة حقًا على الجوّال. Just Drawer وبعض الأزرار تجعل التطبيق بطيئًا. إنه لا يستجيب ويستهلك المزيد من الطاقة حسب الحاجة.
لم تقدم أي مرجع خارجي ، بصرف النظر عن إثارة انتباهنا حول حقيقة أن الأداء مهم ، لا يمكننا جعل هذه المشكلة قابلة للتنفيذ.
لقد قدمت إشارة إلى المشكلة التي أثيرت بالفعل ومرجعًا للرد على الوثائق.
إذا كنت قادرًا على تحديد قيود جذر الأداء لـ Material-UI التي يمكننا التحقيق فيها (باستخدام رموز الاستنساخ وصندوق أو مستودع)
كما قلت ، يمكنني فعل ذلك. هنا مقارنة مكون نقي وغير نقي. خطوات التكاثر هي:
و الأن:
index.js
pure
إلى true
هذا المثال غير واقعي قليلاً لأنني قمت بإدراج الكثير من عناصر القائمة. ولكن كما قلت ، على الجوّال ، يتم بسرعة كبيرة الإشارة إلى حيث "تشعر" بكل فعل.
هذه هي مشكلتي مع WithStyles
. إنه على سطح المكتب مع التحكم في وحدة المعالجة المركزية. أود نشر لقطات شاشة من جهاز حقيقي يوم الاثنين.
الوقت مقابل WithStyles(ListItem)
:
الوقت مقابل ListItem
:
الفرق هو 1.26 مللي ثانية فقط لمكون ListItem
. مع 13 مكونًا مثل هذا ، لا يمكنك تصيير 60 إطارًا في الثانية بعد الآن. لكنني لاحظت على سطح المكتب أن هذه المدة ليست هنا دائمًا.
هنا مقارنة مكون نقي وغير نقي
بالمناسبة ، لا أقول أن PureComponent هو الحل لجميع مشكلات الأداء. أقول فقط ، يمكن أن يكون أحد المساعدين جعل واجهة المستخدم المادية قابلة للاستخدام على الهاتف المحمول.
الفرق هو 1.26 مللي ثانية فقط لمكون عنصر القائمة.
Bessonov يجب أن يكون المكون WithStyles رخيصًا جدًا للمثيلات المتكررة لنفس المكون. نقوم بحقن CSS مرة واحدة فقط.
ربما وصلت إلى قيود React وتكلفة مكونات الترتيب الأعلى.
هناك مجموعة من الحلول للتخفيف من مشكلة الأداء في React. على سبيل المثال ، يمكنك استخدام محاكاة العنصر والمحاكاة الافتراضية. أبقي هذه المشكلة مفتوحة كنقطة بداية لتحقيق الأداء المستقبلي.
لا أعتقد أن هناك الكثير مما يمكننا فعله حيال ذلك الآن. شكرا لإثارة القلق.
حسنًا ، هذا جزء واحد فقط. ما رأيك في الجزء الأكثر أهمية - تحسين shouldComponentUpdate
؟
تحرير: أريد تقسيم هذه المسألة إلى جزأين. هذا الجزء هو حول shouldComponentUpdate
والجزء الآخر WithStyles
، إذا كان بإمكاني إظهار المزيد من المعلومات. هل هذا مناسب لك؟
التحسين shouldComponentUpdate
Bessonov نحن لا ننفذ مثل هذا المنطق عن قصد على جانب Material-UI لسببين:
shouldComponentUpdate
من جذر شجرة React ، زادت فعاليتها. أعني ، كلما زاد تقليم الشجرة ، كان ذلك أفضل. مكونات واجهة المستخدم المادية منخفضة المستوى. هناك فرصة منخفضة للرافعة المالية .الفرصة الوحيدة التي وجدناها هي مع الرموز. دعنا نعرف ما إذا كان يمكنك التعرف على جديدة.
الجزء الآخر لـ WithStyles
+ 90٪ من الوقت الذي تقضيه في WithStyles يتم إنفاقه فعليًا في JSS ، هناك القليل جدًا الذي يمكننا القيام به حيال ذلك على جانب Material-UI.
على الأقل ، كنت أحدد فرصة التخزين المؤقت للعرض من جانب الخادم مؤخرًا لتحسين الأداء بشكل كبير في العرض المتكرر. لكنها من جانب الخادم فقط.
تقبل معظم مكوناتنا عناصر التفاعل ، وهو تغيير مرجعي لعنصر التفاعل في كل تصيير ، مما يجعل المنطق يهدر دورات وحدة المعالجة المركزية بشكل منهجي.
هذا يعتمد على الاستخدام ويمكن تحسينه. لا أقوم بتقييم نفسي ، لكنني متأكد من أن الاستخدام الصحيح للمكونات وتحسين shouldComponentUpdate
(مع المقارنة السطحية) أقل تكلفة من المكون غير المحسن ، خاصة بالنسبة للهياكل غير القابلة للتغيير (و immutable.js ليس مطلوبًا بالمناسبة). تذكرة ذات صلة: https://github.com/mui-org/material-ui/issues/4305
على سبيل المثال في https://github.com/mui-org/material-ui/blob/v1-beta/docs/src/pages/demos/drawers/PermanentDrawer.js#L68 يؤدي هذا إلى كائنات جديدة ويجني PureComponent
بلا معنى:
classes={{
paper: classes.drawerPaper,
}}
لأنه يعود في كل مرة كائن جديد. لكن لا:
const drawerClasses = {
paper: classes.drawerPaper,
};
[...]
classes={drawerClasses}
نفس الشيء بالنسبة للمكونات.
كلما اقترب منطق shouldComponentUpdate من جذر شجرة React ، زادت فعاليتها. أعني ، كلما زاد تقليم الشجرة ، كان ذلك أفضل.
نعم هذا صحيح.
مكونات واجهة المستخدم المادية منخفضة المستوى. هناك فرصة منخفضة للرافعة المالية.
هذا صحيح جزئيًا. كما ترون في https://codesandbox.io/s/r1ov818nwm أنا فقط أقوم بلف List
PureComponent
. لا شيء آخر وهو يعمل على تسريع الدرج بعامل مهم. أود أن أدعي أن هذا صحيح لكل مكون ، على الأقل يستخدم {this.props.children}
. لقد قمت بإنشاء عرض توضيحي آخر: https://codesandbox.io/s/my7rmo2m4y
لا يوجد سوى 101 زرًا (نقي = خطأ) وأزرار ملفوفة في PureComponent (نقي = صحيح ، انظر من أين يتم استيراد الزر). نفس نتيجة اللعبة ، إذا قمت بالنقر فوق الزر "انقر" -:
زر عادي:
زر ملفوف (مع النفقات العامة وما إلى ذلك):
كما ترى ، هناك 637 مللي ثانية مقابل 47 مللي ثانية للأزرار العادية فقط! هل ما زلت تعتقد أن تحسين shouldComponentUpdate
(أو PureComponent
) لا يستحق كل هذا العناء؟ :)
تحرير: إصلاح الصياغة في البداية
oliviertassinarioreqizer لقد لاحظت الشيء المثير للاهتمام. يبدو أنه يمتد إلى PureComponent
ويؤدي بشكل أفضل مثل Component
مع
shouldComponentUpdate() {
return false;
}
تحرير: أعتقد أن هذا هو أحد التحسين الداخلي للتفاعل.
كما ترى ، هناك 637 مللي ثانية مقابل 47 مللي ثانية للأزرار العادية فقط! هل ما زلت تعتقد أن التحسين shouldComponentUpdate (أو PureComponent فقط) لا يستحق كل هذا العناء؟ :)
Bessonov إنه يوضح إمكانات المنطق الخالص. نعم ، يمكن أن يكون مفيدًا جدًا! إنه تحسين x13. لكنني لا أعتقد أنه قريب من ظروف الحياة الواقعية:
oliviertassinari كمطور رائع ، كيف يمكنك كتابة أشياء مثل هذه؟ لماذا تستخدم افتراضاتك الشخصية كحجج وليست حقائق؟ أعتقد أنني قدمت حقائق كافية أعلاه. فعلت كل شيء لأظهره ، لأنني أحب هذا المشروع وأريد المساهمة. إنه لا يكفى؟ حسنًا ، مزيد من الحقائق والافتراضات.
فقط لأجلك أقوم بتقليصه إلى 10 أزرار. 10! انها تعني أي 10 مكونات (أسوأ من ذلك: حاويات) من تباطؤ مادي-واجهة المستخدم أسفل التطبيق بأكمله حتى التطبيق غير صالح للاستخدام! تم اختباره على جهاز حقيقي مع Crosswalk 21 / chrome 51 بدون أي دواسة الوقود:
الزر العادي:
PureButton:
هذا لا يزال تحسن 8x! انه ضخم! هل يمكنك تخيل مدى أهمية هذا على الجهاز المحمول؟
بدلاً من 100 زر ، ستجد 10 أزرار على الأكثر في الصفحة. ومع ذلك ، ستجد 10 شبكات ، 10 X ، إلخ.
لقد استخدمت Button لأنه أحد أبسط المكونات! فإنه يدل على أن واجهة المستخدم، يتم تقسيم المواد من جهة نظر الأداء. الآن ، تخيل مكونات حاوية مثل AppBar ، Toolbar ، List ، Drawer! هذا أسوأ! تحصل بسرعة كبيرة على 20 مكونًا / حاوية في كل صفحة. ولأنك لا تنتهي صلاحية أي بطء على سطح المكتب / جهاز Mac القوي ، فهذا لا يعني أن واجهة المستخدم المادية ليست بطيئة بشكل لا يصدق.
رد فعل-intl ، فإن الاختيار بين الدعائم السابقة والجديدة سيكون دائمًا خاطئًا. سوف تضيع دورات وحدة المعالجة المركزية. لذا x13 -> x0.8
أرني مثالا على الأكوادوعلبة. لا أفهم لماذا يجب أن يحدث هذا. أنا متأكد من أن هذا يحدث فقط عند الاستخدام الخاطئ لمكونات التفاعل. ويظهر المثال الرسمي استخدامًا خاطئًا ، لأنه يبدو وكأنه رد فعل لمشتركي السياق المطبق. ولكن هناك الكثير من المكونات الأخرى التي تتوافق مع إرشادات التفاعل وأفضل الممارسات للبقاء في الأداء.
راجع للشغل: WithStyles تستهلك ما يصل إلى 2،27 مللي ثانية للزر الموجود على الجهاز المحمول. 8 مكونات وأنت أقل من 60 إطارًا في الثانية.
لماذا تستخدم افتراضاتك الشخصية كحجج ولا حقائق؟
ما الذي يجعلك تعتقد أنه افتراض شخصي؟ كنت أحاول أداء التفكير النقدي. من الناحية المفاهيمية ، فإن اجتياز الدعامة الإضافي سيؤدي إلى إبطاء الإصدار النقي مقارنة بالإصدار غير النقي ، وعليه تقليم شيء يستحق العناء. نفس السبب مثل # 5628 أو https://github.com/react-bootstrap/react-bootstrap/issues/633#issuecomment -234749417 أو https://github.com/reactstrap/reactstrap/pull/771#issuecomment -375765577
مع نقي:
بدون نقي:
الاستنساخ هو التالي.
oliviertassinari هل أنت متأكد من أن Codeandbox يجعل كل شيء مناسبًا للاختبار؟ لأن نتائجي مختلفة جدًا:
بدون نقاء (حتى بدون دواسة الوقود يكون بطيئًا):
نقي (بعد التغيير إلى صحيح وحفظ أحصل على عنوان url جديد لـ codeandbox):
نظرًا لأنه لا يتحقق من تغييرات السياق ويفرض أيضًا على المستخدمين التأكد من أن جميع المكونات الفرعية "نقية" أيضًا ، لا أعتقد أن هذا مناسب لهذه المكتبة. يجب أن تكون هذه المكتبة مرنة قدر الإمكان وأعتقد أن هذا سيجعل استخدامها أكثر صعوبة.
أنا أرى النقطة. لكنها مقايضة مثيرة للاهتمام للغاية. من ناحية ، يجب أن تكون واجهة المستخدم المادية "مرنة قدر الإمكان" ، ولكن على الجانب الآخر ، فإن الأداء الحالي يجعلها "غير قابلة للاستخدام" على الإطلاق.
قد يكون عليك التفكير في تقديم نسخة نقية وغير نقية من المكونات. أفعل ذلك الآن لكي يحصل تطبيقي على بعض الأداء القابل للاستخدام حتى على سطح المكتب.
Bessonov لم يتم حفظ الرموز والصندوق بشكل صحيح. آسف. كان يفتقد الفرق التالية. لقد قمت بتحديث الرابط:
<Button>
+ <i>
Button
+ </i>
</Button>
لا أفهم لماذا يجب أن تؤدي إلى نتائج مختلفة؟ أحصل على مخطط أفضل ، لكن الإصدار غير النقي أبطأ بشكل ملحوظ.
تحرير: حسنًا ، فهمت. حاول معرفة ما يحدث ...
حسنًا ، فهمت الآن. فقط نفس "الكائن الجديد في كل عرض" - أي شيء. لم ألاحظ ذلك من قبل. في بعض الحالات ، يمكن تحسينه باستخدام الثوابت من خلال ملحق بابل الإضافي تلقائيًا.
حسنًا ، فأنت تعلم ذلك بالفعل! : D على الرغم من عدم وجود فائدة كبيرة من تلقاء نفسها (لقد أظهرت حوالي 7٪) ، إلا أنها لا تزال مربحة في الختام مع المكونات النقية لتجنب بعض العيوب التي ذكرتها أعلاه. لقد اختبرته الآن مع Pure Wrapper + babel plugin + Production build وهو سريع مثير للإعجاب على نفس الجهاز المحمول!
كما قلت ، أعتقد أنه من الأفضل تقديم كلاهما - مكونات غير نقية للمرونة ومكونات نقية (الأغلفة كافية لإبقائها بسيطة وقابلة للصيانة) للأداء. لكن بالنسبة لي ، يمكنني التعايش مع مكونات نقية فقط ، لأن تحسين الأداء الكلي أكبر بكثير من عيوب الأداء. أو أفضل: لا يمكنني استخدام واجهة المستخدم المادية بدون مكونات نقية.
حسنًا ، في الوقت الحالي أنتظر المزيد من المدخلات حول هذا الموضوع وإنشاء أغلفة خاصة في تطبيقي)
شكرا على الرؤى!
لم أسمع أبدًا عن العناصر الثابتة للتحويل والتفاعل والتي يتم استخدامها بالفعل وتكون مفيدة حقًا. لا بأس من التحسين الجزئي العشوائي ، لكن في الممارسة العملية نادرًا ما تكتب رمزًا بسيطًا بما يكفي للحصول على الكثير منه. على الرغم من أنني أفترض أنه لن يكون تحسينًا سيئًا لجميع مكونات رمز نمط SVG مثل <Add />
.
ألقِ نظرة على هذا المثال (انقر على الإضافات في الجانب ، وابحث عن "رد فعل ثابت" وانقر على مربع الاختيار الموجود على "عناصر تحويل - تفاعل - ثابت") وستلاحظ أنه بالكاد تم تحسين أي شيء:
InputAdornment
إلى الأعلى ، رائع.InputProps={{startAdornment: ...}}
مضمنًا ويخلق كائنًا جديدًا في كل عرض مما يجعل PureComponent مستحيلًا.classes={{label: classes.runButtonLabel}}
يجعل من المستحيل على PureComponent تحسين زر التشغيل.أنا شخصياً أحب PureComponent وأحاول استخدامه في كل مكان على الإطلاق وتحسين الأشياء بقدر ما أستطيع حتى يعمل. ولكن لا يبدو أن MUI مصنوع على الإطلاق بطريقة تعمل PureComponent.
*Props
مثل InputProps
نمطًا أساسيًا لكيفية عمل MUI. إنها ليست مجرد طريقة متقدمة لتعديل الأجزاء الداخلية من MUI عندما تحتاج إليها ، بل هي طريقة تستخدم بانتظام في حالات الاستخدام البسيطة. غالبًا ما يجعل هذا النمط أي مكون طرفية يمكن تحسينه بشكل طبيعي في الوضع النقي ، غير قابل للتحسين.classes={{...}}
لا يعمل أيضًا مع PureComponent وهو طريقة لإضافة أي تصميم للأشياء في MUI. (والقول بأن استخدام classes={classes}
ليس عمليًا بأي حال من الأحوال لأن المستهلك الواقعي من المحتمل أن يكون له اسم فئة مختلف عن الفئة الداخلية للمكون ومن المحتمل أن يتضمن classes
أيضًا فئات تهدف إلى تصميم عناصر أخرى في نفس المكون المستهلك)إذا أردنا تحسين أي شيء ، فيجب التعامل مع هذه المشكلات الأساسية ، وإلا فلن يؤدي السماح للأشخاص ببساطة بتمكين MUI للوضع الخالص إلى تحسين كبير على الإطلاق. يمكنني التفكير في احتمالين.
shallowMemoize
والتي تستخدم this
المحلي و key
(لذا يمكنك استخدامها على أجزاء مختلفة من البيانات) يحفظ البيانات طالما أنها سطحية متساويةshallowMemoize
في 1. وهي تمريرها إلى render()
مع مصمم. بهذه الطريقة يمكننا تمرير عرض جديد لكل عرض وبدلاً من الحاجة إلى key
يمكننا فقط التحقق مما إذا كان يجب إعادة استخدام أي من الكائنات المحفوظة في الذاكرة من العرض الأخير ، ثم تجاهل جميع القيم القديمة.المشكلة بالطبع هي أن هذا يجعل المستهلكين أكبر بكثير وأكثر فوضوية ويتطلب المنطق أن يتم رفعه يدويًا إلى الأماكن التي يكون فيها بعيدًا عن الكود الذي يستخدمه.
import {createSelector} from 'reselect';
class FormPage extends PureComponent {
state = { example: '' };
change = e => this.setState({example: e.target.value});
submit = () => {
console.log('Submit: ', this.state.example);
};
runButtonClasses = createSelector(
props => props.classes.runButtonLabel,
runButtonLabel => ({runButtonLabel}));
render() {
const {title} = this.props;
const {example} = this.state;
return (
<form>
{title}
<TextField
InputProps={this.shallowMemoize('a', {
// This example assumes use of transform-react-constant-elements to make this object always the same
startAdornment: <InputAdornment position="start">Kg</InputAdornment>,
}}}
onChange={example}
value={example} />
<Button classes={this.runButtonClasses(classes)}>Run</Button>
<Button onClick={this.submit}>Submit</Button>
</form>
);
}
}
// ...
<strong i="6">@withShallowMemoize</strong>
render(memo) {
const {title} = this.props;
const {example} = this.state;
return (
<form>
{title}
<TextField
InputProps={memo({
startAdornment: <InputAdornment position="start">Kg</InputAdornment>,
}}}
onChange={example}
value={example} />
<Button classes={memo(classes)}>Run</Button>
<Button onClick={this.submit}>Submit</Button>
</form>
);
}
إذا كانت هذه هي الطريقة الموصى بها لاستخدام MUI ، فقد لا نحتاج حتى إلى وضع خالص. كما ترى ، بمجرد أن تبدأ في صنع مكونات مساعدة صغيرة لحالات الاستخدام الشائعة ، يمكن أن تكون هذه المكونات نفسها مكونات نقية بسهولة. في المثال WeightTextField
الآن لن يتم إعادة عرضه أبدًا طالما أن value
لا يزال هو نفسه ، متخطيًا تمامًا مع الأنماط ، أي عمل لحفظ الذاكرة ضروري لـ InputProps ، أو إعداد InputAdornment. وعندما يتغير value
، يتعين علينا إعادة تقديم TextField على أي حال حتى لا يهم InputProps={{...}}
غير الخالص.
أنا بخير مع هذا المسار. أنا أحب المكونات الدقيقة من الناحية النظرية ؛ على الرغم من أنني أكره كل بناء جملة / نمط صالح حاليًا لكتابتها والتي يمكنني التفكير فيها. لا أريد MyComponent = enhance(MyComponent)
، أريد تزيينها ، لكن لا يمكنك تزيين أي من الطرق القصيرة لكتابة مكون صغير. أنا أيضًا لا أحب تحويل import {TextField} from 'material-ui';
إلى import WeightTextField from '../../../ui/WeightTextField
؛ `.
شبيبة
دع WeightTextField = ({unit، InputProps، ... props}) => (
InputProps = {{
بداية الزينة:
... InputProps
}}
عند التغيير = {مثال}
القيمة = {مثال} />
) ؛
WeightTextField = نقي (WeightTextField) ؛
RunButton = تكوين (
withStyles (المظهر => ({
ضع الكلمة المناسبة: {
وزن الخط: '800'،
} ،
})) ،
نقي
)(زر)؛
const SubmitButton = pure (Button) ؛
فئة FormPage توسع المكون {
الدولة = {مثال: ''} ؛
change = e => this.setState ({example: e.target.value}) ؛
إرسال = () => {
console.log ('Submit:'، this.state.example) ؛
} ؛
يقدم - يجعل() {
const {title} = this.props؛
const {example} = this.state؛
return (
<form>
{title}
<WeightTextField
unit='Kg'
onChange={example}
value={example} />
<RunButton>Run</RunButton>
<SubmitButton onClick={this.submit}>Submit</SubmitButton>
</form>
);
}
}
""
لدي حالة استخدام حيث أحتاج إلى عرض 500-2000 مربع اختيار على صفحة في قائمة كبيرة. باستخدام مربعات اختيار المستعرض الأصلي ، يكون الأداء جيدًا ، ولكن باستخدام المكون <Checkbox>
، يكون الأداء ضعيفًا للغاية ويتوسع خطيًا مع عدد مربعات الاختيار على الصفحة. مثال: https://codesandbox.io/s/5x596w5lwn
أنا أستخدم mui @ next - هل هناك بعض الإستراتيجيات التي يمكنني استخدامها _now_ لجعل هذا عمليًا؟
تضمين التغريدة
أولاً ، لا تفعل ما يلي. سيؤدي هذا إلى إنشاء معالج جديد في كل مربع اختيار كل تصيير ، مما سيؤدي إلى تحسين أي تحسينات PureComponent تحاول القيام بها.
handleChange = index => event => {
this.setState({
ثانيًا ، قم بإنشاء مكون صغير خاص بك لتغليف Checkbox وجعل هذا المكون خالصًا. هذا له فائدة إضافية يمكنك إضافتها في أي خصائص مشتركة لجميع مربعات الاختيار الخاصة بك. ونظرًا لأن لديك مشكلة شائعة تتمثل في الحاجة إلى معالج حدث تغيير مختلف لكل عنصر ، فيمكننا استخدام مكون فئة والقيام بذلك في المكون بدلاً من حاوية القائمة.
إذا أردنا تحسين أي شيء ، فيجب التعامل مع هذه المشكلات الأساسية ، وإلا فلن يؤدي السماح للأشخاص ببساطة بتمكين MUI للوضع الخالص إلى تحسين كبير على الإطلاق. يمكنني التفكير في احتمالين.
dantman تم إجراء اختيارات واجهة برمجة التطبيقات هذه من أجل تحسين DX قدر الإمكان أثناء محاولة أن تكون سريعًا بدرجة كافية.
بدلاً من محاولة تحسين InputProps ، والفئات ، وما إلى ذلك ... نشجع الأشخاص على صنع مكونات دقيقة لجميع أغلفة استخدامهم
نعم فعلنا. نمط الالتفاف هو بالتأكيد الطريقة المشجعة لتخصيص المكتبة. يمكن تمديده لتطبيق تحسينات الأداء. إنه أسهل في أرض المستخدم حيث يكون تباين استخدام المكونات أقل بكثير. يمكننا حتى إضافة سؤال أسئلة وأجوبة أو قسم دليل حول هذه النقطة في الوثائق.
نعم فعلنا. نمط الالتفاف هو بالتأكيد الطريقة المشجعة لتخصيص المكتبة. يمكن تمديده لتطبيق تحسينات الأداء. إنه أسهل في أرض المستخدم حيث يكون تباين استخدام المكونات أقل بكثير. يمكننا حتى إضافة سؤال أسئلة وأجوبة أو قسم دليل حول هذه النقطة في الوثائق.
نعم. في هذه الحالة:
../../../../ui/Foo
إلى شيء مثل something-local/Foo
) يمكن استخدامه لصنع استخدام سلسلتك المحلية الخاصة من المكونات الدقيقة التي تغلف MUI بطريقة لطيفة مثل استخدام import {TextField} from 'material-ui';
ولا تشعر وكأنها تراجع في سهولة المطور .@ دانتمان رائع ، شكرا لك.
لقد احتجت عدة مرات لتطبيق sCU بسبب بطء أسلوب withStyles (أو بالأحرى JSS). لا أعرف كود JSS ولكن يبدو أنه يمكن تحسينه كثيرًا. عادةً ما أستخدم المكونات المصممة أو البراقة ، وبالتالي ينتهي بي الأمر مع JSS وواحد من الآخر في التطبيق وكلاهما يتفوقان على JSS.
على الرغم من أن هذه الحالات قد تكون مزعجة بعض الشيء ، إلا أنه من السهل حلها باستخدام مستوى التطبيق أو تحديثات الحالة الأكثر ذكاءً. لا يزال يتعين عليّ رؤية مكون MUI واحد يكون بطيئًا بدرجة كافية ليكون مشكلة ، ولا يزال يتعين عليّ أيضًا ترميز داخل MUI لأستغرق وقتًا طويلاً.
كي لا نقول إنه لا يمكن أن يكون أسرع وأكيد أنه سيكون أجمل إذا كانت هناك حاجة إلى إشراف أقل ولكن على الأقل لما أراه سيكون من الأفضل قضاء بعض الوقت في تحسين JSS مباشرة من MUI في هذه الحالة.
Pajn شكرا على ردود الفعل. سيكون من الرائع حقًا أن نرى بعض المواقف التي يكون فيها أداء withStyles مشكلة أو حيث يتفوق عليه أداء المكونات المصممة.
هل قام أي شخص بفحص هذا الريبو https://github.com/reactopt/reactopt ؟
$ click - button (text: مقالات
) => CssBaseline,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,ScrollbarSize,TransitionGroup,TouchRipple,Ripple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,Main,ScrollbarSize,TransitionGroup,TouchRipple,Ripple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple
تقوم هذه المكونات بإعادة عرض غير ضرورية فقط بنقرة بسيطة ، فلماذا لا تحاول إجراء دورة حياة تحديث المكون؟
@ nimaa77
هل قام أي شخص بفحص هذا الريبو https://github.com/reactopt/reactopt ؟
لا، وأنا استخدم عادي لماذا-فعل-لك التحديث والكروم / الرد ديف قدرات الأدوات.
تقوم هذه المكونات بإعادة عرض غير ضرورية فقط بنقرة بسيطة ، فلماذا لا تحاول إجراء دورة حياة تحديث المكون؟
انظر المناقشة أعلاه. هذا لا يصلح لكل حالة استخدام. بالنسبة لي ، يبدو أن واجهة المستخدم المادية يجب أن تقدم كلاً من - إصدارات نقية وغير نقية من المكونات. أرى تحسنًا هائلاً في الأداء بمكونات نقية.
تضمين التغريدة
ألقِ نظرة على هذا المثال (انقر على الإضافات في الجانب ، وابحث عن "رد فعل ثابت" وانقر على مربع الاختيار الموجود على "عناصر تحويل - تفاعل - ثابت") وستلاحظ أنه بالكاد تم تحسين أي شيء:
هذه مجرد طريقة واحدة لمعالجة هذه المشكلة. هناك أيضًا خيارات أخرى وإضافات وتحسينات أخرى مصنوعة يدويًا. لا تفهموني خطأ ، لكنني لست مهتمًا بالمناقشات النظرية التي تكون التحسينات جيدة أو سيئة. أنا مهتم بالتدريب العملي على التحسين الذي يعمل. على الأقل في الإعداد الخاص بي. كل ما كتبته أعلاه يعمل بالنسبة لي ويجعل تطبيقي قابلاً للاستخدام على الأقل على الأجهزة المحمولة ذات المستوى المنخفض. على الرغم من أنني مجبر على إجراء المزيد من التحسينات مثل إعادة ترتيب أشجار المكونات ، إلا أن الأداء المحقق لن يكون ممكنًا بدون المكونات النقية والتحسينات التلقائية الأخرى. ونعم ، أقوم بملف التعريف والتحسين كثيرًا لإنجاز ذلك.
Bessonov ربما يمكننا استخدام الدعامة لعمل طريقة shouldComponentUpdate لإجراء مقارنة سطحية (https://reactjs.org/docs/shallow-compare.html) أو إرجاع القيمة false دائمًا ،
لن يؤدي ذلك إلى زيادة حجم الحزمة مع نسختين من المكونات (نقية وعادية)
lucasljj لا أتوقع زيادة كبيرة في حجم الحزمة إذا تم ذلك كغلاف لمكون ذي حالة مثل المذكورة أعلاه. راجع أيضًا الملفات الشخصية أعلاه: المكونات النقية فقط أسرع من return false;
في جامعة كاليفورنيا.
تكمن المشكلة في المكونات أو المكونات الصافية التي تطبق وحدة التحكم عن بعد ، إذا كنت تستخدم مكونًا غير نقي بداخله أو children
. انظر البيانات أعلاه. هناك مشكلة أخرى يجب معالجتها وهي تبديل السمة. لم يتم اختباره ، لكنني أعتقد أنه يمكن التغلب على هذا على الأقل باستخدام واجهة برمجة تطبيقات السياق.
تعتبرbossonov Pure Components من العناصر التي يجب أن تكون افتراضية للتفاعل وليس لأنها جاءت متأخرة إلى الحفلة. لكنني أوافق على أن معظم الناس سيصنعون أغلفة نمط إعادة تشكيل تخفف من عدم وجودها على الشجرة الفرعية
المشكلة التي تشير إليها فيما يتعلق بالمكونات النقية والأطفال ، تحدث فقط إذا لم تنتشر الدعائم ذات المستوى الأعلى للأطفال. سيؤدي كل تغيير خاص بالدعم أو الحالة إلى تشغيل عرض خلال الشجرة الفرعية وصولاً إلى المستوى الذي لا ينشره العنصر.
لأن فكرة المكونات النقية هي أنه يتم عرضه عند كل تغيير في الدعامة أو الحالة. لا أعرف العناصر الداخلية بشكل وثيق ولكني كنت أتساءل في أنه لا يمكنك استخدام خاصية تغيير لكل مكون تمررها إلى كل طفل. يمكنك حتى استخدام واجهة برمجة تطبيقات السياق الجديدة لهذا الغرض حتى لا تضطر إلى تمرير دعامة عبر الشجرة بأكملها.
تضمين التغريدة
سيكون الأداء هو إصدار التركيز بعد الإصدار 1.
رائع ، تم إصدار v1 :) هل هناك أي فكرة متى يجب معالجة الأداء؟ لقد لاحظت أن هذه المشكلة ليست جزءًا من مرحلة ما بعد الإصدار 1.
Bessonov أعتقد أنه سيكون من الرائع قضاء بعض الوقت في تحديث ROADMAP. بخصوص الأداء. لدي شيئان في ذهني قابلين للتنفيذ ، لكني آمل أن أكتشف المزيد:
style = f(props)
(حسنًا ، نحن لا ندعمه بعد: # 7633). يمكننا تنفيذ قدرة تخزين مؤقت فعالة للغاية ، مما يقلل التكلفة بنسبة تقترب من 0٪ للطلبات المتكررة. قد أعمل على ذلك للمكتب إذا كان أداء SSR يضر بمقاييس أعمالنا.شكرا لعناوين المواقع.
أتفق تمامًا مع 1 والمرتبط # 4305 أعلاه.
ستكون تحسينات وقت التجميع رائعة ومن وجهة نظري يجب أن تكون مفضلة ، لأنها يمكن أن تحسن التحميل والعرض لأول مرة.
شيء آخر هو نوع من التوثيق أو مثال على مشروع كيفية استخدام mui (و babel وما إلى ذلك) للحصول على أداء أفضل.
لا أعرف ما إذا كان يمكن استخدام jss-cache .
سيتمكن خط أنابيب المعالجة المسبقة ISTF + من حلق بعض مللي ثانية.
في يوم السبت ، 19 مايو ، 2018 ، الساعة 19:06 ، كتب أنطون بيسونوف [email protected] :
شكرا لعناوين المواقع.
أتفق تمامًا مع 1 والمرتبط # 4305
https://github.com/mui-org/material-ui/issues/4305 أعلاه.
- يمكن أن تساعد SSR في تحميل الصفحة الأولى ، لكنها لا تساعد في البطء
التقديم أو كوردوفا. بينما يمكنني شخصيًا تجاهل أول مرة يتم تحميلها
سطح المكتب أو حتى المحمول ، لا يزال العرض البطيء يؤثر على الأجهزة المحمولة بعد ذلك
أول تحميل.ستكون تحسينات وقت التجميع رائعة ومن وجهة نظري يجب أن تكون
تكون مفضلة ، لأنها يمكن أن تحسن التحميل والعرض لأول مرة.شيء آخر هو نوع من التوثيق أو مثال على مشروع كيفية استخدام mui
(و babel وما إلى ذلك) للحصول على أداء أفضل.لا أعرف ما إذا كان http://cssinjs.org/jss-cache؟v=v3.0.0 ذاكرة التخزين المؤقت لـ jss
تستخدم.-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/mui-org/material-ui/issues/10778#issuecomment-390418709 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/AADOWGrCxNGqrT4MijiX8r9Ad32z6RsJks5t0FEtgaJpZM4S4woq
.
قد يكون مفيدًا في إعداد المعايير:
https://github.com/A-gambit/CSS-IN-JS-Benchmarks/blob/master/RESULT.md
يبدو أن Oh React-jss (الذي تستخدمه material-ui) بطيء جدًا
janhoeck ليس كذلك ، ولن تكون قادرًا على إثبات خلاف ذلك ، أنا متأكد.
kof أنا حقًا . في الواقع ، الأداء العام لواجهة المستخدم المادية ليس لامعًا.
4x-6x بالمقارنة مع أفروديت بطيء حقًا
Bessonov المنهجية المعيارية
https://twitter.com/necolas/status/954024318308007937؟lang=fr
النتائج في متصفحي:
⚠️ مع الشك
الأداء العام لواجهة المستخدم المادية ليس لامعًا
قد نكون مقيدين تمامًا بـ React نفسها وتكلفة المكونات.
Bessonov كل ما استخدمته للتحقق من الأداء ، عندما يتعلق الأمر oliviertassinari الذي نشره هو الأكثر واقعية.
فيما يتعلق بأداء MUI ، يمكنك أن تصبح أسرع عندما لا تستخدم أي تجريد على الإطلاق ، ولكن هذا ليس هو الهدف. MUI التالي سريع جدًا. إنه سريع جدًا بحيث لا تقلق أبدًا بشأن أدائه ما لم تفعل شيئًا خاطئًا تمامًا أو أساءت استخدام المكتبة.
kof لا ، MUI ليس سريعًا بشكل افتراضي. نحن مضطرون إلى تنفيذ الحلول للحصول على أداء مقبول. فقط على وجه اليقين: ألا ترى أن الأمر يتعلق بالأجهزة المحمولة وليس لأجهزة Mac المتطورة؟
لا تقلق أبدًا بشأن أدائها ما لم تفعل شيئًا خاطئًا تمامًا أو أساءت استخدام المكتبة
حسنًا ، فيما يلي بعض أمثلة Codeanbox. إذا استخدمنا مكونات MUI في حاوية وحفظنا قيم الإدخال في حالة الحاوية ، كما هو موضح في العروض التوضيحية للمكونات ، فسيصبح غير قابل للاستخدام بسرعة كبيرة. التفاف في PureComponent ، واستخدام مكونات غير خاضعة للرقابة ، وإعادة ترتيب الشجرة ، والعناصر الثابتة ، وحفظ الذاكرة ، وما إلى ذلك لمساعدتنا في الحفاظ على بعض الأداء المقبول. نرحب بك لإظهار كيفية استخدام MUI بشكل صحيح ، للحصول على نتائج أفضل ، على سبيل المثال في (أجهزة الصراف الآلي لم نعد نستخدم الدرج):
https://codesandbox.io/s/r1ov818nwm
oliviertassinari شكرا على الرابط. فيما يلي نتائج Chrome 66 على جهاز nexus 4. كما ترى ، كانت النتائج أقل بـ 10 مرات. أعتقد أنه في Crosswalk 21 / chrome 51 يمكن أن يكون أبطأ قليلاً:
قد نكون مقيدين تمامًا بـ React نفسها وتكلفة المكونات.
IMHO ليس بالضرورة ، كما ذكر آخرون أيضًا. يعد كل عرض يتم تجنبه مكسبًا كبيرًا للأداء والبطارية. لا تنس ، الأداء هو النقطة الثالثة في خريطة الطريق الخاصة بك: +1:
انظر إلى الأمر بهذه الطريقة: إذا كان ما تفعله باستخدام cssinjs بطيئًا جدًا على جهاز محمول ، فلا يجب أن تستخدمه في هذا التفاعل ومعظم الأشياء الأخرى أيضًا. إذا كان cssinjs يبطئك ، فإن مكون التفاعل يبطئك أكثر بكثير. تحتاج إلى إعادة التفكير في تجريد المستوى أو تطبيق التحسينات.
oliviertassinari هو ذلك evtl. من الممكن أن يقوم برنامج تضمين mui بإعادة عرض أنماط jss عند التحديث؟ قد يكون هناك بعض التسرب الذي يحتمل أن يؤدي عملاً غير ضروري.
kof
انظر إلى الأمر بهذه الطريقة [...]
أرى وجهة نظرك. لكن مكونات التفاعل والتفاعل (النقية) ليست عنق الزجاجة من تلقاء نفسها وتعمل بشكل جيد للغاية. على سبيل المثال ، لا تستخدم MUI PureComponent (مع الإيجابيات والسلبيات الموضحة أعلاه) ، لكنها أكثر أمانًا لحياتنا. ذكر oliviertassinari أن هناك فرصة للحصول على أداء أفضل باستخدام ذاكرات التخزين المؤقت أو المترجم المسبق.
لا تفهموني خطأ ، فأنتم رفاق رائعون وأنا سعيد حقًا بكل إصدار MUI: التصفيق: لكنك تحتاج إلى التفكير في الأداء أيضًا ، لأنه لا يقوم كل مستخدم بزيارة مواقع الويب من خلال سطح المكتب عالي الأداء .
إذا لم يكن التفاعل يمثل عقبة في الأداء وأنت متأكد من ذلك ، فلن يكون JSS أيضًا. الشيء الوحيد الذي يمكنني تخيله والذي يحتاج إلى التحقق من صحته إذا كان هناك بعض الأعمال غير الضرورية الجارية ويتم إعادة إنشاء css عند التحديث.
المكون النقي هو شيء يجب أن تستخدمه في كود مستوى التطبيق الخاص بك ، إذا كنت بحاجة إلى تحسين. لا يتعين على MUI القيام بذلك ، فهي مكتبة عامة ولا ينبغي أن تقدم أي افتراضات. PureComponent ليس جيدًا دائمًا.
لقد نظرت JSS في الأداء منذ اليوم الأول وقضيت ساعات لا حصر لها في التحسينات الدقيقة.
هذا سخيف. لا يمكنني إيقاف إعادة عرض مكونات واجهة المستخدم المادية في كل تفاعل فردي. لا يهم ما أفعله ، عشية شيء بسيط مثل هذا:
class RowText extends Component {
shouldComponentUpdate = (nextProps, nextState) => {
return false;
};
render() {
const { title, artist } = this.props;
return <ListItemText primary={title} secondary={artist} />;
}
}
تقوم المشغلات بإعادة تصيير عناصر الطباعة الأساسية. كيف يكون هذا ممكن حتى ؟
مرحبًا ، هذا يحدث فقط مع عنصر القائمة والقائمة. لماذا ا ؟ هل هناك شيء يمكنني القيام به؟
@ danielo515 من الصعب معرفة ذلك بدون المثال الكامل. تستخدم مكونات List
أيضًا السياق ، لذا إذا كنت تقوم بتغيير هذه القيمة أيضًا ، فسيؤدي ذلك أيضًا إلى تشغيل عمليات إعادة العرض.
أفهم أن @ eps1lon. ومع ذلك ، هل يمكنك أن توضح كيف يمكن أن يحدث تغيير في السياق؟ أنا لا أنقل أي شيء إلى عنصر القائمة ، بل أقوم فقط بضياع الأطفال بداخله.
@ danielo515 بشكل أساسي في كل مرة يتم فيها عرض List
. أتاحت واجهة برمجة تطبيقات السياق الجديدة بعض استراتيجيات التحسين التي يمكننا استكشافها من خلال حفظ قيمة السياق.
تتفاعل واجهة برمجة تطبيقات السياق حاليًا مع تشغيل عرض على كل مستهلك إذا تغيرت القيمة WRT إلى مساواة صارمة. نظرًا لأننا ننشئ عنصرًا جديدًا في كل استدعاء تصيير لـ List
سيُعرض كل مستهلك أيضًا.
لذلك في الوقت الحالي ، سيكون من السهل تعزيز الأداء هو التفاف List
بحيث لا يتم عرضه بشكل متكرر. أود أن أوصي بإجراء المعايير أولاً على الرغم من ذلك أو الخروج من العرض في وقت سابق. لا ينبغي أن تكون مكالمات التقديم المتكررة Typography
بهذا السوء.
مكونات التغليف بـ React.memo
تعمل بشكل جيد لأي شيء بدون أطفال. لدي نموذج به 3 ExpansionPanel وحوالي 14 FormControl وهو متأخر على سطح المكتب.
بدون حل لمشكلات الأداء هذه ، لن أتمكن من الاستمرار في استخدام واجهة المستخدم المادية
prevostc من الصعب معرفة الخطأ بدون مثال.
prevostc بدون رؤية إعادة إنتاج الأكواد ، لا يمكننا ولا يمكنك معرفة ما إذا كان هذا مرتبطًا بهذه المشكلة
prevostc قم
على سبيل المثال ، أنشئ مكوّنًا خالصًا / مذكّرًا MyExpansionPanel
يأخذ دعائم البيانات / الأحداث ولكن ليس الأطفال ويكون مسؤولاً عن تقديم لوحة توسيع واحدة. ثم استخدم هذا <MyExpansionPanel ... />
لعرض كل من لوحات التوسيع الخاصة بك. ثم ستقتصر عمليات إعادة العرض على لوحة توسيع واحدة (أو اثنتين عند الانتقال بين اثنين).
oliviertassinarikofdantman
في ما يلي نسخة من الرموز والصندوق لمشكلة الأداء الخاصة بي: https://codesandbox.io/s/yvv2y2zxxx
إنه نموذج به 20 حقلاً تقريبًا (ليس من غير المألوف) وستواجه بعض التأخير في إدخال المستخدم. على الأجهزة الأبطأ ، لا يمكن استخدام هذا النموذج.
تأتي مشكلة الأداء من إعادة التصيير الهائلة لمدخلات المستخدم ، لكن تغليف مكونات MUI في مكون نقي (React.memo) لا يفعل شيئًا لأن كل شيء هنا له أطفال وأطفال ، وهذا سيجبر إعادة تصيير AFAIK (المصدر: https: // React-api.html#reactpurecomponent)
فيما يلي بعض لقطات الشاشة لمعياري اليدوي ، واحدة بدون أي تحسين ، وواحدة مع كل شيء محفوظ والأخرى تستخدم مكون إدخال مخصصًا مع حالة محلية لتجنب تعيين الحالة على النموذج بالكامل كثيرًا.
في كل تكوين ، تستغرق تسوية إدخال المستخدم حوالي 60 مللي ثانية (أعلى بكثير من 16 مللي ثانية أحتاج إلى عرضها بمعدل 60 إطارًا في الثانية.
يرجى ملاحظة أنني سأعلم بكل سرور أنني فعلت شيئًا خاطئًا لأنني أحب MUI وسأكون حزينًا إذا لم يكن هناك حل سهل <3
dantman كيف يمكنك كتابة ExpansionPanel
لا تأخذ أي React.ReactNode
كمدخلات (أطفال أو دعائم)؟ إذا كنت تقصد أنه يجب أن أكتب مكونًا محددًا لكل لوحة في تطبيقي ، فهذا غير ممكن لسوء الحظ ، لدي الكثير منهم.
dantman كيف يمكنك كتابة
ExpansionPanel
لا تأخذ أيReact.ReactNode
كمدخلات (أطفال أو دعائم)؟ إذا كنت تقصد أنه يجب أن أكتب مكونًا محددًا لكل لوحة في تطبيقي ، فهذا غير ممكن لسوء الحظ ، لدي الكثير منهم.
نعم ، بدلاً من إنشاء مكون ضخم واحد باستخدام شجرة متداخلة بعمق من الألواح ، تفصل أجزاء لوحة التوسيع إلى مكونات. من المستحيل تحسين الأشجار الضخمة من هذا القبيل.
انه ليس مستحيلا. مكونات التفاعل خفيفة الوزن للغاية. قم بنسخ ولصق كتلة من التعليمات البرمجية من مكون ضخم إلى وظيفة وتكون على وشك الانتهاء ، بعد ذلك عليك فقط ربط الدعائم. وطالما أنك تستخدم React.memo هذه الوظيفة وتجنب تمرير الأشياء التي تكسر التحسين الخالص للدعائم ، فسيتم تحسين الأشياء بسهولة تامة.
تذكر ، إذا كنت تقوم بإنشاء مكون صغير لكسر جزء من مكون ضخم. لا يجب أن يكون شيئًا معقدًا بملفه الخاص والتحقق من صحة الخاصية. يمكن أن يكون مكونًا وظيفيًا بسيطًا في نفس الملف مثل المكون المستخدم فيه بدون propTypes. على سبيل المثال ، يمكنك إنشاء مكونات صغيرة لا تتوفر إلا للمكون في نفس الملف مثلها.
نعم ، واجهة المستخدم المادية أبطأ قليلاً من عناصر dom ذات المستوى المنخفض. ولكن حتى لو كان MUI Input
أبطأ input
الخام وأصبحت الأمور بطيئة جدًا بعد 100. ثم لا تزال لديك مشكلة حتى بدون MUI لأنه حتى لو كان أسرع بـ 10 مرات من الخام input
سيجعل الموقع بطيئًا بنفس القدر إذا كان لديك 1000 منهم. لا يمكنك استخدام مكونات أحادية متجانسة في React حتى عندما لا تستخدم MUI. تحتاج إلى تقسيم تطبيقك إلى أجزاء ذات حجم معقول حتى يتمكن React من تحديد الحدود التي يمكنه تحسينها.
prevostc إليك العرض التوضيحي المحسّن عن طريق تقسيم لوحة التوسيع إلى مكون صغير من نفس الملف. كما ترى ، تتم إعادة عرض لوحة توسيع واحدة فقط عند تحديث أحد المدخلات. لا يضيع الوقت في إعادة عرض لوحات التوسع غير ذات الصلة. إذا أردت أن أفعل شيئًا مشابهًا للمدخلات التي تشترك في نمط مماثل ، مما يؤدي إلى عدم إعادة تقديم المدخلات غير ذات الصلة أيضًا.
سألاحظ أن هذا ليس مجرد نمط تحسين جيد ، إنه نمط ترميز جيد. في الكود الحقيقي ، حيث لا تقوم بإنشاء مصفوفة من المدخلات ولكن تكتبها صراحة بأسماء وتسميات وأغراض محددة. لا يؤدي العثور على الحدود والأنماط المتكررة إلى تحسين الأشياء فحسب ، بل يقلل أيضًا من جعل الكود المعياري أكثر جفافاً وقابلية للقراءة. على سبيل المثال ، بدلاً من InputWrapper
المحتمل أن أقوم بتقسيم FormControl + InputLabel + FormHelperText + Input إلى مكون SimpleTextInput محلي صغير. وهو ما لن يؤدي فقط إلى تحسينه (مما يؤدي إلى عدم إعادة عرض المدخلات غير ذات الصلة) ولكنه يعني أيضًا أن الكود لا يحتاج إلى تكرار النموذج المعياري الإضافي.
من خلال قراءة هذا ، توصلت إلى استنتاج مفاده أنه من أجل تحسين mui تحتاج إلى إنشاء مكونات محددة أصغر. هذا شيء أدركته بالفعل وحاولته بنجاح. ومع ذلك ، فقد فهمت أيضًا أنه لا توجد طريقة لتحسين مكونات القائمة لأن واجهة برمجة التطبيقات للسياق تغير جميع عناصر الإدخال.
يعتبر
حسنًا ، إليك اختبار تحمّل محدث https://codesandbox.io/s/wz7yy1kvqk
أتفق مع dantman على هذه النقطة العامة https://github.com/mui-org/material-ui/issues/10778#issuecomment -449153635 لكنني لم أكن أتوقع مثل هذه المشكلة في الأداء مع هذه الكمية المنخفضة من المكونات ، لكنني تحمل معها لي كما وجدت مصدر مشكلة الأداء الخاصة بي.
بالإشارة إلى بعض التعليقات السابقة في هذا الموضوع ، أضفت مربع اختيار في اختبار التحمل لإزالة جميع المكالمات إلى withStyles
وتوصلت إلى استنتاج مفاده أن JSS سريع وليس مصدر مشكلة الأداء (كما أشار kof في https://github.com/mui-org/material-ui/issues/10778#issuecomment-396609276).
بالنسبة لحالة الاستخدام المحددة الخاصة بي ، تمكنت من تحديد المشكلة المتمثلة في إعادة عرض كل إدخال في النموذج عند تحديث النموذج ، على الرغم من تغيير إدخال واحد فقط بالفعل.
في لقطة الشاشة أدناه ، قمت بلف كل من FormControl والإدخال في مكون محفوظ ، وتجنب العرض إذا لم تتغير القيمة. اقترح dantman في الواقع أن أقوم بإنشاء مكون محدد لكل ExpansionPanel
ولكن هذا حل أقل شمولية. كملاحظة جانبية ، لا يزال يتم إعادة عرض كل لوحة والأداء بعيد عن المستوى الأمثل ولكنه كافٍ في الوقت الحالي.
أعتقد أنه لا توجد طريقة لتجنب هذا النوع من المشكلات مع تغيير رمز واجهة المستخدم المادية دون تغيير هائل في واجهة برمجة التطبيقات الحالية التي تعتمد بشكل كبير على تكوين React.ReactNode
.
ولكن كما ذكر dantman في https://github.com/mui-org/material-ui/issues/10778#issuecomment -449153635 ، فإن MUI أبطأ قليلاً مما توقعته منه. عدم معالجة هذا على الإطلاق هو خطأ IMHO.
نظرًا لهذه المشكلة ، قد نحتاج إلى إنشاء صفحة مستند تتعلق بمشكلات الأداء وكيفية معالجتها. حتى إذا كانت صفحته ستعيد التوجيه بشكل أساسي إلى المستند الرسمي (https://reactjs.org/docs/optimizing-performance.html) وقائمة المكونات التي قد تسبب مشكلات في الأداء ، فهذه بداية.
سيكون من الأفضل التحكم في. تحذير المستخدم عند حدوث مثل هذه المشكلة ولكن لا يمكنني اكتشاف طريقة لاكتشاف المشكلات على مستوى واجهة المستخدم المادية.
prevostc هذه الرسالة جعلت يومي ، هذا هو نوع المجتمع الذي أحبه. هل لديك أفكار حول ما يمكن أن يغيره mui لتحسين الأداء وتجنب الحاجة إلى تحسينات أراضي المستخدم؟ قد يكون تغيير API قابلاً للتنفيذ.
لا أفعل: s
لا أعرف داخليًا لـ MUI بما يكفي ليكون لدي أي فكرة عن كيفية تحسين أدائها الأولي (بدون تغيير واجهة برمجة التطبيقات) في الوقت الحالي. أنا أعمل على بعض الأفكار ولكن لا شيء قاطع اعتبارًا من اليوم: لدي تطبيق حيث يتم إعادة عرض مجموعة الراديو عندما لا يكون الوالد المباشر كذلك ، لا يمكن إعادة إنتاج هذا محليًا حتى الآن.
قد يكون أي تغيير في واجهة برمجة التطبيقات هو التفكير في إزالة أي عناصر React.ReactNode
من واجهة برمجة التطبيقات (الأطفال وغيرها من الدعائم مثل الأيقونة ، وما إلى ذلك) ولكن لم أجد طريقة جيدة للاحتفاظ بنفس قابلية التكوين.
إليكم ما جربته: https://codesandbox.io/s/jpw36jw65 (تحذير: لم ينته).
كما أنه من الأشياء التي يجب ملاحظتها أن MUI يكون بطيئًا بشكل خاص أثناء وجوده في وضع التطوير نظرًا لكون رد الفعل بطيئًا بشكل خاص في وضع التطوير. لا أعرف ما إذا كانت هناك طريقة لتحسين هذا.
هل هناك أي تقدم في إضافة القدرات (مثل تلك التي اقترحها Bessonov ) من أجل تحسين مشكلات الأداء التي تواجهها Material-UI حاليًا؟
عندما بدأنا في استخدام هذه المكتبة الرائعة لمشروعنا ، لم أكن أعلم أن مثل هذه المشكلات في الأداء قد تحدث عندما يصبح المشروع أكبر وأكبر ؛ بالإضافة إلى ذلك ، لم أشاهد أي قسم في مستندات Material-UI يخبرني بالحالات التي قد تتسبب في أن تصبح Material-UI بطيئة وتضر UX.
تم الإبلاغ عن الكثير من مشكلات الأداء - المرتبطة بشكل مباشر أو غير مباشر بـ Material-UI - في هذه المشكلة. أعتقد أنه سيكون فكرة جيدة أن تدرجهم في قضية أخرى حتى يتمكن الجميع من تتبع التقدم. إذا كنت تعتقد أنه لا بأس ، يمكنني فتح عدد جديد.
@ mkermani144 لم نتمكن بعد من رؤية تقرير أداء مرتبط بشكل مباشر بشيء تقوم به واجهة المستخدم المادية بشكل خاطئ. حتى الآن تم استخدام هذه القضية كمنتدى مساعدة للأشخاص الذين يعانون. هل تؤكد أنه لم يتم الإبلاغ عن أي شيء عملي؟ سأقول إن تجريد التفاعل الواضح
لنأخذ مثال الجدول. إنه مكون يجده الناس بطيئًا. لقد وثقنا المحاكاة الافتراضية ، فهي تساعد كثيرًا.
في حالة الاختبار التالية ، نقوم بعرض 100 عنصر في وضع dev . يمكننا النظر في الحالات التالية:
لذا فإن النفقات العامة لاستخدام Material-UI في وضع dev على عنصر مضيف تبلغ حوالي x4 (الفرق أصغر في الإنتاج!) ، ببساطة لأننا نصنع مكونات وسيطة. هذا هو سبب أهمية المحاكاة الافتراضية بعد عرض قائمة تضم حوالي 100 عنصر جدول. الآن ، يمكننا الغوص قليلاً في لماذا وماذا يمكننا أن نفعل حيال ذلك؟
لذلك ، لدينا رافعة مالية واحدة متاحة: ترحيل كل المكونات من withStyles إلى makeStyles. يمكننا الفوز بحوالي 30٪ من الأداء (262 / (262-70)) في وضع التطوير .
لقد أجريت نفس حالات الاختبار في وضع الإنتاج:
لذا فإن الترحيل من withStyles
إلى makeStyles
لا يزال يمثل تسريعًا بنسبة 30٪ نظريًا في وضع الإنتاج .
إذا كنت تعتقد أنه لا بأس ، يمكنني فتح عدد جديد.
@ mkermani144 إذا كانت لديك حالة معينة حيث أن Material-UI تفعل ذلك بشكل خاطئ ، بالتأكيد.
قرأت عن جميع التعليقات أدناه هذه المسألة. مشكلتي لا تناسب أيًا من المشكلات الأخرى المذكورة سابقًا.
لدي مكوِّن List
يحتوي على بعض ListItem
s ، مع تحديد واحد منهم وتمييزه. عندما أنقر فوق ListItem
لتحديده وتمييزه ، تتم إعادة عرض القائمة بأكملها (التي تحتوي على العناصر الفرعية) مرة أخرى.
أعلم أن هذه المشكلة قد تبدو تمامًا مثل تعليق سابق ، لكنها ليست كذلك ؛ على الأقل أنا اعتقد ذلك.
لنلقِ نظرة على النتائج من ملف تعريف React:
كما ترى ، لدي مكون MyList
في المستوى العلوي من الصورة. هذا المكون هو مجرد غلاف حول MUI List
ويجعله نقيًا ، أي:
class MyList extends React.PureComponent {
render() {
return (
<List>
{this.props.children}
</List>
);
}
}
لقد أضفت هذا الغلاف لأن @ eps1lon في أحد تعليقاته ذكر أن إعادة عرض List
تؤدي إلى تحديث السياق ، وهذا التحديث السياقي يجعل جميع المستهلكين (بما في ذلك ListItem
s) يعيدون العرض أيضًا .
حاولت أيضًا جعل كل ما عندي من ListItem
s خالصًا وملفًا للتطبيق مرة أخرى. كانت النتائج متشابهة ، باستثناء أن المكوِّن المخصص (على سبيل المثال MyListItem
) لم يعيد تصيير _itself_ ، ولكن جميع العناصر الفرعية التي تحته __did__.
أعلم أن المشكلة تحدث لأن السياق الذي تستخدمه MUI لتصميم يعيد تصيير _ بطريقة ما_. لكني لا أعرف لماذا تحدث إعادة التصيير هذه وكيف يمكنني تجنبها.
أم أنني أفعل شيئًا خاطئًا؟
ملاحظة: أستخدم حل تصميم MUI جديد (ألفا) ، أي @material-ui/styles
. لا أعرف ما إذا كان هذا مهمًا.
@ mkermani144 قم بإزالة Material-UI مع العناصر الأصلية ، لاحظ أن إعادة العرض لا تزال موجودة. المنطق الخالص لن يساعد مثل هذا. يقوم React.createElement بإنشاء مراجع جديدة في كل تصيير ، وهو يبطل PureComponent الخاص بك.
نعم ، أعلم أن العناصر هي كائنات ، والكائنات ليست متساوية تمامًا في جافا سكريبت ، لذلك فشل sCU
.
لكنني لا أفهم ما تقصده عندما تقول أن React.createElement
تم استدعاءه مرة أخرى. أي استدعاء لـ createElement
؟ إذا كنت تقصد المكالمات داخل List
، فإنها تستدعي فقط createElement
لأطفالها ( ListItem
s) فقط إذا تمت إعادة تقديمها. إذا لم تتم إعادة تصييرها ، فلن يتم استدعاء createElement
ولن تحدث إعادة تصيير. المشكلة هي أن List
نفسه يتم إعادة تقديمه.
@ mkermani144 إذا كان بإمكانك إنشاء مثال على الحد الأدنى من التكاثر ، فيمكننا إلقاء نظرة عليه.
يتم عرض MyList
(وبالتالي List
) بسبب المكون الذي يعرض MyList
(دعنا نطلق عليه MyComponent
). لا يساعد PureComponent على MyList
حيث تم عرض MyComponent
وإنشاء أطفال جدد مقابل MyList
بحيث يفشل الشيك MyList
s.
من المحتمل أن تتم إعادة عرض MyComponent
بك لأنه يوجد مكان تخزن فيه حالة العنصر المحدد.
أعتقد أن تنفيذ MUIs للقائمة يجب أن يتغير لعدم إعادة إنشاء قيمة سياق القائمة في كل عرض
هنا: https://github.com/mui-org/material-ui/blob/fb4889f42613b05220c49f8fc361451066989328/packages/material-ui/src/List/List.js#L57
لذا بدلاً من ذلك ، اجعل القائمة تبدو كما يلي:
const List = React.forwardRef(function List(props, ref) {
const {
children,
classes,
className,
component: Component,
dense,
disablePadding,
subheader,
...other
} = props;
const context = React.useMemo(() => ({ dense }), [dense]);
return (
<Component
className={clsx(
classes.root,
{
[classes.dense]: dense && !disablePadding,
[classes.padding]: !disablePadding,
[classes.subheader]: subheader,
},
className,
)}
ref={ref}
{...other}
>
<ListContext.Provider value={context}>
{subheader}
{children}
</ListContext.Provider>
</Component>
);
});
سيؤدي ذلك إلى تبسيط إنشاء إصدارات sCU
من ListItems
يتم إعادة عرض MyList (وبالتالي القائمة) بسبب المكون الذي يعرض MyList (دعنا نسميها MyComponent). لا يساعد PureComponent في MyList حيث تم إعادة عرض MyComponent وإنشاء عناصر فرعية جديدة لـ MyList بحيث يفشل فحص MyLists.
Pajn لا ، انظر إلى نتائج ملف التعريف الخاص بي في React . لم يتم إعادة تقديم MyList
(إنه رمادي) ، ولكن تم إعادة عرض List
(لونه أزرق). لا أصر على استخدام PureComponent
مقابل MyList
. على الرغم من أنني نفذت sCU
مقابل MyList
حتى لا يتم إعادة تصييرها ، فإن List
__ يتم إعادة التقديم__.
تضمين التغريدة
لقد أنشأت مثالًا على الحد الأدنى من التكاثر:
import React, { Component } from 'react';
import StylesProvider from '@material-ui/styles/StylesProvider';
import ThemeProvider from '@material-ui/styles/ThemeProvider';
import { createMuiTheme } from '@material-ui/core';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
const theme = createMuiTheme({});
const MyListItem = React.memo(ListItem, (prev, next) => prev.selected === next.selected);
class App extends Component {
state = {
selected: null,
}
render() {
return (
<StylesProvider>
<ThemeProvider theme={theme}>
<List>
{[0, 1, 2, 3, 4].map(el => (
<MyListItem
button
selected={el === this.state.selected}
onClick={() => this.setState({ selected: el })}
>
{el}
</MyListItem>
))}
</List>
</ThemeProvider>
</StylesProvider>
);
}
}
export default App;
تفاعل نتائج المحلل (بعد النقر على عنصر القائمة الرابع):
كما ترى ، يعمل كما هو متوقع ، أي لا توجد عمليات إعادة تصيير إضافية (باستثناء ButtonBase
داخل ListItem
s). المشكلة هي أن هذا التكاثر _أدنى _ جدا؛ هناك الكثير من الأشياء التي تخطيتها.
أعلم أنه لا يمكنك إخباري ما هو الخطأ في الكود الخاص بي الذي يتسبب في عمليات إعادة تصيير إضافية. لكني أطرح عليك سؤالاً: ما الذي يمكن أن يتسبب في إعادة تصيير مكونات WithStylesInner
التي تغلف مكونات MUI؟
@ mkermani144 ما رأيك في هذا الإصلاح؟
--- a/packages/material-ui/src/List/List.js
+++ b/packages/material-ui/src/List/List.js
@@ -40,6 +40,13 @@ const List = React.forwardRef(function List(props, ref) {
...other
} = props;
+ const context = React.useMemo(
+ () => ({
+ dense,
+ }),
+ [dense],
+ );
+
return (
<Component
className={clsx(
@@ -54,7 +61,7 @@ const List = React.forwardRef(function List(props, ref) {
ref={ref}
{...other}
>
- <ListContext.Provider value={{ dense }}>
+ <ListContext.Provider value={context}>
{subheader}
{children}
</ListContext.Provider>
هل تريد تقديم طلب سحب؟ :) نحن نستخدم نفس الإستراتيجية مع مكون الجدول. إنه يعمل بشكل رائع. شكرا لك على الإبلاغ عن المشكلة!
تضمين التغريدة هذا هو بالضبط ما اقترحه Pajn سابقًا. لقد قدمت PR .
List
عقبة في الأداء إذا كان كبيرًا بما يكفي ، بغض النظر عن مقدار تحسينه. ألا يجب أن نقدم مثالاً يوضح استخدام react-window
أو react-virtualized
مع List
، مثل الذي لدينا في Table
docs؟ألا يجب أن نقدم مثالاً يوضح استخدام نافذة رد الفعل أو التفاعل الافتراضي مع مكون القائمة ، مثل الذي لدينا في مستندات الجدول؟
سيكون ذلك رائعًا: +1:
Fwiw لقد أنشأت تطبيق دردشة ويحتاج التطبيق إلى عرض قائمة كبيرة من جهات الاتصال. واجهتني نفس المشكلة
@ mkermani144 كان.
@ henrylearn2rock هل فكرت في استخدام المحاكاة الافتراضية؟ لقد أضفنا عرضًا توضيحيًا للقائمة: https://next.material-ui.com/demos/lists/#virtualized -list.
هذا أيضًا أوقفني حقًا. أعتقد أن معظم الناس (بمن فيهم أنا) افترضوا أن كل شيء في إطار مكون نقي كان في مأمن من إعادة الإرسال ، ومن الواضح أن هذا ليس هو الحال بالنسبة لهذه المكتبة. سأحاول المحاكاة الافتراضية كما اقترحت مؤخرًا. شكرا!
أعتقد أن معظم الناس (بمن فيهم أنا) افترضوا أن كل شيء في إطار مكون نقي كان في مأمن من إعادة الإرسال ، ومن الواضح أن هذا ليس هو الحال بالنسبة لهذه المكتبة.
هذه ليست طريقة عمل React.PureComponent أو React.memo. إنه يؤثر فقط على المكون نفسه. قد لا يزال يتعين على الأطفال إعادة العرض إذا تغير السياق.
pytyl هل يمكنك مشاركة الكود حيث استخدمت PureComponent وتوقعت أن تمنع أي إعادة تصيير في الشجرة الفرعية؟
@ eps1lon ، تجعل الوثائق التالية الأمر يبدو وكأنه إرجاع خطأ من shouldComponentUpdate يتخطى تلقائيًا إعادة تصيير المكونات الفرعية.
https://reactjs.org/docs/optimizing-performance.html#shouldcomponentupdate-in-action
نظرًا لأن shouldComponentUpdate أعاد خطأ للشجرة الفرعية المتجذرة في C2 ، لم تحاول React تصيير C2 ، وبالتالي لم يكن عليها حتى استدعاء shouldComponentUpdate على C4 و C5.
ربما أكون مخطئا في هذا؟ فيما يلي لقطة من ملف التعريف الخاص بي. من أجل الاختبار فقط ، أعيد صراحة القيمة false لـ shouldComponentUpdate في مكون القائمة الخاص بي:
أدى هذا إلى عدم إعادة تصيير جميع مكونات الأطفال الخاصة بي (الفئات ، والفئة ، وعناصر الفئة ، والفئة العنصر). يبدو أن العديد من الأشياء المتعلقة بـ MUI يتم إعادة عرضها في الجزء السفلي مما يتسبب في حدوث الكثير من التأخير. أشياء مثل withStyles ، Typography ، ButtonBase. لا يزال رد الفعل جديدًا بعض الشيء ، لذا يرجى المعذرة لجهلي. يوجد أدناه الكود الخاص بي لمكون القائمة (حيث أعيد خطأ لـ shouldComponentUpdate):
import React, { Component } from "react";
import Categories from "./Categories";
import { withStyles, Paper } from "@material-ui/core";
const styles = theme => ({
root: {
paddingTop: 0,
marginLeft: theme.spacing.unit * 2,
marginRight: theme.spacing.unit * 2,
marginTop: theme.spacing.unit * 1
}
});
class Menu extends Component {
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.categories.length == this.props.categories.length) {
return false;
}
return true;
}
render() {
const { classes, categories } = this.props;
return (
<Paper className={classes.root}>
<Categories categories={categories} />
</Paper>
);
}
}
export default withStyles(styles)(Menu);
سأحتاج إلى أكواد وصندوق كامل لفهم المشكلة.
@ eps1lon سأحاول إنتاج واحد ليوم غد. شكرا لك.
@ eps1lon هنا هو codepen:
https://codesandbox.io/s/348kwwymj5
وصف قصير
إنه تطبيق قائمة أساسي للمطاعم (التي غالبًا ما تحتوي على ما يزيد عن 100 عنصر قائمة). عندما ينقر المستخدم على عنصر القائمة ، فإنه يفتح مربع حوار "إضافة إلى الأمر". سأقوم بإرفاق بعض المواقف التي يظهر فيها ملف التعريف أداء ضعيفًا (هذه الإحصائيات ليست في بناء إنتاج).
نظام
MacBook Pro (Retina ، 13 بوصة ، أوائل 2015)
3.1 جيجاهرتز Intel Core i7
Firefox 66.0.3
الحالة 1 (ينقر المستخدم على عنصر القائمة)
مدة العرض: 218ms
الحالة 2 (ينقر المستخدم على زر "إضافة إلى الطلب" في مربع الحوار)
مدة التقديم: 356ms
أنا متأكد من أنني أرتكب بعض الأخطاء المبتدئة هنا ، لذا فإن أي توجيه موضع تقدير كبير.
نظرًا لأنه يتم إعادة عرض WithStyles (ButtonBase) ، أفترض أن WithStyles يستخدم سياقًا تم إعادة إنشائه على الرغم من أنه لا يحتاج إلى ذلك.
تمكنت من العثور على هذا https://github.com/mui-org/material-ui/blob/048c9ced0258f38aa38d95d9f1cfa4c7b993a6a5/packages/material-ui-styles/src/StylesProvider/StylesProvider.js#L38 ولكن لا يمكنني العثور على مكان فيه يتم استخدام StylesProvider في الكود الفعلي (بحث GitHubs ليس جيدًا جدًا) ولكن قد يكون السبب.
هل يعرف @ eps1lon ما إذا كان هذا هو السبب؟ إذا كان الأمر كذلك ، فمن المحتمل أن يؤدي استخدام useMemo الموجود في كائن السياق إلى إصلاح ذلك. على الرغم من أنني لا أعرف ما إذا كانت الخيارات المحلية مستقرة أو ما إذا كان يجب نشر useMemo بشكل أكبر.
يمكن. ولكن يجب عليك أولاً التحقق من سبب استخدام المكون الخاص بك باستخدام StylesProvider. هذا إما شيء في الجزء العلوي من الشجرة الخاصة بك أو يجب أن يكون في بعض حدود واجهة المستخدم. في كلتا الحالتين ، نادرًا ما يتم عرضها. تذكر أن سياق التفاعل غير محسن للتحديثات المتكررة على أي حال.
لا ينبغي لنا تحسين هذه الأشياء قبل الأوان لمجرد إعادة إنشاء كائن ما أثناء التصيير. الذكريات ليست رصاصة فضية. لذلك بدون مثال ملموس لا يمكنني فعل الكثير. نعم ، يتم إعادة تقديم الأشياء. في بعض الأحيان يحتاجون إلى ذلك في كثير من الأحيان. لكن إعادة التصيير الضائعة لا تعني أنها سبب اختناق في الأداء.
pytyl لقد
@ eps1lon أعتقد أننا يجب أن نغلق هذه المسألة. سيكون من الأفضل التركيز على القضايا المحددة على وجه التحديد.
TL ؛ DR: إنشاء شرائح سياق ، وحفظ قيم السياق ، ولا توجد مشكلة في واجهة المستخدم المادية على وجه التحديد: https://codesandbox.io/s/8lx6vk2978
هل قمت ببعض التنقيب والمشكلة هي أن لديك هذا السياق العالمي الكبير الذي تمت إعادة إنشائه أثناء العرض. تقوم بإعادة عرض تطبيقك عند النقر في أي نقطة يتم إعادة إنشاء السياق العام. يستمع CategoryItem الخاص بك إليه والذي يظهر 100 مرة في تطبيقك. نظرًا لأن لديك قائمة 100 مادة-واجهة مستخدم ، فإنك تواجه الموت الكلاسيكي بألف تخفيضات.
ومن المفارقات أن جزءًا من الحل هو حفظ قيمة سياق ولكن الجزء المهم هو تحديد شرائح سياق منفصلة. يبدو أن الحالة وسياق الإرسال مناسب. يوصى بهذا عند استخدام useContext مع useReducer ويبدو أنه مناسب هنا.
يمكن أن يؤدي هذا إلى إنشاء شجرة كبيرة جدًا ويجعل الدعائم جحيمة كلما زاد عدد السياقات لديك. أشجعك على إلقاء نظرة على useContext
. سيساعدك كثيرًا إذا بدأت في مواجهة هذه المشكلات.
oliviertassinari من الجيد جمع المزالق الشائعة بالحلول. يمكننا أن نقرر ما إذا كنا نريد إنشاء قضايا منفصلة عنه.
oliviertassinari @ شكرًا
لقد واجهت للتو مشكلة في أداء العرض البطيء. لقد قمت بحلها تمامًا عن طريق استبدال جميع مثيلات المكون <Box>
بـ <div>
s. لقد قمت بتصحيح الأخطاء باستخدام رد فعل devtools flamegraph ، وذهبت من حوالي 420 مللي ثانية إلى 20 مللي ثانية.
مع <Box>
es؛
بدون <Box>
es:
mankittens يمكنك الاحتفاظ بمكون Box ، باستخدام مكونات مصممة كمحرك نمط. سيكون الأداء أفضل بكثير. يجب أن تتحسن مع JSS في المستقبل القريب https://github.com/mui-org/material-ui/pull/16858.
أنا أغلق هذه القضية. نحن بحاجة إلى تقرير أداء مخصص لكل مجال محتمل للتحسين ، وليس موضوعًا شاملاً.
التعليق الأكثر فائدة
oliviertassinari كمطور رائع ، كيف يمكنك كتابة أشياء مثل هذه؟ لماذا تستخدم افتراضاتك الشخصية كحجج وليست حقائق؟ أعتقد أنني قدمت حقائق كافية أعلاه. فعلت كل شيء لأظهره ، لأنني أحب هذا المشروع وأريد المساهمة. إنه لا يكفى؟ حسنًا ، مزيد من الحقائق والافتراضات.
فقط لأجلك أقوم بتقليصه إلى 10 أزرار. 10! انها تعني أي 10 مكونات (أسوأ من ذلك: حاويات) من تباطؤ مادي-واجهة المستخدم أسفل التطبيق بأكمله حتى التطبيق غير صالح للاستخدام! تم اختباره على جهاز حقيقي مع Crosswalk 21 / chrome 51 بدون أي دواسة الوقود:
الزر العادي:
PureButton:
هذا لا يزال تحسن 8x! انه ضخم! هل يمكنك تخيل مدى أهمية هذا على الجهاز المحمول؟
لقد استخدمت Button لأنه أحد أبسط المكونات! فإنه يدل على أن واجهة المستخدم، يتم تقسيم المواد من جهة نظر الأداء. الآن ، تخيل مكونات حاوية مثل AppBar ، Toolbar ، List ، Drawer! هذا أسوأ! تحصل بسرعة كبيرة على 20 مكونًا / حاوية في كل صفحة. ولأنك لا تنتهي صلاحية أي بطء على سطح المكتب / جهاز Mac القوي ، فهذا لا يعني أن واجهة المستخدم المادية ليست بطيئة بشكل لا يصدق.
أرني مثالا على الأكوادوعلبة. لا أفهم لماذا يجب أن يحدث هذا. أنا متأكد من أن هذا يحدث فقط عند الاستخدام الخاطئ لمكونات التفاعل. ويظهر المثال الرسمي استخدامًا خاطئًا ، لأنه يبدو وكأنه رد فعل لمشتركي السياق المطبق. ولكن هناك الكثير من المكونات الأخرى التي تتوافق مع إرشادات التفاعل وأفضل الممارسات للبقاء في الأداء.
راجع للشغل: WithStyles تستهلك ما يصل إلى 2،27 مللي ثانية للزر الموجود على الجهاز المحمول. 8 مكونات وأنت أقل من 60 إطارًا في الثانية.