अगर आप Angular में 5 साल के अनुभव वाले डेवलपर हैं और इंटरव्यू की तैयारी कर रहे हैं, तो यह ब्लॉग पोस्ट आपके लिए है। इसमें हमने उन महत्वपूर्ण प्रश्नों को शामिल किया है जो अक्सर इंटरव्यू में पूछे जाते हैं। Angular की डीप-डाइव कॉन्सेप्ट्स जैसे Change Detection, Ivy, Dependency Injection और Lazy Loading जैसी तकनीकों को समझने के लिए यह प्रश्न और उनके उत्तर आपको तैयार करेंगे। इंटरव्यू में बेहतर प्रदर्शन के लिए इन सवालों को समझकर अपनी तैयारी को और मज़बूत करें।
Q1: How does change detection work in Angular? What are the different change detection strategies?
Answer in Hindi:
Angular में Change Detection वह प्रक्रिया है जो डेटा मॉडल में हुए बदलावों के अनुसार DOM को अपडेट करती है। जब भी एप्लिकेशन में कोई इवेंट (जैसे क्लिक, इनपुट, HTTP रिस्पॉन्स) होता है, Angular पूरे कंपोनेंट ट्री को स्कैन करता है और देखता है कि क्या डेटा मॉडल में बदलाव हुआ है। अगर डेटा में कोई बदलाव पाया जाता है, तो वह संबंधित DOM को अपडेट करता है।
Angular में दो प्रमुख Change Detection स्ट्रैटेजी होती हैं:
- Default Strategy:
- यह डिफॉल्ट मोड है। इसमें Angular हर इवेंट या डेटा परिवर्तन के बाद पूरे कंपोनेंट ट्री को स्कैन करता है और उन सभी कंपोनेंट्स को रेंडर करता है जिनमें बदलाव हुआ है।
- यह ज्यादा फ्लेक्सिबल है लेकिन बड़े एप्लिकेशन में परफॉर्मेंस इश्यूज पैदा कर सकता है क्योंकि हर छोटे बदलाव पर पूरे ट्री की जांच होती है।
- OnPush Strategy:
- इस स्ट्रैटेजी का उपयोग उन कंपोनेंट्स में किया जाता है जहां डेटा इनपुट प्रॉपर्टीज़ के जरिए आता है और कंपोनेंट की स्थिति (state) नहीं बदलती।
- इसमें Angular केवल तभी Change Detection चलाता है जब इनपुट प्रॉपर्टीज़ में बदलाव होता है, जिससे परफॉर्मेंस में सुधार होता है।
- इसे उन स्थितियों में उपयोग किया जाता है जहां कंपोनेंट्स को बार-बार जांचने की ज़रूरत नहीं होती।
Answer in English:
In Angular, Change Detection is the process that keeps the DOM in sync with the data model. Whenever an event occurs (such as a click, input, or HTTP response), Angular scans the entire component tree to check if there have been any changes in the data model. If any changes are found, Angular updates the corresponding DOM.
There are two main Change Detection Strategies in Angular:
- Default Strategy:
- This is the default mode. Angular checks the entire component tree after every event or data change and renders all the components that have changed.
- It is flexible but can cause performance issues in large applications because the entire tree is checked after every small change.
- OnPush Strategy:
- This strategy is used for components where the data comes through input properties, and the component’s state does not change.
- Angular only runs Change Detection when the input properties change, improving performance.
- It is useful in cases where components don’t need to be checked frequently.
This approach ensures efficient rendering and prevents unnecessary updates to the DOM, especially in large applications.
Q2: Explain the concept of Angular Ivy. What benefits does it bring to Angular applications?
Answer in Hindi:
Angular Ivy एक नया कंपाइलिंग और रेंडरिंग इंजन है जिसे Angular 9 से पेश किया गया। Ivy का मुख्य उद्देश्य Angular एप्लिकेशन्स को तेज और छोटा बनाना है, जिससे डेवलपर अनुभव और एप्लिकेशन की परफॉर्मेंस बेहतर हो सके। Ivy के आने से Angular के अंदरूनी काम करने के तरीके में महत्वपूर्ण बदलाव आए, जिससे अधिक फ्लेक्सिबल और ऑप्टिमाइज़्ड एप्लिकेशन बनाना संभव हुआ।
Angular Ivy के मुख्य लाभ:
- छोटे बंडल साइज:
- Ivy ट्री-शेकिंग का बेहतर उपयोग करता है, यानी केवल आवश्यक कोड को अंतिम बंडल में शामिल किया जाता है। इससे एप्लिकेशन का साइज छोटा होता है और लोडिंग टाइम कम होता है।
- फास्ट कम्पाइलिंग टाइम:
- Ivy कंपाइलिंग प्रक्रिया को तेज़ करता है, जिससे डेवलपर्स के लिए एप्लिकेशन को तेजी से रन और डिबग करना संभव होता है। इससे डेवलपर अनुभव बेहतर होता है।
- बेहतर डिबगिंग:
- Ivy आपको डायरेक्ट कंपोनेंट्स और टेम्पलेट्स में बेहतर डिबगिंग टूल्स प्रदान करता है, जिससे जटिल एप्लिकेशन्स में बग को ट्रैक करना आसान हो जाता है।
- Backward Compatibility:
- Ivy पुराने Angular वर्जन्स के साथ भी कम्पैटिबल है, यानी इसे बिना किसी बड़ी समस्या के मौजूदा प्रोजेक्ट्स में लागू किया जा सकता है।
- Dynamic Component Loading:
- Ivy में डायनामिक कंपोनेंट्स को बहुत ही आसान तरीके से लोड किया जा सकता है, जो पहले जटिल था। यह फीचर एप्लिकेशन को और भी डायनामिक और इंटरएक्टिव बनाता है।
Answer in English:
Angular Ivy is a new rendering and compiling engine introduced in Angular 9. The primary goal of Ivy is to make Angular applications faster and smaller, improving both the developer experience and application performance. With Ivy, significant changes were made to how Angular works internally, allowing more flexibility and optimization.
Key Benefits of Angular Ivy:
- Smaller Bundle Sizes:
- Ivy makes better use of tree-shaking, meaning only the necessary code is included in the final bundle. This results in smaller application sizes and faster loading times.
- Faster Compile Times:
- Ivy speeds up the compile process, allowing developers to run and debug applications faster, enhancing the overall developer experience.
- Improved Debugging:
- Ivy provides better debugging tools by allowing direct access to components and templates, making it easier to track down bugs in complex applications.
- Backward Compatibility:
- Ivy is compatible with older versions of Angular, meaning it can be implemented in existing projects without major issues.
- Dynamic Component Loading:
- Ivy simplifies dynamic component loading, a feature that was previously more complex. This makes applications more dynamic and interactive.
Ivy improves both the performance and usability of Angular applications, making development faster and more efficient while delivering leaner applications for users.
Q3: What are the key differences between ViewEncapsulation.Emulated and ViewEncapsulation.ShadowDom?
Answer in Hindi:
Angular में ViewEncapsulation का उपयोग स्टाइल्स को एक कंपोनेंट तक सीमित रखने के लिए किया जाता है, जिससे यह सुनिश्चित हो सके कि एक कंपोनेंट के CSS स्टाइल्स अन्य कंपोनेंट्स को प्रभावित न करें। Angular में दो प्रमुख View Encapsulation मोड हैं: Emulated और ShadowDom।
ViewEncapsulation.Emulated:
- यह Angular का डिफ़ॉल्ट मोड है।
- इस मोड में, Angular अपने ढंग से CSS को प्रोसेस करता है ताकि कंपोनेंट के स्टाइल्स सिर्फ उसी कंपोनेंट पर लागू हों, लेकिन यह वास्तविक शैडो DOM का उपयोग नहीं करता।
- Angular प्रत्येक कंपोनेंट के HTML एलिमेंट्स में एक यूनिक एट्रिब्यूट जोड़ता है, और फिर CSS को इस यूनिक एट्रिब्यूट के साथ सीमित करता है।
- इसे “Emulated” कहा जाता है क्योंकि यह शैडो DOM जैसा व्यवहार करता है, लेकिन बिना शैडो DOM के।
ViewEncapsulation.ShadowDom:
- इस मोड में, Angular ब्राउज़र द्वारा समर्थित वास्तविक Shadow DOM का उपयोग करता है।
- Shadow DOM वेब कम्पोनेंट्स के एक फीचर का हिस्सा है, जो एक कंपोनेंट के DOM और स्टाइल्स को पूरी तरह से आइसोलेट करता है।
- इसमें स्टाइल्स और DOM को कैप्सुलेट किया जाता है ताकि वेब पेज के बाकी हिस्सों से पूरी तरह से अलग हों।
- शैडो DOM का उपयोग करने से कंपोनेंट के स्टाइल्स और स्ट्रक्चर को बाहरी दुनिया से पूरी तरह से छिपाया जा सकता है, जिससे वह पूरी तरह से आइसोलेटेड हो जाता है।
मुख्य अंतर:
- ViewEncapsulation.Emulated:
- स्टाइल्स को “इम्यूलेटेड” तरीके से कंपोनेंट तक सीमित करता है।
- वास्तविक शैडो DOM का उपयोग नहीं करता।
- स्टाइल्स को यूनिक एट्रिब्यूट के माध्यम से अलग करता है।
- ViewEncapsulation.ShadowDom:
- ब्राउज़र द्वारा समर्थित वास्तविक शैडो DOM का उपयोग करता है।
- कंपोनेंट को DOM और स्टाइल्स को पूरी तरह आइसोलेट करता है।
- इसके स्टाइल्स और संरचना पेज के बाकी हिस्सों से बिल्कुल अलग रहते हैं।
Answer in English:
In Angular, ViewEncapsulation is used to isolate styles to a component, ensuring that the CSS styles of one component do not affect others. Angular offers two main View Encapsulation modes: Emulated and ShadowDom.
ViewEncapsulation.Emulated:
- This is the default mode in Angular.
- In this mode, Angular processes CSS in a way that styles are scoped to the component but does not use real Shadow DOM.
- Angular adds a unique attribute to the component’s HTML elements and limits the CSS using this unique attribute.
- It is called “Emulated” because it behaves like Shadow DOM but without actually using Shadow DOM.
ViewEncapsulation.ShadowDom:
- In this mode, Angular uses the browser-supported Shadow DOM.
- Shadow DOM is a part of the web components specification, which encapsulates a component’s DOM and styles entirely.
- With Shadow DOM, styles and DOM are completely isolated from the rest of the page.
- Using Shadow DOM ensures that the component’s styles and structure are hidden from the outside world, making it fully isolated.
Key Differences:
- ViewEncapsulation.Emulated:
- Styles are scoped in an “emulated” way to the component.
- Does not use real Shadow DOM.
- Isolates styles through unique attributes.
- ViewEncapsulation.ShadowDom:
- Uses browser-supported real Shadow DOM.
- Completely isolates the component’s DOM and styles.
- Styles and structure are hidden from the rest of the page.
In essence, Emulated encapsulates styles using Angular’s mechanism, while ShadowDom relies on the browser’s native Shadow DOM for complete style and DOM isolation.
Q4: How would you optimize the performance of a large-scale Angular application? Provide specific techniques and tools.
Answer in Hindi:
एक बड़े पैमाने के Angular एप्लिकेशन की परफॉर्मेंस को ऑप्टिमाइज़ करना एक चुनौतीपूर्ण कार्य हो सकता है, लेकिन सही तकनीकों और टूल्स का उपयोग करके इसे काफी बेहतर किया जा सकता है। यहाँ कुछ प्रमुख तरीके और टूल्स दिए गए हैं जिनका उपयोग आप कर सकते हैं:
- Lazy Loading:
- Lazy Loading का उपयोग करके उन मोड्यूल्स को डिफर्ड (deferred) लोड किया जा सकता है जिनकी तुरंत आवश्यकता नहीं होती। इससे बंडल साइज छोटा रहता है और एप्लिकेशन तेज़ी से लोड होती है।
- Angular में Lazy Loading के लिए रूटिंग मॉड्यूल में
loadChildren
का उपयोग किया जाता है।
- Change Detection को Optimize करना:
- Change Detection स्ट्रैटेजी को OnPush मोड में सेट करें। इससे Angular केवल उन कंपोनेंट्स की जाँच करेगा जिनकी इनपुट प्रॉपर्टीज़ में बदलाव हुआ है, न कि पूरे कंपोनेंट ट्री की।
- इसके अलावा, जहाँ जरूरत हो,
detectChanges()
औरmarkForCheck()
जैसी विधियों का उपयोग करके मैन्युअली Change Detection नियंत्रित कर सकते हैं।
- trackBy का उपयोग करें:
- ngFor के साथ trackBy फ़ंक्शन का उपयोग करें। यह Angular को आइटम्स के ट्रैकिंग में मदद करता है ताकि केवल बदले हुए आइटम्स को ही DOM में अपडेट किया जाए, जिससे रेंडरिंग तेज होती है।
- Tree Shaking:
- Tree Shaking तकनीक के साथ एप्लिकेशन को छोटे बंडल में परिवर्तित करें। इसका उद्देश्य सिर्फ उन कोड को लोड करना है जो वास्तव में उपयोग में आ रहे हैं।
- Angular CLI इसका स्वचालित रूप से समर्थन करता है और इससे अनावश्यक कोड को समाप्त किया जाता है।
- आउटसाइड ज़ोन में कोड चलाएं:
- परफॉर्मेंस इश्यूज से बचने के लिए Angular के NgZone के बाहर कुछ कोड चलाएं।
runOutsideAngular()
का उपयोग करके आप Change Detection से बच सकते हैं, जैसे कि स्क्रॉल इवेंट्स या एनिमेशन के दौरान।
- परफॉर्मेंस इश्यूज से बचने के लिए Angular के NgZone के बाहर कुछ कोड चलाएं।
- एसेट्स को Optimize करें:
- इमेजेज़ और अन्य एसेट्स को कंप्रेस करें और केवल ज़रूरतमंद एसेट्स को लोड करें।
- CDN का उपयोग करके एसेट्स को तेजी से लोड किया जा सकता है।
- HTTP Requests को Optimize करें:
- HTTP Requests को बैच करें और जहाँ संभव हो वहां कॅशिंग का उपयोग करें।
- RxJS ऑपरेटर जैसे
switchMap
,debounceTime
, औरmergeMap
का उपयोग करके नेटवर्क रिक्वेस्ट्स को नियंत्रित करें ताकि अनावश्यक API कॉल्स से बचा जा सके।
- AOT (Ahead of Time) कंपाइलिंग का उपयोग करें:
- AOT कंपाइलिंग से एप्लिकेशन के कोड को पहले से कंपाइल कर लिया जाता है, जिससे लोडिंग समय तेज हो जाता है। इससे रनटाइम पर JavaScript कोड को इंटरप्रेट करने की आवश्यकता नहीं होती।
- ऑडिटिंग और मॉनिटरिंग टूल्स:
- Lighthouse: गूगल का परफॉर्मेंस ऑडिटिंग टूल है जो एप्लिकेशन की गति, SEO, और एक्सेसिबिलिटी का आकलन करता है।
- Webpack Bundle Analyzer: इससे आप बंडल साइज का एनालिसिस कर सकते हैं और देख सकते हैं कि किन हिस्सों को और ऑप्टिमाइज़ किया जा सकता है।
Answer in English:
Optimizing the performance of a large-scale Angular application can be challenging, but using the right techniques and tools can significantly improve it. Here are some key ways and tools to optimize performance:
- Lazy Loading:
- Use Lazy Loading to defer the loading of modules that are not immediately required. This keeps the bundle size smaller and allows the application to load faster.
- In Angular,
loadChildren
in the routing module is used for Lazy Loading.
- Optimize Change Detection:
- Set the Change Detection strategy to OnPush mode. This ensures that Angular only checks components whose input properties have changed, not the entire component tree.
- Additionally, you can manually control Change Detection using methods like
detectChanges()
andmarkForCheck()
.
- Use trackBy with ngFor:
- Use the trackBy function with ngFor. This helps Angular keep track of items, so only the changed items are updated in the DOM, improving rendering performance.
- Tree Shaking:
- Leverage Tree Shaking to reduce the bundle size by including only the code that is actually used.
- Angular CLI supports Tree Shaking automatically, eliminating unused code.
- Run Code Outside Angular’s Zone:
- To avoid performance issues, run some code outside Angular’s NgZone. Use
runOutsideAngular()
to bypass Change Detection for tasks like scroll events or animations.
- To avoid performance issues, run some code outside Angular’s NgZone. Use
- Optimize Assets:
- Compress images and other assets, and load only the necessary ones.
- Use a CDN to deliver assets faster.
- Optimize HTTP Requests:
- Batch HTTP requests and use caching wherever possible.
- Use RxJS operators like
switchMap
,debounceTime
, andmergeMap
to manage network requests efficiently and avoid unnecessary API calls.
- Use AOT (Ahead of Time) Compilation:
- AOT compiles the application code ahead of time, speeding up load times by eliminating the need for runtime interpretation of JavaScript code.
- Auditing and Monitoring Tools:
- Lighthouse: Google’s performance auditing tool that evaluates the speed, SEO, and accessibility of your application.
- Webpack Bundle Analyzer: Analyze your bundle size and see which parts of the code can be further optimized.
By applying these strategies, you can ensure better performance for large Angular applications, leading to faster load times, smoother interactions, and a better user experience.
Q5: Describe the Angular dependency injection system. How would you create and use a custom injector?
Answer in Hindi:
Angular का Dependency Injection सिस्टम (DI) एक डिजाइन पैटर्न है जो क्लासेज़ या सेवाओं के बीच निर्भरता को नियंत्रित करता है। Angular में DI सिस्टम के माध्यम से, आप एक कंपोनेंट, सर्विस, या अन्य क्लास में निर्भरता को इनजेक्ट कर सकते हैं, जिससे कोड मॉड्यूलर और अधिक मैनेजबल बनता है। यह मुख्य रूप से लूज़ कपलिंग के लिए इस्तेमाल होता है, यानी क्लासेज़ आपस में tightly coupled नहीं होतीं और आवश्यक सेवाओं को Angular द्वारा स्वतः इनजेक्ट किया जाता है।
Angular में DI तीन मुख्य चीज़ों पर आधारित होता है:
- Provider: यह DI सिस्टम को बताता है कि किस सर्विस या वैल्यू को इनजेक्ट करना है।
- Injector: यह उन सर्विसेज़ को क्रिएट करता है जिन्हें इनजेक्ट किया जाना है।
- Token: यह एक यूनिक आइडेंटिफायर है जिसका उपयोग सही सर्विस या वैल्यू को प्राप्त करने के लिए किया जाता है।
कस्टम इनजेक्टर कैसे बनाएं और उपयोग करें:
कभी-कभी, आपको एक कस्टम इनजेक्टर की आवश्यकता होती है, जो डिफ़ॉल्ट इनजेक्टर की बजाय एक विशिष्ट स्थिति में निर्भरता प्रदान कर सके। कस्टम इनजेक्टर बनाने के लिए आप Injector.create()
का उपयोग कर सकते हैं।
कस्टम इनजेक्टर बनाने के स्टेप्स:
- एक कस्टम प्रॉवाइडर बनाएँ: सबसे पहले, एक कस्टम प्रॉवाइडर बनाएं जो यह परिभाषित करेगा कि किस टोकन के लिए किस सर्विस को प्रदान किया जाना चाहिए।
const customInjector = Injector.create({ providers: [ { provide: MyService, useClass: MyService } ] });
- सेवा का उपभोग करें: एक बार कस्टम इनजेक्टर बना लेने के बाद, आप इसे कंपोनेंट या क्लास में इस्तेमाल कर सकते हैं और ज़रूरत के अनुसार सेवाएं प्राप्त कर सकते हैं।
const myServiceInstance = customInjector.get(MyService); myServiceInstance.someMethod();
प्रैक्टिकल उपयोग:
यह तकनीक उन मामलों में उपयोगी होती है जहाँ आपको डायनामिक रूप से सेवाओं का निर्माण और वितरण करना हो, जैसे कि डायनामिक कंपोनेंट लोडिंग या रUNTIME पर नई सेवाओं को जोड़ना।
Answer in English:
Angular’s Dependency Injection system (DI) is a design pattern that manages dependencies between classes or services. With Angular’s DI system, you can inject dependencies into a component, service, or other class, making the code more modular and maintainable. DI helps in achieving loose coupling, meaning classes are not tightly coupled and necessary services are automatically injected by Angular.
Angular’s DI is based on three main concepts:
- Provider: It tells the DI system what service or value to inject.
- Injector: It creates the instances of services that need to be injected.
- Token: A unique identifier used to retrieve the correct service or value.
How to Create and Use a Custom Injector:
Sometimes, you need a custom injector that provides dependencies in a specific context instead of using the default injector. You can create a custom injector using the Injector.create()
method.
Steps to Create a Custom Injector:
- Create a custom provider: First, create a custom provider that defines which service should be provided for a specific token.
const customInjector = Injector.create({ providers: [ { provide: MyService, useClass: MyService } ] });
- Consume the service: Once the custom injector is created, you can use it in your component or class to get the required service dynamically.
const myServiceInstance = customInjector.get(MyService); myServiceInstance.someMethod();
Practical Use:
This technique is useful in scenarios where you need to dynamically create and provide services, such as in dynamic component loading or adding services at runtime.
By using Angular’s powerful dependency injection system and custom injectors, you can make your application more flexible and maintainable.
Q6: What are NgZones in Angular? How can you run code outside of Angular’s zone?
Answer in Hindi:
NgZones Angular का एक महत्वपूर्ण फीचर है, जिसका उपयोग एप्लिकेशन के अंदर Change Detection को नियंत्रित करने के लिए किया जाता है। जब Angular में कोई इवेंट (जैसे कि बटन क्लिक, HTTP रिक्वेस्ट आदि) होता है, तो Angular के अंदर एक Zone बनाया जाता है, जिसे NgZone कहा जाता है। इस Zone का मुख्य कार्य यह सुनिश्चित करना है कि जब भी कोई इवेंट या असिंक्रोनस ऑपरेशन पूरा हो, तब Angular स्वतः Change Detection ट्रिगर कर सके ताकि UI को डेटा के साथ सिंक्रोनाइज किया जा सके।
NgZones के मुख्य कार्य:
- Angular में इवेंट्स और असिंक्रोनस ऑपरेशन्स को ट्रैक करना।
- इवेंट्स के बाद Change Detection को ट्रिगर करना ताकि UI और डेटा मॉडल सिंक में रहें।
- एप्लिकेशन के प्रदर्शन को अनुकूलित करना और अनावश्यक Change Detection से बचना।
Angular के Zone के बाहर कोड कैसे चलाएं?
कई बार, आपको ऐसा कोड चलाने की आवश्यकता होती है जो बार-बार Change Detection को ट्रिगर न करे, जैसे कि एनिमेशन, स्क्रॉलिंग, या कुछ लंबी प्रक्रियाएँ। ऐसे मामलों में, आप Angular के Change Detection ज़ोन से बाहर कोड चला सकते हैं।
Angular में, runOutsideAngular()
विधि का उपयोग करके आप यह सुनिश्चित कर सकते हैं कि कोई भी कार्य Angular के ज़ोन के बाहर चले और इससे बार-बार Change Detection ट्रिगर न हो।
Example:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-example', template: `<div (click)="performTask()">Click Me</div>` }) export class ExampleComponent { constructor(private ngZone: NgZone) {} performTask() { // This task will run outside of Angular's zone this.ngZone.runOutsideAngular(() => { // Code that you want to run outside Angular's zone this.longRunningTask(); }); } longRunningTask() { // Example of a long-running task such as scroll event, animations, etc. for (let i = 0; i < 100000; i++) { console.log(i); } // Once the task is done, you can run code back inside Angular's zone if needed this.ngZone.run(() => { // Code that should trigger Angular's change detection console.log('Task completed'); }); } }
इस कोड में, runOutsideAngular()
के जरिए लंबी प्रक्रिया को Angular के ज़ोन के बाहर चलाया गया है, जिससे बार-बार Change Detection ट्रिगर नहीं होगा। इसके बाद, यदि आवश्यक हो, तो ngZone.run()
का उपयोग करके Angular के ज़ोन के अंदर वापस आ सकते हैं।
Answer in English:
NgZones is a critical feature in Angular used to control Change Detection within the application. When an event occurs in Angular (such as a button click, HTTP request, etc.), a Zone is created inside Angular, known as NgZone. The primary purpose of this zone is to automatically trigger Change Detection whenever an event or asynchronous operation completes, ensuring that the UI stays in sync with the data.
Main functions of NgZones:
- Track events and asynchronous operations in Angular.
- Trigger Change Detection after events to keep the UI and data model synchronized.
- Optimize performance by avoiding unnecessary Change Detection cycles.
How to run code outside Angular’s zone?
There are scenarios where you may want to run code that doesn’t need to trigger Change Detection frequently, such as animations, scrolling, or long-running tasks. In such cases, you can run code outside Angular’s Change Detection zone.
In Angular, the runOutsideAngular()
method is used to execute code outside Angular’s zone, preventing unnecessary Change Detection.
Example:
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-example', template: `<div (click)="performTask()">Click Me</div>` }) export class ExampleComponent { constructor(private ngZone: NgZone) {} performTask() { // This task will run outside of Angular's zone this.ngZone.runOutsideAngular(() => { // Code that you want to run outside Angular's zone this.longRunningTask(); }); } longRunningTask() { // Example of a long-running task such as scroll event, animations, etc. for (let i = 0; i < 100000; i++) { console.log(i); } // Once the task is done, you can run code back inside Angular's zone if needed this.ngZone.run(() => { // Code that should trigger Angular's change detection console.log('Task completed'); }); } }
In this code, runOutsideAngular()
is used to execute a long-running task outside Angular’s zone, ensuring that Change Detection is not triggered repeatedly. After the task completes, you can optionally return to Angular’s zone using ngZone.run()
to trigger Change Detection if needed.
This approach helps in optimizing performance by running non-essential tasks outside of Angular’s zone, thereby preventing unnecessary updates to the DOM and improving the overall application speed.
Q7: How does lazy loading work in Angular? What are the best practices for implementing it?
Answer in Hindi:
Lazy Loading एक परफॉर्मेंस ऑप्टिमाइज़ेशन तकनीक है जिसका उपयोग Angular एप्लिकेशन में उन मॉड्यूल्स को डिफर्ड (deferred) लोड करने के लिए किया जाता है, जिनकी तुरंत आवश्यकता नहीं होती। इसका उद्देश्य यह है कि जब उपयोगकर्ता किसी विशेष फ़ीचर या पेज पर जाता है, तभी संबंधित मॉड्यूल लोड किया जाए, ताकि एप्लिकेशन का लोडिंग टाइम और बंडल साइज छोटा रहे।
Angular में Lazy Loading मुख्य रूप से रूटिंग के माध्यम से लागू किया जाता है। जब उपयोगकर्ता किसी विशेष रूट पर जाता है, तभी वह मॉड्यूल लोड होता है, जो उस रूट से जुड़ा होता है।
Lazy Loading कैसे काम करता है?
- रूट मॉड्यूल सेटअप करें:
- Lazy Loading को लागू करने के लिए, आप
loadChildren
रूटिंग स्ट्रैटेजी का उपयोग करते हैं। यह Angular को बताता है कि जब उपयोगकर्ता इस रूट पर जाएगा, तभी संबंधित मॉड्यूल लोड होना चाहिए।
उदाहरण:
const routes: Routes = [ { path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) } ];
- Lazy Loading को लागू करने के लिए, आप
- Feature Module बनाएं:
- जिस मॉड्यूल को Lazy Load करना हो, उसे अलग फ़ीचर मॉड्यूल के रूप में डिफाइन करें। इसके बाद इसे मुख्य एप्लिकेशन मॉड्यूल में शामिल नहीं करें। केवल जब उपयोगकर्ता उस मॉड्यूल की आवश्यकता होती है, तभी वह लोड होगा।
- Routing Module का उपयोग करें:
- प्रत्येक Lazy Loaded मॉड्यूल में एक रूटिंग मॉड्यूल होता है जो उस मॉड्यूल के लिए रूट्स को परिभाषित करता है। इसे मुख्य रूटिंग फ़ाइल में रजिस्टर करें और Lazy Loading कॉन्फ़िगर करें।
Lazy Loading के लिए सर्वोत्तम प्रथाएँ (Best Practices):
- सभी बड़ी फ़ीचर मॉड्यूल्स को Lazy Load करें:
- बड़े और स्वतंत्र फ़ीचर मॉड्यूल्स जैसे कि एडमिन पैनल, रिपोर्ट्स, यूज़र प्रोफाइल को Lazy Load करना चाहिए। इससे शुरुआती बंडल साइज कम होता है और एप्लिकेशन तेजी से लोड होता है।
- Preloading Modules:
- Preloading Strategy का उपयोग करें। यदि कुछ मॉड्यूल्स को Lazy Load करना ज़रूरी है, लेकिन आप चाहते हैं कि वे बैकग्राउंड में लोड हो जाएँ, तो प्रीलोडिंग का उपयोग करें।
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
- Preloading Strategy का उपयोग करें। यदि कुछ मॉड्यूल्स को Lazy Load करना ज़रूरी है, लेकिन आप चाहते हैं कि वे बैकग्राउंड में लोड हो जाएँ, तो प्रीलोडिंग का उपयोग करें।
- Avoid Loading Core Modules Lazily:
- उन मॉड्यूल्स को Lazy Load न करें जो पूरे एप्लिकेशन के लिए आवश्यक हैं, जैसे कि CoreModule या SharedModule। ये एप्लिकेशन के शुरुआती लोडिंग के लिए महत्वपूर्ण होते हैं।
- सतर्कता से रूट्स को डिज़ाइन करें:
- सुनिश्चित करें कि आपके Lazy Load रूट्स एप्लिकेशन की नेविगेशन लॉजिक के साथ मेल खाते हैं। जटिल रूट्स या गहरे नेस्टेड रूट्स में Lazy Loading ठीक से काम नहीं कर सकता।
- स्मार्ट कोड स्प्लिटिंग:
- कोड स्प्लिटिंग का इस्तेमाल करते समय यह ध्यान रखें कि Lazy Load किए गए मॉड्यूल्स के बीच कोई अनावश्यक निर्भरता न हो। इसका मतलब है कि Lazy Loaded मॉड्यूल्स को एक दूसरे पर निर्भर न होने दें, क्योंकि इससे परफॉर्मेंस लाभ कम हो सकता है।
- Optimize Third-Party Libraries:
- सुनिश्चित करें कि बड़े थर्ड-पार्टी लाइब्रेरियों को Lazy Loaded मॉड्यूल्स के भीतर ही इस्तेमाल करें। इससे लाइब्रेरी केवल तब लोड होगी जब वास्तव में जरूरत होगी।
- Use Route Guards for Authorization:
- Lazy Loaded मॉड्यूल्स के लिए सुरक्षा बढ़ाने हेतु रूट गार्ड्स (Route Guards) का उपयोग करें, ताकि कोई अनधिकृत उपयोगकर्ता उन रूट्स को एक्सेस न कर सके।
- Avoid Loading Core Modules Lazily:
- Feature Module बनाएं:
Answer in English:
Lazy Loading is a performance optimization technique in Angular that is used to defer the loading of modules that are not immediately needed. The idea is to load a module only when the user navigates to a specific feature or page, reducing the initial load time and the bundle size of the application.
In Angular, Lazy Loading is primarily implemented via routing. Modules are only loaded when the user navigates to a route that corresponds to that module.
How does Lazy Loading work?
- Setup Route Modules:
- To implement Lazy Loading, you use the
loadChildren
strategy in routing. This tells Angular to load the module only when the user navigates to a specific route.
Example:
const routes: Routes = [ { path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) } ];
- To implement Lazy Loading, you use the
- Create Feature Modules:
- The module you want to lazy load should be defined as a separate feature module. It should not be included in the main application module. It will only be loaded when the user navigates to it.
- Use a Routing Module:
- Each Lazy Loaded module should have its own routing module, defining the routes for that module. Register it in the main routing file and configure Lazy Loading.
Best Practices for Lazy Loading:
- Lazy Load Large Feature Modules:
- Large and independent feature modules, like admin panels, reports, or user profiles, should be lazy loaded. This reduces the initial bundle size and speeds up the application load time.
- Preloading Modules:
- Use the Preloading Strategy. If certain modules should be lazy loaded but preloaded in the background, use preloading.
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
- Use the Preloading Strategy. If certain modules should be lazy loaded but preloaded in the background, use preloading.
- Avoid Lazy Loading Core Modules:
- Do not lazy load core modules like CoreModule or SharedModule that are required across the entire application. These should be loaded upfront as they are crucial for the initial load.
- Design Routes Carefully:
- Ensure your lazy-loaded routes are aligned with the navigation logic of your application. Complex or deeply nested routes may not work well with lazy loading.
- Smart Code Splitting:
- When using code splitting, ensure that lazy-loaded modules do not have unnecessary dependencies on each other, as this can reduce the performance benefits.
- Optimize Third-Party Libraries:
- Ensure large third-party libraries are used inside lazy-loaded modules only. This ensures that the library is only loaded when required.
- Use Route Guards for Security:
- Use Route Guards to enhance security for lazy-loaded modules, ensuring that unauthorized users cannot access those routes.
By following these best practices, you can effectively implement Lazy Loading in your Angular applications to optimize performance and provide a better user experience.
- Avoid Lazy Loading Core Modules:
- Create Feature Modules:
Q8: Describe the differences between pure and impure pipes. When would you use each?
Answer in Hindi:
Angular में पाइप्स का उपयोग डेटा को फ़िल्टर करने, ट्रांसफ़ॉर्म करने या उसे फॉर्मेट करने के लिए किया जाता है। पाइप्स को दो प्रकारों में विभाजित किया जाता है: Pure Pipes और Impure Pipes। दोनों का उपयोग अलग-अलग परिस्थितियों में किया जाता है।
Pure Pipes:
- Pure Pipes केवल तभी कार्य करते हैं जब उनके इनपुट डेटा में बदलाव होता है। यह Angular के Change Detection साइकल के दौरान केवल तभी अपडेट होते हैं जब इनपुट प्रॉपर्टीज़ बदलती हैं।
- यह डिफ़ॉल्ट प्रकार के पाइप्स होते हैं। जब आप कोई कस्टम पाइप बनाते हैं, तो वह स्वचालित रूप से एक Pure Pipe होता है।
- ये अधिक परफॉर्मेंस-फ्रेंडली होते हैं क्योंकि केवल आवश्यक समय पर ही रेंडर होते हैं और अनावश्यक Change Detection से बचते हैं।
उपयोग कब करें: Pure Pipes तब उपयोग किए जाते हैं जब आपको स्थिर डेटा या संरचनात्मक रूप से अपरिवर्तनीय डेटा की जरूरत होती है, जैसे:
- किसी संख्या को फ़ॉर्मेट करना
- टेक्स्ट को अप्परकेस में बदलना
- एक ही डेटा को बार-बार प्रक्रिया करने की आवश्यकता न हो
उदाहरण:
@Pipe({ name: 'uppercase' }) export class UppercasePipe implements PipeTransform { transform(value: string): string { return value.toUpperCase(); } }
Impure Pipes:
- Impure Pipes हर बार Change Detection साइकल के दौरान काम करते हैं, चाहे इनपुट में कोई बदलाव हो या न हो।
- यह उन डेटा के साथ काम करने के लिए उपयोगी होते हैं जो बार-बार या तेजी से बदलते रहते हैं, जैसे कि Arrays, Objects, या असंरचित डेटा।
- Impure Pipes को परफॉर्मेंस पर भारी असर डाल सकते हैं क्योंकि ये बार-बार रेंडर होते हैं, यहां तक कि छोटे बदलावों पर भी।
उपयोग कब करें: Impure Pipes का उपयोग तब किया जाता है जब इनपुट डेटा बार-बार बदल रहा हो या जब ऑब्जेक्ट्स और एरेज जैसी डेटा संरचनाएँ बार-बार अपडेट हो रही हों, जैसे:
- जब आपको एक ऐसा पाइप चाहिए जो Arrays, Objects, या अन्य म्यूटेबल डेटा के साथ काम कर सके
- जब आपके पास एक असंरचित डेटा स्ट्रक्चर हो जो Change Detection में बार-बार बदलता हो
उदाहरण:
@Pipe({ name: 'filterArray', pure: false // Marking the pipe as impure }) export class FilterArrayPipe implements PipeTransform { transform(items: any[], searchText: string): any[] { if (!items) return []; return items.filter(item => item.includes(searchText)); } }
मुख्य अंतर:
- Pure Pipes:
- केवल तब काम करते हैं जब इनपुट में बदलाव होता है।
- Angular के Change Detection के दौरान कम बार अपडेट होते हैं।
- डिफ़ॉल्ट होते हैं और परफॉर्मेंस-फ्रेंडली होते हैं।
- Impure Pipes:
- हर बार Change Detection साइकल में काम करते हैं, चाहे इनपुट में बदलाव हो या न हो।
- बार-बार रेंडर होते हैं, जिससे परफॉर्मेंस पर असर पड़ सकता है।
- इन्हें
pure: false
के साथ घोषित किया जाता है।
Answer in English:
Pipes in Angular are used to filter, transform, or format data. Pipes are categorized into two types: Pure Pipes and Impure Pipes. Each type is used in different scenarios.
Pure Pipes:
- Pure Pipes work only when their input data changes. They update only when input properties change during Angular’s Change Detection cycle.
- These are the default type of pipes. When you create a custom pipe, it is automatically a pure pipe.
- Pure pipes are performance-friendly because they render only when necessary, avoiding unnecessary Change Detection.
When to use: Pure pipes are used when you have stable or immutable data, such as:
- Formatting a number
- Converting text to uppercase
- When data does not need frequent processing
Example:
@Pipe({ name: 'uppercase' }) export class UppercasePipe implements PipeTransform { transform(value: string): string { return value.toUpperCase(); } }
Impure Pipes:
- Impure Pipes execute every time during the Change Detection cycle, even if the input data has not changed.
- They are useful for working with data that changes frequently or rapidly, such as arrays, objects, or unstructured data.
- Impure pipes can impact performance negatively as they render frequently, even for small changes.
When to use: Impure pipes should be used when input data is changing frequently or when dealing with mutable data structures like arrays or objects, such as:
- When you need a pipe to work with arrays, objects, or mutable data
- When your data structure changes frequently during Change Detection
Example:
@Pipe({ name: 'filterArray', pure: false // Marking the pipe as impure }) export class FilterArrayPipe implements PipeTransform { transform(items: any[], searchText: string): any[] { if (!items) return []; return items.filter(item => item.includes(searchText)); } }
Key Differences:
- Pure Pipes:
- Work only when the input data changes.
- Updated less frequently during Angular’s Change Detection.
- Default type, and are performance-friendly.
- Impure Pipes:
- Execute on every Change Detection cycle, even if the input data does not change.
- Render frequently, which can impact performance.
- Declared with
pure: false
.
By understanding the use cases for both pure and impure pipes, you can select the appropriate one based on how frequently your data changes and the performance requirements of your Angular application.
Q9: Explain the concept of Angular schematics. How would you create a custom schematic?
Answer in Hindi:
Angular Schematics एक कोड जनरेशन टूल है जिसे Angular CLI द्वारा उपयोग किया जाता है। इसका उद्देश्य कोड को ऑटोमेटिकली जनरेट करना, मॉड्यूल्स या कम्पोनेंट्स बनाना, और प्रोजेक्ट स्ट्रक्चर को ऑर्गनाइज़ करना है। Schematics आपको Angular प्रोजेक्ट्स में रिफैक्टरिंग करने, अपडेट्स लागू करने और नए फीचर्स जोड़ने में मदद करता है, जिससे मैन्युअल काम कम हो जाता है और कोड कंसिस्टेंट रहता है।
Angular CLI में पहले से कई Schematics होते हैं, जैसे कि ng generate component
, ng generate service
इत्यादि। ये आपको प्रोजेक्ट में नई फ़ाइल्स बनाने और उन्हें एक संगठित तरीके से प्रोजेक्ट में जोड़ने में मदद करते हैं। यदि आपको किसी विशेष आवश्यकता के लिए कस्टम कोड जनरेट करने की जरूरत है, तो आप एक कस्टम Schematic बना सकते हैं।
Angular Schematic के मुख्य उपयोग:
- कोड जनरेशन: Components, Directives, Services, Modules, आदि को ऑटोमेटिकली जनरेट करना।
- रिफैक्टरिंग: प्रोजेक्ट कोडबेस को ऑर्गनाइज़ और अपडेट करना।
- टेम्पलेट्स बनाना: रिपीट होने वाले कोड को ऑटोमेटिक रूप से जनरेट करना।
- प्रोजेक्ट सेटअप: नए प्रोजेक्ट्स के लिए कॉन्फ़िगरेशन फ़ाइल्स और बेसिक स्ट्रक्चर तैयार करना।
कस्टम Schematic कैसे बनाएं?
- Angular Schematics CLI इंस्टॉल करें: सबसे पहले, आपको Angular Schematics CLI को ग्लोबल रूप से इंस्टॉल करना होगा ताकि आप कस्टम स्कीमैटिक बना सकें।
npm install -g @angular-devkit/schematics-cli
- नया Schematic प्रोजेक्ट सेटअप करें: एक नया Schematic प्रोजेक्ट जनरेट करने के लिए, आप
schematics
कमांड का उपयोग कर सकते हैं।schematics blank --name=my-schematic cd my-schematic
- Schematic Logic जोड़ें: Schematic प्रोजेक्ट में
src/
डायरेक्टरी होती है, जिसमें मुख्य कोड होता है। यहाँindex.ts
फ़ाइल में, आप अपने Schematic की मुख्य लॉजिक जोड़ सकते हैं। उदाहरण के लिए, एक नया कंपोनेंट जनरेट करने का कोड लिख सकते हैं:import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; export function mySchematic(_options: any): Rule { return (tree: Tree, _context: SchematicContext) => { tree.create('hello.txt', 'Hello World'); return tree; }; }
यह उदाहरण एक
hello.txt
फ़ाइल को प्रोजेक्ट में जोड़ देगा जिसमें “Hello World” लिखा होगा। - Schema.json सेटअप करें:
schema.json
फ़ाइल में आपके Schematic के लिए विकल्पों (options) को परिभाषित किया जाता है। आप इसके जरिए कस्टम इनपुट्स ले सकते हैं, जैसे फ़ाइल का नाम या पाथ।{ "$schema": "http://json-schema.org/schema", "id": "MySchematic", "title": "My Custom Schematic", "type": "object", "properties": { "name": { "type": "string", "description": "The name of the component", "default": "my-component" } } }
- Schematic का परीक्षण करें: स्कीमैटिक को लोकल टेस्ट करने के लिए, आप निम्न कमांड का उपयोग कर सकते हैं:
schematics .:my-schematic --dry-run
यह स्कीमैटिक को रन करेगा लेकिन कोई वास्तविक बदलाव नहीं करेगा, केवल यह दिखाएगा कि क्या बदलाव होगा। आप
--dry-run=false
उपयोग कर इसे असलियत में लागू कर सकते हैं। - स्कीमैटिक को पब्लिश करें: यदि आप अपना Schematic अन्य प्रोजेक्ट्स में उपयोग करना चाहते हैं, तो आप इसे
npm
पर पब्लिश कर सकते हैं:npm publish
कस्टम Schematic के फायदे:
- प्रोडक्टिविटी में वृद्धि: कस्टम Schematics आपको बार-बार किए जाने वाले टास्क्स को ऑटोमेट करने की सुविधा देते हैं।
- कंसिस्टेंसी: जब आप कस्टम टेम्पलेट्स और स्ट्रक्चर्स का उपयोग करते हैं, तो यह सुनिश्चित होता है कि पूरे प्रोजेक्ट में एकसमानता बनी रहे।
- रिफैक्टरिंग में मदद: आप बड़ी कोडबेस को ऑर्गनाइज और रिफैक्टर करने के लिए भी स्कीमैटिक्स का उपयोग कर सकते हैं।
Answer in English:
Angular Schematics is a code generation tool used by the Angular CLI. It automates the creation of components, services, modules, or any project structure, helping you maintain consistency and reducing manual work. Schematics are especially helpful for refactoring, implementing updates, and adding new features to Angular projects.
Angular CLI already includes several default schematics like ng generate component
, ng generate service
, etc. These help you generate new files and organize them in your project. If you have specific requirements for generating custom code, you can create a custom schematic.
Key uses of Angular Schematics:
- Code Generation: Automatically generating components, directives, services, modules, etc.
- Refactoring: Organizing and updating the project codebase.
- Template Creation: Automatically generating repetitive code.
- Project Setup: Setting up configuration files and project structure for new projects.
How to create a custom schematic?
- Install the Angular Schematics CLI: First, install the Angular Schematics CLI globally to create custom schematics.
npm install -g @angular-devkit/schematics-cli
- Set up a new schematic project: Generate a new schematic project using the
schematics
command.schematics blank --name=my-schematic cd my-schematic
- Add Schematic Logic: In the schematic project, the
src/
directory contains the main code. Inindex.ts
, you can add the logic for your schematic. For example, to create a new component or file:import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; export function mySchematic(_options: any): Rule { return (tree: Tree, _context: SchematicContext) => { tree.create('hello.txt', 'Hello World'); return tree; }; }
This example will create a
hello.txt
file in the project with the text “Hello World.” - Set up Schema.json: The
schema.json
file defines options (inputs) for your schematic. You can customize inputs like file names, paths, etc.{ "$schema": "http://json-schema.org/schema", "id": "MySchematic", "title": "My Custom Schematic", "type": "object", "properties": { "name": { "type": "string", "description": "The name of the component", "default": "my-component" } } }
- Test the schematic: To test your schematic locally, run:
schematics .:my-schematic --dry-run
This will simulate the schematic without making any actual changes. To apply the changes, run it without
--dry-run
. - Publish the schematic: If you want to share your schematic for use in other projects, publish it to
npm
:npm publish
Benefits of Custom Schematics:
- Increased Productivity: Custom schematics automate repetitive tasks, saving time.
- Consistency: Using custom templates ensures that the project structure and code stay consistent.
- Helps in Refactoring: Schematics can help in organizing and refactoring large codebases.
By creating custom schematics, you can significantly improve the workflow in Angular projects, reduce manual work, and maintain consistent code structures across the project.