سلسلة تحسين أداء iOS 03|المشاكل الشائعة مع تعثر قائمة iOS
عادةً ما يكون سبب تأخر القائمة هو أن الخيط الرئيسي يستهلك الكثير من العمل الذي يتنافس مع الإطار الحالي أثناء عملية التمرير.
يعد تأخر القائمة مشكلة الأداء الأكثر شيوعًا والأكثر سوءًا في الحكم عليها في مشاريع iOS.
بمجرد أن أرى هذا الوضع والقائمة لا تسير بسلاسة، سأقول على الفور:
- هل
SwiftUI Listبطيء جدًا؟ - هل تم تكوين
UICollectionViewبشكل غير صحيح؟ - هل هذا التحكم عالق بطبيعته؟
في بعض الأحيان لا تكون هذه الأحكام خاطئة تمامًا، لكنها غالبًا ما تكون سطحية. السؤال الحقيقي الأكثر مركزية هو عادة:
في التمرير، وهو الإجراء الذي يعتمد بشكل كبير على استجابة الموضوع الرئيسي في الوقت المناسب، ما مقدار العمل الإضافي الذي يقوم به النظام في نفس الوقت؟
لذلك، على الرغم من تنفيذ UITableView وUICollectionView وSwiftUI List بطرق مختلفة، إلا أنها غالبًا ما تقع في مشكلات متشابهة جدًا.
1. من المرجح أن تكشف القوائم مشاكل في الأداء أكثر من العديد من الصفحات.
لأن القائمة عبارة عن مشهد مستمر عالي التردد وحساس لكل إطار.
أثناء قيام المستخدم بالتمرير، يحتاج النظام إلى إكمال هذه الأشياء بشكل مستمر:
- حساب التخطيط
- تحضير الوحدات المرئية
- وحدات إعادة الاستخدام والتدوير
- رسم المحتوى
- الرد على الإيماءات
إذا طُلب من الخيط الرئيسي أيضًا القيام بالكثير من العمل الإضافي في نفس الوقت، مثل:
- فك تشفير الصورة
- تجميع النص الغني
- تحليل JSON
- حسابات التخطيط التلقائي عالية التكلفة
- تغييرات الحالة المتكررة تؤدي إلى التحديث الكامل
وهذا التأخر يكاد يكون نتيجة حتمية.
سبب شهرة القائمة هو أنها تبدو غامضة في الظاهر، لكنها في الحقيقة أقرب إليها، مما يضخم الضغط على الخيط الرئيسي بشكل واضح للغاية.
2. المشكلة الأكثر شيوعًا هي أنك تفعل شيئًا لا ينبغي لك فعله في هذه اللحظة أثناء التمرير.
من الأساليب الشائعة عند التحسين التركيز فقط على طول رمز الخلية عند تحسين القوائم. لكن في المشاريع الحقيقية، غالبًا ما تكون أسباب بطاقات القائمة كالتالي:
- لا يتم فك تشفير الصورة حتى يتم عرضها
- يتم حساب ارتفاع النص بشكل متكرر أثناء التمرير
- تتم إعادة تنسيق الخلية وتحويل البيانات في كل مرة تظهر فيها.
- تم تشغيل عدد كبير جدًا من تحديثات حالة الطبقة الأصلية عند تمرير القائمة
- يؤدي التغيير البسيط إلى إعادة رسم القائمة بأكملها أو أن يكون الفرق باهظ الثمن
السمات المشتركة لهذه المشاكل هي: من المفترض أن تكون “لا ينبغي القيام بها في هذه اللحظة من التمرير”.
لذا فإن الفكرة الأكثر أهمية لتحسين القائمة هي:
- ما المهام التي يمكن القيام بها مقدما؟
- ما هي الوظائف التي يمكن تخزينها مؤقتا
- ما المهام التي يمكن تأجيلها
- ما هي التحديثات التي يمكن ترجمتها
3. غالبًا ما تكون الصور هي السبب وراء تأخر القائمة. في الظاهر، تبدو وكأنها تنزيلات، لكنها في الواقع أقرب إلى فك التشفير ومعالجة الحجم.
تقول العديد من الفرق “عدد كبير جدًا من الصور” عندما يواجهون بطاقات القائمة. في بعض الأحيان يكون اتجاه هذه الجملة صحيحا، لكن السبب غالبا ما يكون خاطئا.
ما يبطئ التمرير حقًا هو في كثير من الأحيان:
- فك تشفير الصورة
- تكبير الصورة
- حجم التحميل غير مناسب
- تشغيل معالجة الصور بشكل متكرر على الموضوع الرئيسي
ومع ذلك، فإن الشيء الأكثر رعبًا في مشكلة الرسومات هو أنه يمكنها بسهولة إدراج عمل مكلف على المسار الحرج للفة.
لذلك، فإن جوهر تحسين الصورة في القائمة لا يقتصر عادةً على التخزين المؤقت فحسب، بل:
- قم بتحضير الحجم المناسب مسبقاً
- تقليل ضغط فك التشفير لحظة العرض
- تجنب المعالجة الثقيلة للصور عند التمرير
4. غالبًا ما تؤدي معالجة البيانات إلى تأخير تجربة التمرير.
وهذا أكثر شيوعًا مما قد يعتقده المرء.
على سبيل المثال، يجب عرض عنصر القائمة:
- تنسيق الوقت
- تنسيق المبلغ
- مزيج النص الغني
- رسم الخرائط العلامة
- كتابة الحالة المعقدة
إذا تم تنفيذ هذه الأشياء مؤقتًا أثناء مرحلة تكوين الخلية، فسيستمر الخيط الرئيسي في استهلاك هذه التكلفة أثناء التمرير.
الجزء الأكثر إزعاجًا في هذا النوع من المشاكل هو:
- وظيفيا صحيحا تماما
- التكلفة الفردية لا تبدو مبالغ فيها
- لكن في التمرير عالي التردد، سيتم تضخيمه بشكل كبير
ولذلك، فإن المبدأ المهم جدًا لتحسين أداء القائمة هو: **دع طبقة العرض تحاول استهلاك بيانات العرض المعدة بدلاً من إجراء الكثير من التحويلات أثناء التمرير. **
5. إذا كانت طريقة تحديث الحالة خاطئة، فستتعطل القائمة، وغالبًا ما يتم الخلط بينها وبين مشكلة في التخطيط.
بعض مشكلات القائمة ليست معقدة على الإطلاق بسبب الخلية، ولكن أيضًا بسبب كون دقة تحديث الحالة خشنة جدًا.
على سبيل المثال:
- قم بتحديث القائمة بأكملها بمجرد تغيير كلمة البحث الأساسية
- مثل أحد العناصر ويتم إعادة بناء شجرة حالة الصفحة بأكملها
- تعود النتيجة المرقّمة ويتم إعادة حساب القائمة بأكملها
يتم تشخيص هذا النوع من المشاكل بسهولة بشكل خاطئ على النحو التالي:
- مكونات واجهة المستخدم بطيئة جدًا
- نظام التخطيط غير فعال
في الواقع، المشكلة الحقيقية في كثير من الأحيان هي:
** أدى تغيير صغير في الأعمال إلى تحديث واجهة المستخدم الذي كان أكبر بكثير من اللازم. **
لذا، عندما تتأخر قائمة استكشاف الأخطاء وإصلاحها، فإن الشيء الوحيد الذي أسأله غالبًا هو:
ما هي العناصر التي يجب أن تتأثر بهذا التغيير في الحالة؟ لماذا أثرت على هذه المساحة الكبيرة في النهاية؟
6. ما هي المشاكل الشائعة لـ UITableView وUICollectionView وSwiftUI List؟
على الرغم من أن تفاصيل تنفيذ هذه الأنظمة الثلاثة مختلفة تمامًا، إلا أن مشكلات الأداء عالي التردد متشابهة جدًا في الواقع:
- القيام بالكثير من عمل الخيط الرئيسي أثناء التمرير
- يوضح عنصر القائمة أن البيانات قد تم إعدادها بعد فوات الأوان
- يتم وضع معالجة الصور والنصوص على المسار الحرج
- حجم التحديث كبير جدًا
- بعض التخطيطات أو التسلسلات الهرمية للعرض معقدة للغاية
بمعنى آخر، مشاكلهم المشتركة ليست:
**الشكل التفاعلي للقائمة نفسها حساس بشكل خاص لتوقيت الموضوع الرئيسي وتخصيص العمل. **
لذلك، يمكن أن يتسبب نفس التصميم الخاطئ في توقفات مشابهة في ثلاثة عناصر تحكم مختلفة بالقائمة.
7. تسلسل استكشاف الأخطاء وإصلاحها أقرب إلى القتال الفعلي
إذا كنت أرغب في التحقق من مشكلة تأخر القائمة اليوم، فعادةً لن أقوم بتغيير الكود أولاً، ولكن سأحكم أولاً بهذا الترتيب:
- يحدث التأتأة عند ظهور الشاشة الأولى، أو عند التمرير السريع، أو عند حدوث ترقيم الصفحات.
- ما إذا كان عنصر القائمة الحالي يحتوي على صور أو نص منسق أو تخطيط معقد.
- ما إذا كان قد تم إجراء الكثير من التحويلات في الوقت الفعلي قبل عرض الخلية.
- ما إذا كان تغيير معين في الحالة المحلية قد أدى إلى تحديث واسع النطاق بشكل مفرط.
- ما إذا كان هناك فك تشفير أو قياس أو إعادة حساب متزامن أثناء التمرير.
قيمة هذا التسلسل هي: اكتشف أولاً “ما العمل الذي يشغل الموضوع الرئيسي أثناء التمرير” بدلاً من تخمين مشكلة إطار العمل أولاً.
8. الاستنتاج: عادة ما يكون جوهر تأخر القائمة هو حشو الكثير من العمل في المسار الحرج الذي لا ينبغي حشوه.
ولكي أختصر الأمر أقول:
القائمة عالقة، وعادةً ما يتم تمرير الجزء الأساسي. في هذا السيناريو عالي التردد، يحمل الخيط الرئيسي الكثير من تكاليف التخطيط وفك التشفير والتحويل والتحديث المفرط في نفس الوقت.
لذا فإن أهم الأشياء لتحسين القائمة هي:
- ضع العمل مقدما
- ذاكرة التخزين المؤقت للنتائج
- تقليل تفاصيل التحديث
- إزالة العبء الإضافي عن المسار الحرج
إذا قمت بهذه الأمور الأربعة بشكل صحيح، فعادةً ما تكون تجربة القائمة أكثر استقرارًا من مجرد تعديل بعض المعلمات.
What to read next
Want more posts about iOS Performance Optimization?
Posts in the same category are usually the best next step for reading more on this topic.
View same categoryWant to keep following #iOS?
Tags are useful for related tools, specific problems, and similar troubleshooting notes.
View same tagWant to explore another direction?
If you are not sure what to read next, return to the homepage and start from categories, topics, or latest updates.
Back home