Angular Devs مراقب باشید: آیا شما مقصر این تمرین کشتن عملکرد هستید؟

سلام، هموطنان علاقمند به Angular! امروز، ما به یک تکنیک ضروری بهینه سازی Angular می پردازیم که می تواند برنامه شما را روان تر و سریع تر کند. من بهعنوان یک علاقهمند به Angular، برنامهنویسهای بیشماری را دیدهام که با فراخوانی مستقیم تابع در قالبها دچار مشکل شدهاند. اما نترسید، ما با هم این معما را حل خواهیم کرد و در طول مسیر کمی سرگرم خواهیم شد. بنابراین، نوشیدنی مورد علاقه خود را بردارید، راحت باشید، و بیایید ترک بخوریم!
مشکل: فراخوانی مستقیم تابع در قالب ها
این را تصویر کنید: شما در حال ساخت یک برنامه Angular با یک کادر جستجوی ساده هستید که لیستی از موارد را فیلتر می کند. در قالب جزء خود، تابعی را فراخوانی می کنید تا موارد را بر اساس ورودی جستجو فیلتر کند. در ابتدا بی ضرر به نظر می رسد، اما کمی می دانید که این تصمیم دوباره به سراغ شما خواهد آمد.
ببینید، فراخوانی مستقیم تابع در قالب های Angular می تواند منجر به مشکلات عملکرد، به ویژه در برنامه های پیچیده شود. هنگامی که Angular تشخیص تغییر را اجرا می کند، هر بار این توابع را اجرا می کند، حتی اگر چیزی تغییر نکرده باشد. این می تواند منجر به یک برنامه نفخ کرده و کند شود که باعث می شود کاربران شما با ناراحتی سر خود را خارانند.
اینجاست که قهرمان ما وارد می شود: خواص و قابل مشاهده! این دستیاران قابل اعتماد می توانند به شما کمک کنند تا داده های خود را به طور کارآمدتری مدیریت کنید و عملکرد مورد نیاز برنامه را افزایش دهید.
راه حل: ویژگی ها و قابل مشاهده ها را در آغوش بگیرید
ما نحوه جایگزینی فراخوانی مستقیم تابع در قالب های Angular را با ویژگی ها و قابل مشاهده ها بررسی خواهیم کرد. در طول راه، چند تکنیک پیشرفته را برای اجرای روان و کارآمد برنامه شما کشف خواهیم کرد.
مرحله 1: کامپوننت خود را تنظیم کنید
ابتدا، اجازه دهید یک مؤلفه ایجاد کنیم که فهرستی از موارد را نمایش دهد و شامل یک کادر ورودی جستجو باشد. برای ساده نگه داشتن کارها، از آرایه ای از رشته ها به عنوان منبع داده خود استفاده می کنیم.
import { Component } from '@angular/core';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss']
})
export class SearchComponent {
items = [
'Apple',
'Banana',
'Orange',
'Pineapple',
'Strawberry',
'Grape',
'Mango',
'Watermelon'
];
searchText = '';
filteredItems: string[] = [];
constructor() {
this.filteredItems = this.items;
}
}
در این مثال، ما مقدار را مقداردهی اولیه کردیم filteredItems
آرایه با آرایه اقلام اصلی این نقطه شروع ما برای فرآیند فیلترینگ خواهد بود.
مرحله 2: یک روش برای فیلتر کردن موارد ایجاد کنید
اکنون که کامپوننت ما راه اندازی شده است، به راهی برای فیلتر کردن موارد بر اساس ورودی جستجو نیاز داریم. برای این کار بیایید متدی به نام ایجاد کنیم onSearchTextChange()
که به روز می کند filteredItems
آرایه زمانی که متن جستجو تغییر می کند.
onSearchTextChange() {
const searchText = this.searchText.toLowerCase();
this.filteredItems = this.items.filter(item =>
item.toLowerCase().includes(searchText)
);
}
این روش جریان را می گیرد searchText
، آن را به حروف کوچک تبدیل می کند و سپس موارد را بر اساس اینکه حاوی متن جستجو هستند فیلتر می کند.
مرحله 3: برای جلوگیری از تماس مستقیم عملکرد، الگو را بهروزرسانی کنید
در الگوی کامپوننت خود، با پیوند دادن شروع می کنیم searchText
ویژگی به جعبه ورودی با استفاده از [(ngModel)]
. این اتصال دو طرفه تضمین می کند که ما searchText
ویژگی با مقدار ورودی همگام می ماند.
در مرحله بعد، از رویداد (ورودی) برای فراخوانی استفاده می کنیم onSearchTextChange()
روشی که قبلا ایجاد کردیم این تضمین میکند که روش ما فقط زمانی فراخوانی میشود که ورودی جستجو واقعاً تغییر کند، نه در هر چرخه تشخیص تغییر.
در نهایت، ما از آن استفاده خواهیم کرد *ngFor
دستور العمل به حلقه از طریق filteredItems
آرایه کنید و نتایج را نمایش دهید.
در اینجا قالب به روز شده است:
<input
[(ngModel)]="searchText"
(input)="onSearchTextChange()"
placeholder="Search items"
/>
<ul>
<li *ngFor="let item of filteredItems">
{{ item }}
</li>
</ul>
مرحله 4: از قدرت مشاهده پذیرها استفاده کنید
اکنون که کامپوننت خود را طوری تنظیم کردهایم که از فراخوانی مستقیم تابع در الگو جلوگیری کنیم، بیایید یک قدم جلوتر برویم و از قدرت مشاهدهپذیرها استفاده کنیم. Observables یک ابزار فوق العاده در زرادخانه Angular است که ما را قادر می سازد تا تغییرات داده ها را به طور موثر مدیریت کنیم و به آن واکنش نشان دهیم.
ابتدا باید Subject و Observable را از کتابخانه rxjs وارد کنیم:
import { Subject, Observable } from 'rxjs';
در مرحله بعد یک موضوع به نام ایجاد کنید searchTextChanged$
هر زمان که متن جستجو تغییر کند یک مقدار جدید منتشر می کند:
typescript
private searchTextChanged$ = new Subject<string>();
اکنون، به روز رسانی کنید onSearchTextChange()
روش انتشار جریان searchText
ارزش هر زمان که نامیده می شود:
onSearchTextChange() {
this.searchTextChanged$.next(this.searchText);
}
در نهایت یک Observable به نام ایجاد می کنیم filteredItems$
که به تغییرات گوش می دهد searchTextChanged$
و به روز رسانی می کند filteredItems
بر این اساس آرایه کنید. برای انجام این کار، از debounceTime
و distinctUntilChanged
اپراتورها از rxjs
، که کمک می کند اطمینان حاصل شود که ما فقط مقادیر متن جستجوی جدید و منحصر به فرد را پردازش می کنیم.
filteredItems$: Observable<string[]>;
constructor() {
this.filteredItems$ = this.searchTextChanged$.pipe(
debounceTime(300),
distinctUntilChanged(),
map(searchText =>
this.items.filter(item =>
item.toLowerCase().includes(searchText.toLowerCase())
)
)
);
}
و بس! با این تغییرات، مؤلفه جستجوی ما اکنون از فراخوانی مستقیم تابع در قالب اجتناب میکند و بهطور مؤثر آن را بهروزرسانی میکند filteredItems
آرایه با استفاده از قابل مشاهده
مرحله 5: از async pipe
برای قالب های تمیزتر
در حالی که مؤلفه جستجوی ما به خوبی کار می کند، می توانیم با استفاده از آن، الگوی خود را تمیزتر کنیم async pipe
. این async pipe
مشترک یک قابل مشاهده میشود و هر زمان که دادههای جدید میرسد، نمای را بهطور خودکار بهروزرسانی میکند. همچنین از لغو اشتراک در موارد قابل مشاهده در هنگام از بین رفتن مؤلفه مراقبت می کند و از نشت حافظه جلوگیری می کند.
بیایید الگوی خود را برای استفاده از آن به روز کنیم async pip
e با filteredItems$
قابل مشاهده:
<input
[(ngModel)]="searchText"
(input)="onSearchTextChange()"
placeholder="Search items"
/>
<ul>
<li *ngFor="let item of filteredItems$ | async">
{{ item }}
</li>
</ul>
اکنون الگوی ما حتی تمیزتر و قابل خواندن تر است!
مقایسه از onSearchTextChange()
برای رویکرد مبتنی بر مستقیم و قابل مشاهده
فراخوانی مستقیم تابع در قالب با onSearchTextChange(): هنگام استفاده از فراخوانی مستقیم تابع در الگو، Angular تابع را در طول هر چرخه تشخیص تغییر اجرا می کند. حتی اگر تابع به رویداد ورودی متصل است، Angular همچنان هر بار که تشخیص تغییر را اجرا میکند، فراخوانی تابع را برای تغییرات بررسی میکند. این می تواند منجر به عملکرد ضعیف شود، به خصوص اگر عملکرد از نظر محاسباتی گران باشد [in this case it is filtering in every change detection] یا برنامه دارای به روز رسانی های مکرر است.
مبتنی بر قابل مشاهده onSearchTextChange(): در این حالت تابعonSearchTextChange(
) تنها زمانی فراخوانی می شود که رویداد ورودی به لطف اتصال رویداد منتشر شود. خود تابع هیچ منطق فیلترینگی را انجام نمی دهد. در عوض، یک مقدار جدید به the منتشر می کندsearchTextChanged$
موضوع، که باعث ایجاد خط لوله قابل مشاهده برای انجام فیلتر می شود. این تضمین میکند که فیلتر کردن تنها زمانی رخ میدهد که مقدار ورودی تغییر کند، که منجر به عملکرد بهتر در مقایسه با فراخوانی مستقیم تابع در قالبها میشود.
اکنون، بیایید چند تکنیک پیشرفته و بهترین روشها را بررسی کنیم تا برنامههای Angular خود را حتی کارآمدتر و کارآمدتر کنیم.
مرحله 6: لوله های خالص برای عملکرد بهتر
Angular تعدادی لوله داخلی برای تبدیل داده ها در قالب ها فراهم می کند. به طور پیش فرض، این لوله ها “خالص” هستند، به این معنی که تنها زمانی خروجی خود را دوباره محاسبه می کنند که مقادیر ورودی آنها تغییر کند. این می تواند منجر به بهبود عملکرد قابل توجهی شود، زیرا Angular نیازی به ارزیابی مجدد خروجی لوله در طول هر چرخه تشخیص تغییر نخواهد داشت.
زمانی که تبدیل داده ای دارید که از نظر محاسباتی گران است، اما خروجی آن صرفاً توسط ورودی آن تعیین می شود، ایجاد لوله های خالص سفارشی را در نظر بگیرید. در اینجا نمونه ای از یک لوله خالص سفارشی است که لیستی از موارد را بر اساس یک عبارت جستجو فیلتر می کند:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filterItems',
pure: true,
})
export class FilterItemsPipe implements PipeTransform {
transform(items: string[], searchText: string): string[] {
return items.filter(item =>
item.toLowerCase().includes(searchText.toLowerCase())
);
}
}
برای استفاده از لوله سفارشی ما در قالب، به سادگی دستور *ngFor را با دستور زیر جایگزین کنید:
<li *ngFor="let item of items | filterItems: searchText">
{{ item }}
</li>
اکنون منطق فیلترینگ ما درون یک لوله سفارشی و خالص کپسوله شده است، که باعث می شود جزء ما کارآمدتر شود!
اکنون بیایید ()onSearchTextChange مبتنی بر مشاهده را با راه حل لوله خالص سفارشی مقایسه کنیم.
مبتنی بر قابل مشاهده onSearchTextChange(): در این حالت، زمانی که رویداد ورودی منتشر می شود، تابع فراخوانی می شود. خود تابع هیچ منطق فیلترینگی را انجام نمی دهد. در عوض، یک مقدار جدید به the منتشر می کند
searchTextChanged$
موضوع، که باعث ایجاد خط لوله قابل مشاهده برای انجام فیلتر می شود. این تضمین میکند که فیلتر کردن تنها زمانی رخ میدهد که مقدار ورودی تغییر کند، که منجر به عملکرد بهتر در مقایسه با فراخوانی مستقیم تابع در قالبها میشود.
راه حل لوله خالص سفارشی: در این مورد، ما از یک لوله خالص سفارشی برای مدیریت منطق فیلتر استفاده می کنیم. لوله های خالص کارآمدتر هستند زیرا Angular تنها زمانی خروجی آنها را دوباره محاسبه می کند که مقادیر ورودی آنها تغییر کند. این بدان معنی است که منطق فیلتر تنها زمانی اجرا می شود که مقدار ورودی یا لیست موارد تغییر کند. این رویکرد نیاز به روش جداگانه ای مانندonSearchTextChange()
و منطق فیلتر کردن داخل لوله را کپسوله می کند.
بسته شدن
تبریک می گویم! شما مقاله اجتناب از فراخوانی مستقیم تابع در قالب های Angular را تکمیل کرده اید. ما همه چیز را پوشش دادهایم، از اصول اولیه اتصال اموال و مدیریت رویداد گرفته تا تکنیکهای پیشرفته با قابل مشاهدهها و لولههای خالص. با اجرای این بهترین شیوه ها، شما در راه ساخت اپلیکیشن های Angular با کارایی بالا هستید.
به یاد داشته باشید، Angular یک فریمورک وسیع و قدرتمند با امکانات بی پایان است. به کاوش، یادگیری و به اشتراک گذاری دانش خود با جامعه ادامه دهید. به عنوان یکی از علاقه مندان به Angular، من نمی توانم صبر کنم تا ببینم چه چیزی خلق می کنید! کد نویسی مبارک!