Bird
Raised Fist0
Angularframework~8 mins

@ViewChild decorator usage in Angular - Performance & Optimization

Choose your learning style10 modes available
Performance: @ViewChild decorator usage
MEDIUM IMPACT
This affects the DOM access timing and component rendering flow, impacting interaction responsiveness and layout stability.
Accessing a child element or component in Angular
Angular
export class MyComponent {
  @ViewChild('myElement', { static: true }) myElementRef!: ElementRef;

  ngOnInit() {
    console.log(this.myElementRef.nativeElement.textContent);
  }
}
Using { static: true } allows access earlier in the lifecycle, avoiding delays and extra reflows.
📈 Performance GainSingle reflow and faster interaction readiness.
Accessing a child element or component in Angular
Angular
export class MyComponent {
  @ViewChild('myElement', { static: false }) myElementRef!: ElementRef;

  ngAfterViewInit() {
    setTimeout(() => {
      console.log(this.myElementRef.nativeElement.textContent);
    }, 0);
  }
}
Using setTimeout to access @ViewChild delays DOM access and can cause layout thrashing and unpredictable timing.
📉 Performance CostBlocks rendering for extra milliseconds and triggers multiple reflows due to delayed DOM access.
Performance Comparison
PatternDOM OperationsReflowsPaint CostVerdict
@ViewChild with static: false and setTimeoutDelayed DOM query after view initMultiple reflows due to delayed accessHigher paint cost from layout thrashing[X] Bad
@ViewChild with static: true accessed in ngOnInitEarly DOM query before view initSingle reflowLower paint cost with stable layout[OK] Good
Rendering Pipeline
The @ViewChild decorator queries the DOM for a child element or component reference. If used with static: false, the query runs after change detection, causing delayed access and potential reflows. With static: true, the query runs earlier, reducing layout shifts.
→DOM Query
→Change Detection
→Layout
→Paint
⚠️ BottleneckLayout stage due to delayed DOM queries causing reflows
Core Web Vital Affected
INP
This affects the DOM access timing and component rendering flow, impacting interaction responsiveness and layout stability.
Optimization Tips
1Use { static: true } with @ViewChild when the child element is present at compile time.
2Avoid accessing @ViewChild inside setTimeout or delayed callbacks to prevent layout thrashing.
3Access @ViewChild references as early as possible in the component lifecycle to improve responsiveness.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance benefit of using { static: true } with @ViewChild?
AIt allows earlier DOM access, reducing layout shifts and reflows.
BIt delays DOM access to after view initialization.
CIt disables change detection for the child element.
DIt automatically lazy loads the child component.
DevTools: Performance
How to check: Record a performance profile while interacting with the component. Look for long tasks or layout thrashing after view initialization.
What to look for: Check for multiple layout events or delayed scripting tasks indicating inefficient @ViewChild usage.

Practice

(1/5)
1. What is the primary purpose of the @ViewChild decorator in Angular?
easy
A. To get a reference to a template element or child component
B. To create a new Angular module
C. To define routes in the application
D. To style components dynamically

Solution

  1. Step 1: Understand the role of @ViewChild

    @ViewChild is used to access a child element or component from the template directly in the class.
  2. Step 2: Compare with other options

    Creating modules, defining routes, or styling are unrelated to @ViewChild's purpose.
  3. Final Answer:

    To get a reference to a template element or child component -> Option A
  4. Quick Check:

    @ViewChild = Reference to template element [OK]
Hint: Remember: @ViewChild grabs template elements or child components [OK]
Common Mistakes:
  • Confusing @ViewChild with routing or module decorators
  • Thinking @ViewChild creates components
  • Assuming @ViewChild styles elements
