Bird
Raised Fist0
Angularframework~8 mins

ngDoCheck for custom change detection in Angular - Performance & Optimization

Choose your learning style10 modes available
Performance: ngDoCheck for custom change detection
HIGH IMPACT
This affects the interaction responsiveness and rendering speed by controlling how often Angular checks for changes in components.
Detecting changes in a component with complex or non-primitive data
Angular
export class MyComponent implements DoCheck {
  private oldValue: any;
  ngDoCheck() {
    if (this.hasChanged(this.data, this.oldValue)) {
      this.oldValue = this.data;
      this.updateView();
    }
  }
  hasChanged(newVal: any, oldVal: any) {
    // shallow reference comparison
    return newVal !== oldVal;
  }
  updateView() {
    // update UI only when needed
  }
}
Runs update logic only when data actually changes, reducing unnecessary work and improving responsiveness.
📈 Performance Gainreduces work during change detection cycles by up to 90%, improving INP and reducing UI blocking
Detecting changes in a component with complex or non-primitive data
Angular
export class MyComponent implements DoCheck {
  ngDoCheck() {
    // heavy or frequent checks
    this.expensiveCheck();
  }
  expensiveCheck() {
    // complex logic running every change detection cycle
  }
}
Runs expensive logic on every change detection cycle, causing slow input response and UI jank.
📉 Performance Costtriggers change detection on every event, blocking rendering for tens of milliseconds per cycle
Performance Comparison
PatternDOM OperationsReflowsPaint CostVerdict
Heavy logic in ngDoCheck every cycleMany unnecessary DOM checksMultiple reflows if DOM updated unnecessarilyHigh paint cost due to blocking[X] Bad
Optimized ngDoCheck with change comparisonMinimal DOM updates only on real changesSingle reflow per actual changeLow paint cost, smooth rendering[OK] Good
Rendering Pipeline
ngDoCheck hooks into Angular's change detection cycle, which runs before the browser paints. Heavy or frequent ngDoCheck logic delays the Layout and Paint stages by blocking the main thread.
→Change Detection
→Layout
→Paint
⚠️ BottleneckChange Detection stage due to expensive or frequent checks
Core Web Vital Affected
INP
This affects the interaction responsiveness and rendering speed by controlling how often Angular checks for changes in components.
Optimization Tips
1Avoid heavy or synchronous logic inside ngDoCheck.
2Use shallow or optimized comparisons to detect real changes.
3Run update logic only when data actually changes to reduce blocking.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance risk of using ngDoCheck without optimization?
ARunning expensive checks on every change detection cycle, causing UI lag
BSkipping change detection entirely, causing stale UI
CIncreasing bundle size significantly
DCausing layout shifts during animations
DevTools: Performance
How to check: Record a performance profile while interacting with the component. Look for long tasks or frequent change detection cycles in the flame chart.
What to look for: High CPU usage during change detection, long blocking times, and frequent reflows indicate poor ngDoCheck performance.

Practice

(1/5)
1. What is the main purpose of the ngDoCheck lifecycle hook in Angular?
easy
A. To run custom change detection logic when Angular's default detection misses changes.
B. To initialize component data before rendering.
C. To handle user input events like clicks and keypresses.
D. To destroy the component and clean up resources.

Solution

  1. Step 1: Understand Angular's default change detection

    Angular automatically detects changes for simple data types but can miss changes in complex objects or arrays.
  2. Step 2: Role of ngDoCheck

    ngDoCheck allows developers to add custom checks to detect changes Angular might miss.
  3. Final Answer:

    To run custom change detection logic when Angular's default detection misses changes. -> Option A
  4. Quick Check:

    ngDoCheck = custom change detection [OK]
Hint: Remember: ngDoCheck is for custom checks Angular misses [OK]
Common Mistakes:
  • Confusing ngDoCheck with ngOnInit or ngOnDestroy
  • Thinking ngDoCheck handles user events
  • Assuming ngDoCheck replaces Angular's default detection
2. Which of the following is the correct syntax to implement ngDoCheck in an Angular component?
easy
A. ngDoCheck() { console.log('Checking changes'); }
B. ngDoCheck: function() { console.log('Checking changes'); }
C. function ngDoCheck() { console.log('Checking changes'); }
D. ngDoCheck => { console.log('Checking changes'); }

