ویژگی های جدید Angular 8: قابلیت Differential loading و تغییرات دیگر

12 شهریور 1398
angular-8-new-features-2

ویژگی های جدید Angular 8

Angular (تلفظ اصلی: اَنگیولار - در ایران به آن آنگولار گفته می شود) یک فریم ورک open-source و font-end است که بر پایه ی جاوا اسکریپت کار میکند. گوگل و برخی از شرکت های دیگر از این فریم ورک پشتیبانی کرده و مسئول مدیریت و به روز رسانی آن هستند. هدف این فریم ورک در وهله ی اول از بین بردن مشکلات موجود در زمینه ی طراحی صفحات SPA است. تاریخ اولین انتشار این فریم ورک در 20 اکتبر سال 2010 بوده است و تا به حال دچار تغییرات زیادی شده است. حالا پس از انتظاری طولانی بالاخره نسخه ی هشتم Angular منتشر شده است و ما هم مثل شما کنجکاو هستیم که چه چیزهایی تغییر کرده است و ویژگی های جدید Angular 8 چیست. در قسمت قبل دو مورد از اساسی ترین این تغییرات را بررسی کردیم و حالا نوبت به بررسی موارد جزئی تر است.

قابلیت Differential loading

معرفی ECMAScript 2015 و نسخه های جدید تر آن تاثیر بسزایی در سرعت وب گردی کاربران داشته است. این نسخه های جدید جاوا اسکریپت بهینه تر هستند و bundle های کوچک تری تولید میکنند. همچنین مرورگرها نیز می توانند این دسته از کدها را سریع تر و راحت تر تفسیر کنند اما استفاده از این کدهای جدید ممکن است مشکل ساز شود چرا که بسیاری از کاربران از مرورگرهای قدیمی استفاده می کنند و کدهای جدید در آن ها کار نمی کنند.

CLI آنگولار یک قابلیت جدید به نام differential loading را اضافه کرده است. ایده ی اصلی آن ارائه ی دو نوع bundle است: یکی بر اساس ECMAScript 5 که مخصوص مرورگرهای قدیمی است و دیگری بر اساس ECMAScript 2015 و نسخه های جدید تر که مخصوص مرورگرهای جدیدتر است. بنابراین شما می توانید از سرعت بهتر در مرورگرهای جدید استفاده کنید اما اگر کاربرانتان از مرورگرهای قدیمی استفاده می کنند هنوز هم می توانند سایت شما را مشاهده کنند.

برای فعال سازی differential loading کافی است که حد بالا و پایینی را برای نسخه های ES تعیین کنید. تعیین بالاترین حد در فایل tsconfig.json انجام می شود:

"target": "es2015"

حد پایین نیز در یک browserslist ذخیره می شود؛ لیستی از مرورگرها که نسخه های مختلف مرورگرها را شناسایی می کند. این اطلاعات می تواند در فایلی به نام browserslist ذخیره شود (CLI این فایل را میسازد). به طور مثال این دستور CLI کار را برایمان انجام می دهد:

> 0.5%
last 2 versions
Firefox ESR
not dead
IE 9-11

در کد بالا browserslist به مرورگرهای ECMAScript 5 اشاره دارد (شروع با مرورگرهای IE9 تا IE11) بنابراین CLI نیز حد پایین را همین مرورگرها در نظر می گیرد. حالا اگر دستور ng build در CLI اجرا شود، عملیات کامپایل و ساخت bundle برای هر دو نسخه انجام می شود:

اگر از differential loading استفاده کنید دو نسخه ی متفاوت برای build نهایی ساخته می شود که زمان لازم برای این ساخت را دو برابر خواهد کرد.
اگر از differential loading استفاده کنید دو نسخه ی متفاوت برای build نهایی ساخته می شود که زمان لازم برای این ساخت را دو برابر خواهد کرد.

عیب این روش در اینجا مشخص می شود: زمان build دو برابر خواهد شد!

حالا مرورگرها می توانند انتخاب کنند که از کدام نسخه استفاده کنند. مرورگرهای قدیمی دستور nomodule را در یک script درون index.html دریافت میکنند بنابراین از module های ECMAScript  استفاده نخواهند کرد. مرورگرهای جدید نیز یک type از نوع module میگیرند:

<script src="main-es2015.js" type="module"></script>
 
<script src="main-es5.js" nomodule></script>

تغییر در Lazy loading

قابلیت Lazy loading از نسخه های اولیه ی Angular در دسترس ما بوده است. برای استفاده از آن باید module بارگذاری را به این شکل تنظیم می کردیم:

{
    path: 'lazy',
    loadChildren: () => './lazy/lazy.module#LayzModule'
}

رشته ی قبل از علامت # نشان دهنده ی مسیر فایل و رشته ی بعد از آن نشان دهنده ی کلاس مورد نظر است. این روش هنوز هم در Angular 8 کار می کند اما منسوخ است و از دستورات جدید import (در ECMAScript) استفاده شده است:

