| وجه المقارنة المعمارية | الأنابيب النقية (Pure Pipes - الافتراضية) | الأنابيب غير النقية (Impure Pipes) |
|---|---|---|
| متى يتم إعادة تشغيل الأنبوب؟ | فقط عند حدوث تغيير حقيقي في القيمة البدائية المدخلة أو مرجع البيانات (Reference Change) | مع كل دورة تحقق من الأداء في التطبيق (Every Change Detection Cycle) |
| تأثير الأداء على واجهة المستخدم | عالي الكفاءة وخفيف جداً على الموارد لأن أنجولر يتخزن النتائج مؤقتاً (Memoization) | مكلف أحياناً من الناحية الحسابية ويجب استخدامه بحذر شديد لتفادي بطء التطبيق |
| حالة الاستخدام المعماري المفضلة | معالجة وتنسيق البيانات الثابتة أو التي تتغير عبر تغيير المراجع (Immutable Data) | مراقبة التغييرات الداخلية ضمن العناصر الفرعية للمصفوفات أو الكائنات المعقدة (Mutable Data) |
أحد أهم المفصل المعمارية المتقدمة في هندسة Angular 22.1؛ ألا وهو التمييز الحاسم بين الأنابيب النقية (Pure Pipes) والأنابيب غير النقية (Impure Pipes). كقاعدة افتراضية، كل الأنابيب في أنجولر تكون نقية، مما يعني أنها لا تعيد تنفيذ عملية التحويل إلا إذا تغيرت القيمة البدائية المدخلة (Primitive) أو المرجع الأساسي للكائن. فهم هذا الفرق الجوهري يمكن المطور من تجنب المشاكل الكارثية في الأداء أو معالجة التحديثات المستمرة للبيانات غير القابلة للتغيير (Immutability).
تعتمد الأنابيب النقية على مبدأ التخزين المؤقت للنتائج (Memoization). إذا تم استدعاء الأنبوب بنفس المدخلات تماماً، فلن يعيد حساب النتيجة، بل سيعيد القيمة المخزنة مباشرة، مما يوفر طاقة المعالجة بشكل هائل في تطبيقات المؤسسات الضخمة.
عند ضبط الأنبوب ليكون غير نقي عبر الخاصية pure: false في الكلاس Pipe, فإن أنجولر يجبر الأنبوب على إعادة العمل مع كل حركة في واجهة المستخدم (مثل الضغط على زر، تحريك الفأرة، أو تدفق مؤقت). يُستخدم هذا النوع بحذر فقط عند الحاجة الملحة لتتبع التغييرات العميقة داخل المصفوفات أو الكائنات دون تغيير مرجعها الأساسي.
| 1 | import { Pipe, PipeTransform } from '@angular/core'; |
| 2 | |
| 3 | @Pipe({ |
| 4 | name: 'taxCalculator', |
| 5 | standalone: true, |
| 6 | pure: true // القيمة الافتراضية |
| 7 | }) |
| 8 | export class TaxCalculatorPipe implements PipeTransform { |
| 9 | transform(amount: number, taxRate: number = 0.15): number { |
| 10 | console.log('تم استفيذ الأنبوب النقي وإعادة حساب الضريبة...'); |
| 11 | return amount + (amount * taxRate); |
| 12 | } |
| 13 | } |
| 1 | import { Pipe, PipeTransform } from '@angular/core'; |
| 2 | |
| 3 | @Pipe({ |
| 4 | name: 'deepSearchFilter', |
| 5 | standalone: true, |
| 6 | pure: false // تحويل الأنبوب ليصبح غير نقي |
| 7 | }) |
| 8 | export class DeepSearchFilterPipe implements PipeTransform { |
| 9 | transform(items: string[], searchTerm: string): string[] { |
| 10 | console.log('تم تشغيل الأنبوب غير النقي وفحص عناصر المصفوفة...'); |
| 11 | if (!items || !searchTerm) { |
| 12 | return items; |
| 13 | } |
| 14 | return items.filter(item => item.toLowerCase().includes(searchTerm.toLowerCase())); |
| 15 | } |
| 16 | } |
| 1 | import { Component, signal } from '@angular/core'; |
| 2 | import { CommonModule } from '@angular/common'; |
| 3 | import { TaxCalculatorPipe } from './tax-calculator.pipe'; |
| 4 | import { DeepSearchFilterPipe } from './deep-search-filter.pipe'; |
| 5 | |
| 6 | @Component({ |
| 7 | selector: 'app-pipes-performance-demo', |
| 8 | standalone: true, |
| 9 | imports: [CommonModule, TaxCalculatorPipe, DeepSearchFilterPipe], |
| 10 | template: ` |
| 11 | <div class="master-container"> |
| 12 | <h3>مقارنة الأداء بين الأنابيب النقية وغير النقية في Angular 22.1</h3> |
| 13 | |
| 14 | <div class="data-card"> |
| 15 | <p><strong>المبلغ الأساسي:</strong> {{ baseAmount() }}</p> |
| 16 | <p><strong>المبلغ بعد الأنبوب النقي:</strong> {{ baseAmount() | taxCalculator }}</p> |
| 17 | <button (click)="updateAmount()" class="action-btn">تحديث المرجع الأساسي</button> |
| 18 | </div> |
| 19 | |
| 20 | <div class="data-card"> |
| 21 | <p><strong>قائمة المشاريع الهندسية:</strong></p> |
| 22 | <ul> |
| 23 | @for (project of projects | deepSearchFilter: 'Angular'; track $index) { |
| 24 | <li>{{ project }}</li> |
| 25 | } |
| 26 | </ul> |
| 27 | </div> |
| 28 | </div> |
| 29 | `, |
| 30 | styles: [` |
| 31 | .master-container { background: #090d16; color: #fff; padding: 24px; border-radius: 12px; } |
| 32 | .data-card { background: #1e293b; color: #38bdf8; padding: 16px; border-radius: 8px; margin: 12px 0; border: 1px solid #334155; } |
| 33 | .action-btn { background: #38bdf8; color: #090d16; border: none; padding: 8px 16px; border-radius: 6px; font-weight: bold; cursor: pointer; margin-top: 8px; } |
| 34 | .action-btn:hover { background: #7dd3fc; } |
| 35 | `] |
| 36 | }) |
| 37 | export class PipesPerformanceDemoComponent { |
| 38 | baseAmount = signal(1000); |
| 39 | projects = ['Angular 22.1 Architecture', 'React Advanced Patterns', 'Vue Composition API']; |
| 40 | |
| 41 | updateAmount() { |
| 42 | this.baseAmount.update(val => val + 250); |
| 43 | } |
| 44 | } |