تكرار السؤال: …
الإجابة المختصرة
يحدد shouldRepaint() ما إذا كانت هناك حاجة لإعادة تنفيذ أوامر الرسم على الـ Canvas عند إعادة البناء؛ وعدم التحقق الدقيق من الحقول يؤدي لإعادة رسم فادحة وغير مبررة تستهلك الـ GPU.
الشرح
ينفذ CustomPainter أوامر رسم منخفضة المستوى عبر RenderCustomPaint. دالة paint() تستقبل Canvas و Size. للوصول لأعلى أداء: (1) يجب إنشاء كائنات Paint ومسارات Path خارج دالة paint() وتفادي إنشاء كائنات جديدة في كل فريم. (2) يجب أن تقارن shouldRepaint() القيم الحقيقية المؤثرة على الرسم وترجع false إذا لم تتغير. (3) وضع الـ CustomPaint داخل RepaintBoundary لعزل الطبقة الرسومية عن شجرة الواجهة المحيطة.
مثال بالكود
class CircleProgressPainter extends CustomPainter {
final double progress;
final Color color;
CircleProgressPainter({required this.progress, required this.color});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()..color = color..strokeWidth = 4.0..style = PaintingStyle.stroke;
canvas.drawCircle(size.center(Offset.zero), size.width / 2, paint);
}
@override
bool shouldRepaint(covariant CircleProgressPainter oldDelegate) {
return oldDelegate.progress != progress || oldDelegate.color != color;
}
}أخطاء شائعة
- إرجاع true دائماً من shouldRepaint() ظناً أنها ممارسة آمنة، مما يجبر المحرك على إعادة استهلاك الموارد الرسومية مع كل rebuild.
- تخصيص ذاكرة وإنشاء مصفوفات ومسارات ضخمة داخل دالة paint() المكررة في كل فريم.