From d470dff03488df9b5de3f0e5f9acfa2dcf33da3c Mon Sep 17 00:00:00 2001 From: Artur Androsovych Date: Mon, 28 Feb 2022 21:25:12 +0200 Subject: [PATCH] perf(store): tree-shake `deepFreeze` (#1821) --- CHANGELOG.md | 1 + bundlesize.config.json | 10 +++++----- .../store/src/internal/state-operations.ts | 20 +++++++++++++++---- packages/store/src/symbols.ts | 3 +++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27ab97401..e81cb59aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ $ npm install @ngxs/store@dev - Performance: Tree-shake errors and warnings [#1732](https://github.com/ngxs/store/pull/1732) - Performance: Tree-shake `ConfigValidator`, `HostEnvironment` and `isAngularInTestMode` [#1741](https://github.com/ngxs/store/pull/1741) - Performance: Tree-shake `SelectFactory` [#1744](https://github.com/ngxs/store/pull/1744) +- Performance: Tree-shake `deepFreeze` [#1819](https://github.com/ngxs/store/pull/1819) - Performance: Router Plugin - Tree-shake `isAngularInTestMode()` [#1738](https://github.com/ngxs/store/pull/1738) - Performance: Tree-shake `isAngularInTestMode()` [#1739](https://github.com/ngxs/store/pull/1739) - Performance: Storage Plugin - Tree-shake `console.*` calls and expand error messages [#1727](https://github.com/ngxs/store/pull/1727) diff --git a/bundlesize.config.json b/bundlesize.config.json index a927b85a8..023fc9af2 100644 --- a/bundlesize.config.json +++ b/bundlesize.config.json @@ -32,14 +32,14 @@ "path": "./@ngxs/store/fesm2015/ngxs-store.js", "package": "@ngxs/store", "target": "es2015", - "maxSize": "113.70KB", + "maxSize": "114.70KB", "compression": "none" }, { "path": "./@ngxs/store/fesm5/ngxs-store.js", "package": "@ngxs/store", "target": "es5", - "maxSize": "132.60KB", + "maxSize": "133.60KB", "compression": "none" }, { @@ -143,19 +143,19 @@ { "path": "./integrations/hello-world-ng11-ivy/dist-integration/main.*.js", "target": "es2015", - "maxSize": "251.30 kB", + "maxSize": "250.90 kB", "compression": "none" }, { "path": "./integrations/hello-world-ng12-ivy/dist-integration/main.*.js", "target": "es2015", - "maxSize": "236.90 kB", + "maxSize": "236.50 kB", "compression": "none" }, { "path": "./integrations/hello-world-ng13-ivy/dist-integration/main.*.js", "target": "es2015", - "maxSize": "237.20 kB", + "maxSize": "236.80 kB", "compression": "none" } ] diff --git a/packages/store/src/internal/state-operations.ts b/packages/store/src/internal/state-operations.ts index 67ce26907..df17e9bc0 100644 --- a/packages/store/src/internal/state-operations.ts +++ b/packages/store/src/internal/state-operations.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { isAngularInTestMode } from '@ngxs/store/internals'; import { StateOperations, StatesAndDefaults } from '../internal/internals'; import { InternalDispatcher } from '../internal/dispatcher'; @@ -28,9 +29,21 @@ export class InternalStateOperations { dispatch: (actionOrActions: any | any[]) => this._dispatcher.dispatch(actionOrActions) }; - return this._config.developmentMode - ? ensureStateAndActionsAreImmutable(rootStateOperations) - : rootStateOperations; + // We have to have that duplication since this will allow us to tree-shake `ensureStateAndActionsAreImmutable` + // and `deepFreeze` in Ivy production build. + // The below `if` condition checks 2 things: + // 1) if we're in View Engine (`ngDevMode` is `undefined`) + // 2) if we're running tests, we should fallback to `config.developmentMode` to be backwards-compatible + if (typeof ngDevMode === 'undefined' || (ngDevMode && isAngularInTestMode())) { + return this._config.developmentMode + ? ensureStateAndActionsAreImmutable(rootStateOperations) + : rootStateOperations; + } else { + // If we're in Ivy and not running tests, then tree-shake `ensureStateAndActionsAreImmutable` and `deepFreeze`. + return ngDevMode + ? ensureStateAndActionsAreImmutable(rootStateOperations) + : rootStateOperations; + } } setStateToTheCurrentWithNew(results: StatesAndDefaults): void { @@ -43,7 +56,6 @@ export class InternalStateOperations { } } -// We make it as a separate function and not the class method to tree-shake it in the future. function ensureStateAndActionsAreImmutable(root: StateOperations): StateOperations { return { getState: () => root.getState(), diff --git a/packages/store/src/symbols.ts b/packages/store/src/symbols.ts index 9e67a9c3f..8a1e26e76 100644 --- a/packages/store/src/symbols.ts +++ b/packages/store/src/symbols.ts @@ -30,6 +30,9 @@ export class NgxsConfig { * Run in development mode. This will add additional debugging features: * - Object.freeze on the state and actions to guarantee immutability * (default: false) + * + * @deprecated This property is no longer necessary when the Ivy compiler is used. + * We'll determine the development mode through the `ngDevMode`. It's still essential with View Engine. */ developmentMode: boolean; compatibility: {