Solution

  1. Step 1: Recognize Angular lifecycle hook syntax

    Angular lifecycle hooks are methods inside the component class with no special syntax like arrow functions or function keywords.
  2. Step 2: Identify correct method declaration

    ngDoCheck() { console.log('Checking changes'); } shows the correct method syntax inside a class: ngDoCheck() { ... }.
  3. Final Answer:

    ngDoCheck() { console.log('Checking changes'); } -> Option A
  4. Quick Check:

    ngDoCheck is a class method, not a function expression [OK]
Hint: Use method syntax inside class for lifecycle hooks [OK]
Common Mistakes:
  • Using arrow functions for lifecycle hooks
  • Adding function keyword inside class
  • Using object literal syntax for hooks
3. Consider this Angular component snippet:
items = [1, 2, 3];

ngDoCheck() {
  if (this.items.length !== this.oldLength) {
    console.log('Items changed');
    this.oldLength = this.items.length;
  }
}

What will be logged if items.push(4) is called and Angular runs change detection?
medium
A. Error: oldLength is undefined
B. Nothing is logged
C. Items changed twice
D. Items changed

Solution

  1. Step 1: Check initialization of oldLength

    The code uses this.oldLength but it is never initialized, so it's undefined initially.
  2. Step 2: Runtime behavior after items.push(4)

    this.items.length becomes 4, and 4 !== undefined is true, so 'Items changed' is logged. No error occurs.
  3. Final Answer:

    Items changed -> Option D
  4. Quick Check:

    4 !== undefined -> true, logs [OK]
Hint: Always initialize variables used in ngDoCheck before use [OK]
Common Mistakes:
  • Assuming oldLength is automatically defined
  • Expecting ngDoCheck to detect changes without setup
  • Thinking accessing undefined properties causes runtime errors
4. Given this ngDoCheck implementation:
ngDoCheck() {
  if (this.data !== this.oldData) {
    this.processData();
    this.oldData = this.data;
  }
}

Why might processData() never be called even if data changes internally (like modifying a property inside an object)?
medium
A. Because ngDoCheck only runs once per component.
B. Because !== compares object references, not internal changes.
C. Because processData() is not a valid method.
D. Because oldData is not declared.

Solution

  1. Step 1: Understand object reference comparison

    The !== operator checks if two variables point to different objects, not if the content inside objects changed.
  2. Step 2: Effect on ngDoCheck logic

    If data is the same object but its properties change, this.data !== this.oldData is false, so processData() is not called.
  3. Final Answer:

    Because !== compares object references, not internal changes. -> Option B
  4. Quick Check:

    Object reference check misses internal mutations [OK]
Hint: Use deep checks or immutable objects for internal changes [OK]
Common Mistakes:
  • Thinking !== detects internal object changes
  • Assuming ngDoCheck runs only once
  • Ignoring method existence or variable declaration
5. You want to detect changes inside a nested object profile in ngDoCheck. Which approach correctly detects changes to any property inside profile without replacing the whole object?
hard
A. Call detectChanges() manually inside ngDoCheck.
B. Only check if profile !== oldProfile using reference equality.
C. Use a deep comparison function inside ngDoCheck to compare profile with a saved copy.
D. Replace profile with a new object every time a property changes.

Solution

  1. Step 1: Understand limitations of reference checks

    Reference checks only detect if the object itself changed, not internal property changes.
  2. Step 2: Use deep comparison for nested changes

    A deep comparison function compares all nested properties to detect any internal changes.
  3. Step 3: Avoid unnecessary object replacement

    Replacing the whole object every time is inefficient; deep comparison allows detecting changes without replacement.
  4. Final Answer:

    Use a deep comparison function inside ngDoCheck to compare profile with a saved copy. -> Option C
  5. Quick Check:

    Deep compare nested objects for internal changes [OK]
Hint: Deep compare objects to detect internal changes [OK]
Common Mistakes:
  • Relying on reference equality for nested objects
  • Manually calling detectChanges inside ngDoCheck
  • Replacing whole object unnecessarily
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