Skip to content

refactor(core): wrap checkNoChanges body in if (ngDevMode) for better tree-shaking#63387

Closed
arturovt wants to merge 1 commit intoangular:mainfrom
arturovt:refactor/drop-checkNoChanges
Closed

refactor(core): wrap checkNoChanges body in if (ngDevMode) for better tree-shaking#63387
arturovt wants to merge 1 commit intoangular:mainfrom
arturovt:refactor/drop-checkNoChanges

Conversation

@arturovt
Copy link
Copy Markdown
Contributor

@arturovt arturovt commented Aug 25, 2025

The checkNoChanges method previously used an early-return guard:

  if (!ngDevMode) return;
  // dev-only code ...

In production builds, ngDevMode is replaced with false, so the guard compiles to return;. However, bundlers like ESBuild still keep the remaining statements after the return as unreachable code instead of removing them. This leaves behind unnecessary dead code in the output.

Technically, the body is unreachable. But to prove that, the bundler must be 100% certain that:

  • return cannot be removed by some transform
  • there's no later transformation that changes control flow

As thus, it's always conservative.

This commit updates the method to instead wrap the full body:

  if (ngDevMode) {
    // dev-only code ...
  }

With this change, the method collapses to an empty function in production builds.

This ensures that the dev-only logic and its dependencies (e.g. checkNoChangesInternal, UseExhaustiveCheckNoChanges) can be fully tree-shaken, reducing bundle size.

image

@pullapprove pullapprove bot requested a review from thePunderWoman August 25, 2025 20:48
@angular-robot angular-robot bot added the area: core Issues related to the framework runtime label Aug 25, 2025
@ngbot ngbot bot added this to the Backlog milestone Aug 25, 2025
@arturovt arturovt force-pushed the refactor/drop-checkNoChanges branch 2 times, most recently from 4a5ad38 to 1579f28 Compare August 27, 2025 19:59
…tter tree-shaking

The `checkNoChanges` method previously used an early-return guard:

  if (!ngDevMode) return;
  // dev-only code ...

In production builds, `ngDevMode` is replaced with `false`, so the
guard compiles to `return;`. However, bundlers like ESBuild
still keep the remaining statements after the return as unreachable
code instead of removing them. This leaves behind unnecessary dead
code in the output.

This commit updates the method to instead wrap the full body:

  if (ngDevMode) {
    // dev-only code ...
  }

With this change, the method collapses to an empty function in
production builds:

  checkNoChanges() {}

This ensures that the dev-only logic and its dependencies
(e.g. `checkNoChangesInternal`, `UseExhaustiveCheckNoChanges`) can be
fully tree-shaken, reducing bundle size.
@arturovt arturovt force-pushed the refactor/drop-checkNoChanges branch from 1579f28 to 68f5eb2 Compare August 28, 2025 19:39
Copy link
Copy Markdown
Contributor

@thePunderWoman thePunderWoman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thePunderWoman thePunderWoman added action: merge The PR is ready for merge by the caretaker target: patch This PR is targeted for the next patch release labels Sep 15, 2025
thePunderWoman pushed a commit that referenced this pull request Sep 15, 2025
…tter tree-shaking (#63387)

The `checkNoChanges` method previously used an early-return guard:

  if (!ngDevMode) return;
  // dev-only code ...

In production builds, `ngDevMode` is replaced with `false`, so the
guard compiles to `return;`. However, bundlers like ESBuild
still keep the remaining statements after the return as unreachable
code instead of removing them. This leaves behind unnecessary dead
code in the output.

This commit updates the method to instead wrap the full body:

  if (ngDevMode) {
    // dev-only code ...
  }

With this change, the method collapses to an empty function in
production builds:

  checkNoChanges() {}

This ensures that the dev-only logic and its dependencies
(e.g. `checkNoChangesInternal`, `UseExhaustiveCheckNoChanges`) can be
fully tree-shaken, reducing bundle size.

PR Close #63387
@thePunderWoman
Copy link
Copy Markdown
Contributor

This PR was merged into the repository. The changes were merged into the following branches:

@arturovt arturovt deleted the refactor/drop-checkNoChanges branch September 15, 2025 21:18
wildcardalice pushed a commit to wildcardalice/angular that referenced this pull request Sep 18, 2025
…tter tree-shaking (angular#63387)

The `checkNoChanges` method previously used an early-return guard:

  if (!ngDevMode) return;
  // dev-only code ...

In production builds, `ngDevMode` is replaced with `false`, so the
guard compiles to `return;`. However, bundlers like ESBuild
still keep the remaining statements after the return as unreachable
code instead of removing them. This leaves behind unnecessary dead
code in the output.

This commit updates the method to instead wrap the full body:

  if (ngDevMode) {
    // dev-only code ...
  }

With this change, the method collapses to an empty function in
production builds:

  checkNoChanges() {}

This ensures that the dev-only logic and its dependencies
(e.g. `checkNoChangesInternal`, `UseExhaustiveCheckNoChanges`) can be
fully tree-shaken, reducing bundle size.

PR Close angular#63387
@angular-automatic-lock-bot
Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Oct 16, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker area: core Issues related to the framework runtime target: patch This PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants