ऐंगुलर में रूट-लेवल कोड का बंटवारा

रूट-लेवल पर कोड को अलग-अलग करने की सुविधा का इस्तेमाल करके, अपने ऐप्लिकेशन की परफ़ॉर्मेंस को बेहतर बनाएं!

इस पोस्ट में Angular ऐप्लिकेशन में रूट-लेवल पर कोड विभाजन सेट अप करने का तरीका बताया गया है. इससे JavaScript बंडल का साइज़ कम हो सकता है और Time to Interactive में बहुत सुधार हो सकता है.

इस लेख में दिए गए कोड के सैंपल, GitHub पर देखे जा सकते हैं. इगियर रूटिंग का उदाहरण, इगियर शाखा में उपलब्ध है. रूट-लेवल पर कोड को बांटने का उदाहरण लेज़ी ब्रांच में है.

कोड को अलग-अलग हिस्सों में बांटने की सुविधा क्यों ज़रूरी है

वेब ऐप्लिकेशन की जटिलता की वजह से, उपयोगकर्ताओं के लिए JavaScript की शिपिंग की संख्या में काफ़ी बढ़ोतरी हुई है. बड़ी JavaScript फ़ाइलों की वजह से, इंटरैक्टिविटी में काफ़ी देरी हो सकती है. इसलिए, खास तौर पर मोबाइल पर, यह एक महंगा संसाधन हो सकता है.

अपने ऐप्लिकेशन की सुविधाओं को कम किए बिना, JavaScript बंडलों को छोटा करने का सबसे असरदार तरीका है, कोड को अलग-अलग करने की सुविधा का इस्तेमाल करना.

कोड को अलग-अलग करने की सुविधा की मदद से, अपने ऐप्लिकेशन के JavaScript को अलग-अलग रूट या सुविधाओं से जुड़े कई हिस्सों में बांटा जा सकता है. इस तरीके से, उपयोगकर्ताओं को सिर्फ़ वह JavaScript भेजा जाता है जो ऐप्लिकेशन के शुरुआती लोड के दौरान ज़रूरी होता है. इससे, लोड होने में लगने वाला समय कम हो जाता है.

कोड को बांटने की तकनीकें

कोड को दो लेवल पर बांटा जा सकता है: कॉम्पोनेंट लेवल और रूट लेवल.

  • कॉम्पोनेंट-लेवल पर कोड को अलग-अलग करने की सुविधा में, कॉम्पोनेंट को उनके अपने JavaScript चंक में ले जाया जाता है. साथ ही, ज़रूरत पड़ने पर उन्हें धीरे-धीरे लोड किया जाता है.
  • रूट-लेवल कोड स्प्लिटिंग में, हर रूट की फ़ंक्शन को अलग-अलग चंक में रखा जाता है. जब उपयोगकर्ता आपके ऐप्लिकेशन पर नेविगेट करते हैं, तो वे अलग-अलग रूट से जुड़े चंक फ़ेच करते हैं. साथ ही, ज़रूरत पड़ने पर उनसे जुड़ी सुविधाएं भी पाते हैं.

इस पोस्ट में, Angular में रूट-लेवल पर स्प्लिटिंग सेट अप करने के बारे में बताया गया है.

सैंपल ऐप्लिकेशन

Angular में रूट-लेवल पर कोड को अलग-अलग करने की सुविधा का इस्तेमाल करने के तरीके के बारे में जानने से पहले, एक सैंपल ऐप्लिकेशन देखें:

ऐप्लिकेशन के मॉड्यूल लागू करने का तरीका देखें. AppModule में दो रूट तय किए गए हैं: HomeComponent से जुड़ा डिफ़ॉल्ट रूट और NyanComponent से जुड़ा nyan रूट:

@NgModule({
  ...
  imports: [
    BrowserModule,
    RouterModule.forRoot([
      {
        path: '',
        component: HomeComponent,
        pathMatch: 'full'
      },
      {
        path: 'nyan',
        component: NyanComponent
      }
    ])
  ],
  ...
})
export class AppModule {}

रूट-लेवल पर कोड को बांटना

कोड को अलग-अलग हिस्सों में बांटने की सुविधा सेट अप करने के लिए, nyan ईगर रूट को फिर से लिखना होगा.

Angular CLI के 8.1.0 वर्शन में, इस निर्देश के साथ आपके लिए सब कुछ किया जा सकता है:

ng g module nyan --module app --route nyan

इससे ये जनरेट होंगे: - NyanModule नाम का एक नया रूटिंग मॉड्यूल - AppModule में nyan नाम का एक रूट, जो NyanModule को डाइनैमिक तौर पर लोड करेगा - NyanModule में एक डिफ़ॉल्ट रूट - NyanComponent नाम का एक कॉम्पोनेंट, जो उपयोगकर्ता के डिफ़ॉल्ट रूट पर जाने पर रेंडर होगा

चलिए, इन चरणों को मैन्युअल तरीके से पूरा करते हैं, ताकि हमें Angular के साथ कोड को अलग-अलग हिस्सों में बांटने की सुविधा को लागू करने के बारे में बेहतर जानकारी मिल सके!