{
{
    path: 'lazy',
    loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}

تغییر در ViewChild و ContentChild

نسخه ی جدید آنگولار در زمینه ی استفاده از ViewChild و ContentChild دچار تغییرات اساسی و مهمی شده است. این دو دستور در نسخه های قدیمی همیشه رفتار ثابتی نداشتند. با اینکه این دستورات برای دسترسی یک کامپوننت به عناصر خارج از ngIf و ngFor استفاده می شد اما نتیجه ی کوئری همیشه در ngOnInit موجود بود. در غیر این صورت برنامه می توانست در همان ابتدا با استفاده از ngAfterViewInit (یا ngAfterContentInit برای دستور ContentChild) به آن دسترسی داشته باشد.

برنامه ی ما برای عناصری که به دلیل data binding بعدا به DOM اضافه می شدند، مجبور بود ngAfterViewChecked یا ngAfterContentChecked را اضافه کند. از آنجایی که این فرآیند گیج کننده بود تصمیم گرفته شد که از این به بعد کامپوننت ها دقیقا مشخص کنند این عملیات در چه قسمتی انجام می شود:

@ViewChild('info', { static: false })
  paragraph: ElementRef;

اگر static مقدار true داشته باشد، آنگولار سعی می کند در هنگام راه اندازی اولیه ی کامپوننت، عنصر مورد نظر را پیدا کند. این حالت فقط زمانی جواب می دهد که درون structural directive نباشیم اما با استفاده از static: false می گوییم ابتدا view را کامل کن و سپس به دنبال عنصر مورد نظر بگرد. درخواست هایی که از ViewChildren و ContentChildren استفاده می کنند تحت تاثیر این تغییر نخواهند بود چرا که همیشه به صورت static: false عمل کرده اند.

ویژگی های جدید برای ngUpgrade

یکی از مشکلات اصلی اجرای AngularJS 1.x به همراه Angular (با استفاده از ngUpgrade) این بوده است که router های هر دو فریم ورک با هم بر سر URL درگیری دارند. این موضوع باعث مشکلات زیادی شده بود اما جدیدا راه حلی برای آن در نظر گرفته شده است. خدمات Location یکسان برای دسترسی به URL در هر دو فریم ورک اضافه شده است تا از این بابت هیچ مشکلی نداشته باشیم. برای دست یابی به این راه حل، تیم توسعه ی آنگولار خدمات Location این فریم ورک را توسعه داده است و جایگزین مناسبی برای $location در AngularJS در نظر گرفته است. به همین دلیل متد onUrlChange نیز به خدمات Location اضافه شده است:

export class AppComponent {
  constructor(loc: Location, pLoc: PlatformLocation) {
    loc.onUrlChange((url) => console.debug('url change', url));
    console.debug('hostname: ', pLoc.hostname);
  }
}

خدمات PlatformLocation به شما اجازه می دهد که به قسمت های خاص و جداگانه ی URL نیز دسترسی داشته باشید. برای مطالعه ی بیشتر در این مورد می توانید به این صفحه سری بزنید.

بنچ‌مارک بین Angular 7 و Angular 8

تمامی این تغییرات و قابلیت های جدید بسیار عالی هستند اما اکثر افرادی که به نسخه های جدید تر آنگولار بروزرسانی میکنند دنبال یک چیز هستند: سرعت بالاتر! به همین دلیل سعی کرده ایم که یک بنچ‌مارک ساده از دو نسخه ی جدید Angular بگیریم تا تغییرات نسخه ی جدید را در عمل ببینیم. برای این تست یک برنامه ی جدید ساخته شد (دستورات ng new و ng build --prod) و خود تست با audit tab مرورگر کروم و در حالت Applied Fast 3G, 4X CPU Slowdown (همراه با شبیه سازی حالت گوشی های همراه) اجرا شد.

نتایج تست Angular 7.2 - حجم نهایی برنامه: 240 کیلوبایت
نتایج تست Angular 7.2 - حجم نهایی برنامه: 240 کیلوبایت
نتایج تست Angular 8 - حجم نهایی برنامه برای مرورگر های قدیمی 250 کیلوبایت و حجم نهایی برای مرورگر های جدید: 170 کیلوبایت بوده است
نتایج تست Angular 8 - حجم نهایی برنامه برای مرورگرهای قدیمی 250 کیلوبایت و حجم نهایی برای مرورگرهای جدید: 170 کیلوبایت بوده است.

همانطور که گفتیم Angular 8 دو نسخه ی متفاوت برای مرورگرهای قدیمی و جدید ارائه می دهد به همین دلیل دو عدد برای حجم نهایی پروژه ذکر شده است. همانطور که می بنیید Angular 8 نسبت به Angular 7 در حد قابل توجهی سریع تر است و بهتر است که همین امروز فریم ورک خود را بروزرسانی کنید. دلیل برای ماندن با نسخه های قبلی وجود ندارد.

جمع بندی بحث

با همه ی این تغییرات تیم توسعه ی آنگولار به قول خود عمل کرده است و بروزرسانی به نسخه ی 8 این فریم ورک را در حد ساده ای نگه داشته است. شما می توانید بدون زحمت زیاد و به راحتی فریم ورک خود را بروزرسانی کنید. Differential loading به ما اجازه می دهد که بر اساس مرورگر کاربران خود و پشتیبانی آن ها از قابلیت های جدید دو نسخه ی متفاوت از سایت خود را به آن ها ارائه کنیم تا هر دو گروه از بهترین قابلیت ها استفاده کنند. web worker ها نیز به سرعت در حال ورود به دنیای جدید وب هستند و می توانند پردازش ها و محاسبات بسیار سنگین را در پس زمینه ی سایت ما اجرا کنند. اگر شما هم از توسعه دهندگان کنجکاو Angular هستید یادتان نرود که به Ivy نیز سری بزنید!

نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.