2. Which of the following is the correct syntax to use @ViewChild to get a reference to a template element with template variable #myInput?
easy
A. @ViewChild(myInput) inputElement: ElementRef;
B. @ViewChild('myInput') inputElement: ElementRef;
C. @ViewChild(#myInput) inputElement: ElementRef;
D. @ViewChild('inputElement') myInput: ElementRef;

Solution

  1. Step 1: Check correct string usage in @ViewChild

    The template variable name must be passed as a string, so it should be '@ViewChild('myInput')'.
  2. Step 2: Validate variable names and types

    The variable name in the class can be anything, here 'inputElement', and type should be ElementRef for native elements.
  3. Final Answer:

    @ViewChild('myInput') inputElement: ElementRef; -> Option B
  4. Quick Check:

    Template variable name as string in @ViewChild [OK]
Hint: Always pass template variable name as a string in @ViewChild [OK]
Common Mistakes:
  • Omitting quotes around template variable name
  • Using # inside @ViewChild argument
  • Swapping variable names and template references
3. Given the following Angular component code, what will be logged to the console after the view initializes?
  <input #myInput type="text" value="Hello">

  export class MyComponent implements AfterViewInit {
    @ViewChild('myInput') inputRef!: ElementRef<HTMLInputElement>;

    ngAfterViewInit() {
      console.log(this.inputRef.nativeElement.value);
    }
  }
medium
A. undefined
B. Error: inputRef is undefined
C. null
D. Hello

Solution

  1. Step 1: Understand @ViewChild and ngAfterViewInit timing

    @ViewChild gets the input element reference, and ngAfterViewInit runs after the view is ready, so inputRef is defined.
  2. Step 2: Access nativeElement value

    inputRef.nativeElement.value accesses the input's value attribute, which is 'Hello'.
  3. Final Answer:

    Hello -> Option D
  4. Quick Check:

    Access input value via @ViewChild after view init [OK]
Hint: Access @ViewChild only after ngAfterViewInit to get values [OK]
Common Mistakes:
  • Trying to access @ViewChild in constructor or ngOnInit
  • Assuming inputRef is null or undefined after view init
  • Confusing nativeElement with the ElementRef itself
4. Identify the error in the following Angular component code using @ViewChild:
  export class MyComponent {
    @ViewChild('myButton') buttonRef: ElementRef;

    ngOnInit() {
      this.buttonRef.nativeElement.click();
    }
  }
medium
A. Accessing @ViewChild reference before view initialization
B. Missing quotes around 'myButton' in @ViewChild
C. Using ElementRef instead of TemplateRef
D. No error, code is correct

Solution

  1. Step 1: Check lifecycle hook used

    ngOnInit runs before the view is fully initialized, so @ViewChild references are not ready yet.
  2. Step 2: Correct lifecycle hook for @ViewChild access

    Accessing @ViewChild should be done in ngAfterViewInit to ensure the element exists.
  3. Final Answer:

    Accessing @ViewChild reference before view initialization -> Option A
  4. Quick Check:

    @ViewChild ready only after ngAfterViewInit [OK]
Hint: Use ngAfterViewInit, not ngOnInit, to access @ViewChild [OK]
Common Mistakes:
  • Accessing @ViewChild in ngOnInit causing undefined errors
  • Confusing lifecycle hooks for view queries
  • Ignoring the timing of template element availability
5. You want to call a method focusInput() on a child component ChildComponent using @ViewChild. Which of the following is the correct way to do this safely after the view initializes?
hard
A. Use @ViewChild(ChildComponent) child: ElementRef; and call this.child.nativeElement.focusInput() inside ngAfterViewInit()
B. Use @ViewChild('child') child: ChildComponent; and call this.child.focusInput() inside constructor()
C. Use @ViewChild(ChildComponent) child!: ChildComponent; and call this.child.focusInput() inside ngAfterViewInit()
D. Use @ViewChild('child') child: ElementRef; and call this.child.focusInput() inside ngOnInit()

Solution

  1. Step 1: Correct @ViewChild usage for child component

    Use the component class type in @ViewChild to get the child component instance, e.g. @ViewChild(ChildComponent).
  2. Step 2: Call child method after view initialization

    Call the method inside ngAfterViewInit to ensure the child component is ready.
  3. Final Answer:

    Use @ViewChild(ChildComponent) child!: ChildComponent; and call this.child.focusInput() inside ngAfterViewInit() -> Option C
  4. Quick Check:

    Child component method call via @ViewChild after view init [OK]
Hint: Use component class in @ViewChild and call methods after ngAfterViewInit [OK]
Common Mistakes:
  • Calling child methods in constructor or ngOnInit
  • Using ElementRef instead of component class for child components
  • Trying to access nativeElement for component methods
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard