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

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

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

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

कोड को बांटना क्यों ज़रूरी होता है

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

अपने ऐप्लिकेशन की सुविधाओं से समझौता किए बिना JavaScript बंडल को छोटा करने का सबसे अच्छा तरीका है, कोड को तेज़ी से बांटना.

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

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

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

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

यह पोस्ट 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 मि॰से॰ इंतज़ार का समय दिखाया है, ताकि आप स्पिनर को काम करते हुए देख सकें.

नतीजा

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

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