जब उपयोगकर्ता nyan रूट पर जाता है, तो राउटर, राउटर आउटलेट में NyanComponent को रेंडर करेगा.

Angular में रूट-लेवल के कोड को बांटने की सुविधा का इस्तेमाल करने के लिए, रूट के एलान की loadChildren प्रॉपर्टी सेट करें और इसे डाइनैमिक इंपोर्ट के साथ जोड़ें:

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

इगरी रूट से दो मुख्य अंतर हैं:

  1. आपने component के बजाय, loadChildren को सेट किया है. रूट-लेवल पर कोड को अलग-अलग करने की सुविधा का इस्तेमाल करते समय, आपको कॉम्पोनेंट के बजाय डाइनैमिक तौर पर लोड होने वाले मॉड्यूल पर ले जाना होगा.
  2. loadChildren में, प्रॉमिस पूरा होने के बाद, NyanComponent के बजाय NyanModule दिखाया जाता है.

ऊपर दिए गए स्निपेट से पता चलता है कि जब उपयोगकर्ता nyan पर जाता है, तो Angular को nyan डायरेक्ट्री से nyan.module को डाइनैमिक तौर पर लोड करना चाहिए और मॉड्यूल में बताए गए डिफ़ॉल्ट रूट से जुड़े कॉम्पोनेंट को रेंडर करना चाहिए.

इस एलान का इस्तेमाल करके, डिफ़ॉल्ट रूट को कॉम्पोनेंट के साथ जोड़ा जा सकता है:

import { NgModule } from '@angular/core';
import { NyanComponent } from './nyan.component';
import { RouterModule } from '@angular/router';

@NgModule({
  declarations: [NyanComponent],
  imports: [
    RouterModule.forChild([{
      path: '',
      pathMatch: 'full',
      component: NyanComponent
    }])
  ]
})
export class NyanModule {}

जब उपयोगकर्ता https://example.com/nyan पर जाता है, तो यह कोड NyanComponent रेंडर करता है.

यह देखने के लिए कि Angular राउटर आपके लोकल एनवायरमेंट में nyan.module को लैज़ी तरीके से डाउनलोड करता है या नहीं:

  1. DevTools खोलने के लिए, `Control+Shift+J` (या Mac पर `Command+Option+J`) दबाएं.
  2. नेटवर्क टैब पर क्लिक करें.

  3. सैंपल ऐप्लिकेशन में, NYAN पर क्लिक करें.

  4. ध्यान दें कि nyan-nyan-module.js फ़ाइल, नेटवर्क टैब में दिखती है.

रूट-लेवल पर कोड को अलग-अलग करने की सुविधा की मदद से, JavaScript बंडलों को धीरे-धीरे लोड करना

यह उदाहरण GitHub पर देखें.

स्पिनर दिखाना

फ़िलहाल, जब कोई उपयोगकर्ता NYAN बटन पर क्लिक करता है, तो ऐप्लिकेशन यह नहीं दिखाता कि वह बैकग्राउंड में JavaScript लोड कर रहा है. स्क्रिप्ट लोड होने के दौरान उपयोगकर्ता को सुझाव देने के लिए, आपको स्पिनर जोड़ना होगा.

ऐसा करने के लिए, app.component.html में router-outlet एलिमेंट के अंदर इंडिकेटर के लिए मार्कअप जोड़ें:

<router-outlet>
  <span class="loader" *ngIf="loading"></span>
</router-outlet>

इसके बाद, रूटिंग इवेंट को मैनेज करने के लिए AppComponent क्लास जोड़ें. यह क्लास, RouteConfigLoadStart इवेंट सुनने पर loading फ़्लैग को true पर सेट करेगी और RouteConfigLoadEnd इवेंट सुनने पर फ़्लैग को false पर सेट करेगी.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  loading: boolean;
  constructor(router: Router) {
    this.loading = false;
    router.events.subscribe(
      (event: RouterEvent): void => {
        if (event instanceof NavigationStart) {
          this.loading = true;
        } else if (event instanceof NavigationEnd) {
          this.loading = false;
        }
      }
    );
  }
}

नीचे दिए गए उदाहरण में, हमने 500 मिलीसेकंड का आर्टिफ़िशियल इंतज़ार जोड़ा है, ताकि आप स्पिनर को काम करते हुए देख सकें.

नतीजा

रूट-लेवल पर कोड को अलग-अलग करने की सुविधा लागू करके, अपने Angular ऐप्लिकेशन के बंडल का साइज़ कम किया जा सकता है:

  1. डाइनैमिक सीएलआई लेज़ी लोडेड मॉड्यूल जनरेटर का इस्तेमाल करें, ताकि डाइनैमिक तरीके से लोड होने वाले रास्ते अपने-आप लोड हो सकें.
  2. जब कोई उपयोगकर्ता लेज़ी रूट पर जा रहा हो, तब यह दिखाने के लिए कि कोई कार्रवाई चल रही है या नहीं, लोड होने का इंडिकेटर जोड़ें.