Skip to content

Conversation

@greglittlefield-wf
Copy link
Contributor

@greglittlefield-wf greglittlefield-wf commented Oct 8, 2025

Motivation

The amount of code generated by the over_react builder is non-negligible, and has some opportunities to be optimized, ultimately reducing the size of compiled dart2js in apps with many components.

Changes

Perform low-hanging optimizations. Note: there are some more potential opportunities for optimization that require more investigation and may involve breakages, which we may revisit later.

Since they affect generated code, changes are easiest to to review commit-by-commit, and the main ones are described below:

  1. 4668279
    1. Remove specialized $PlainMap and $JsMap generated classes, reducing the number of generated concrete props classes from 3 to 1, which translates to similar reductions in the count of dart2js-compiled class representations
      • Note: this does not include generated mixin classes
      • The $JsMap class was originally included as a potential performance optimization when reading/writing props, but there's no evidence that it's helpful, and it's unlikely to be worth the code size increase
    2. Remove workaround for an old DDC bug that required an additional field and constructor body (added in CPLAT-4674: Add workaround for ddc bug via props/state impl constructor #256)
      • This also has the side effect of allowing get$props calls to get inlined, and their results to be reused when reading props
  2. 235add1 Move $isClassGenerated check into an assert so it can be compiled out
  3. edd6bc5 Change aria/dom to getters to optimize dart2js output size
    This way, they don't get compiled as fields, which emit extra code in each props class's dart2js constructor.
  4. 235add1 Move $isClassGenerated check into an assert so it can be compiled out

Effects on build output

This saves ~577 bytes per component (when using -03 --csp --minify), which was calculated by comparing a benchmark component via the benchmark added in #991:

dart run benchmark/dart2js_output.dart compare-code --head='{"git":{"url":"https://github.com/Workiva/over_react.git/","ref":"clean-up-and-optimize-generated-props"}}'

dart2js output changes, obtained by running:

dart run benchmark/dart2js_output.dart compare-code --head='{"git":{"url":"https://github.com/Workiva/over_react.git/","ref":"clean-up-and-optimize-generated-props"}}'

This diff is compares optimized, non-minified dart2js (-03 --csp --no-minify), which has been normalized to allow for better diffing.

Full dart2js diff:
@ -459,3 +459,3 @@
       t#.names = "";
-      if (namedArguments != null && namedArguments.__js_helper$_length !== ###)
+      if (namedArguments != null && namedArguments._length !== ###)
         namedArguments.forEach$###(###, new A.Primitives_functionNoSuchMethod_closure(t#, namedArgumentList, $arguments));
@@ -466,3 +466,3 @@
       if (Array.isArray(positionalArguments))
-        t# = namedArguments == null || namedArguments.__js_helper$_length === ###;
+        t# = namedArguments == null || namedArguments._length === ###;
       else
@@ -510,3 +510,3 @@
       if (t#) {
-        if (namedArguments != null && namedArguments.__js_helper$_length !== ###)
+        if (namedArguments != null && namedArguments._length !== ###)
           return A.Primitives_functionNoSuchMethod($function, $arguments, namedArguments);
@@ -517,3 +517,3 @@
       if (Array.isArray(defaultValues)) {
-        if (namedArguments != null && namedArguments.__js_helper$_length !== ###)
+        if (namedArguments != null && namedArguments._length !== ###)
           return A.Primitives_functionNoSuchMethod($function, $arguments, namedArguments);
@@ -555,3 +555,3 @@
           }
-          if (used !== namedArguments.__js_helper$_length)
+          if (used !== namedArguments._length)
             return A.Primitives_functionNoSuchMethod($function, $arguments, namedArguments);
@@ -1213,3 +1213,3 @@
       var _ = this;
-      _.__js_helper$_length = t#;
+      _._length = t#;
       _._jsObject = t#;
@@ -1288,3 +1288,3 @@
       var _ = this;
-      _.__js_helper$_length = ###;
+      _._length = ###;
       _._last = _._first = _.__js_helper$_rest = _._nums = _._strings = null;
@@ -3266,3 +3266,3 @@
       var _ = this;
-      _.__js_helper$_length = ###;
+      _._length = ###;
       _._last = _._first = _.__js_helper$_rest = _._nums = _._strings = null;
@@ -3276,3 +3276,3 @@
       _._validKey = t#;
-      _.__js_helper$_length = ###;
+      _._length = ###;
       _._last = _._first = _.__js_helper$_rest = _._nums = _._strings = null;
@@ -3672,3 +3672,3 @@
       _._array = t#;
-      _._length = t#;
+      _._html$_length = t#;
       _._position = -###;
@@ -3746,21 +3746,6 @@
     _$ResizeSensor(backingProps) {
-      return backingProps == null ? A._$$ResizeSensorProps$JsMap$(new A.JsBackedMap({})) : A._$$ResizeSensorProps__$$ResizeSensorProps(backingProps);
+      return A._$$ResizeSensorProps$(backingProps);
     },
-    _$$ResizeSensorProps__$$ResizeSensorProps(backingMap) {
-      var t#;
-      if (backingMap instanceof A.JsBackedMap)
-        return A._$$ResizeSensorProps$JsMap$(type$.nullable_JsBackedMap._as(backingMap));
-      else {
-        t# = type$.dynamic;
-        t# = new A._$$ResizeSensorProps$PlainMap(A.LinkedHashMap_LinkedHashMap$_empty(t#, t#), $, $);
-        t#.get$$$isClassGenerated();
-        t#._props = backingMap;
-        return t#;
-      }
-    },
-    _$$ResizeSensorProps$JsMap$(backingMap) {
-      var t# = new A._$$ResizeSensorProps$JsMap(new A.JsBackedMap({}), $, $);
-      t#.get$$$isClassGenerated();
-      t#._props = backingMap == null ? new A.JsBackedMap({}) : backingMap;
-      return t#;
+    _$$ResizeSensorProps$(backingMap) {
+      return new A._$$ResizeSensorProps(backingMap == null ? new A.JsBackedMap({}) : backingMap);
     },
@@ -3776,18 +3761,7 @@
     _$ResizeSensorPropsAccessorsMixin: function _$ResizeSensorPropsAccessorsMixin() {},
-    _$$ResizeSensorProps: function _$$ResizeSensorProps() {},
-    _$$ResizeSensorProps_$getPropKey_closure: function _$$ResizeSensorProps_$getPropKey_closure() {},
-    _$$ResizeSensorProps$PlainMap: function _$$ResizeSensorProps$PlainMap(t#, t#, t#) {
-      var _ = this;
-      _._props = t#;
-      _.componentFactory = null;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_aria_FI = t#;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_dom_FI = t#;
-    },
-    _$$ResizeSensorProps$JsMap: function _$$ResizeSensorProps$JsMap(t#, t#, t#) {
-      var _ = this;
-      _._props = t#;
-      _.componentFactory = null;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_aria_FI = t#;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_dom_FI = t#;
+    _$$ResizeSensorProps: function _$$ResizeSensorProps(t#) {
+      this.props = t#;
+      this.componentFactory = null;
     },
+    _$$ResizeSensorProps_$getPropKey_closure: function _$$ResizeSensorProps_$getPropKey_closure() {},
     _$ResizeSensorComponent: function _$ResizeSensorComponent(t#, t#, t#, t#) {
@@ -3808,13 +3782,8 @@
     DomProps$(componentFactory, props) {
-      var t# = new A.DomProps(componentFactory, props == null ? new A.JsBackedMap({}) : props, $, $);
-      t#.get$$$isClassGenerated();
-      return t#;
+      return new A.DomProps(componentFactory, props == null ? new A.JsBackedMap({}) : props);
     },
-    DomProps: function DomProps(t#, t#, t#, t#) {
-      var _ = this;
-      _.DomProps_componentFactory = t#;
-      _.props = t#;
-      _.componentFactory = null;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_aria_FI = t#;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_dom_FI = t#;
+    DomProps: function DomProps(t#, t#) {
+      this.DomProps_componentFactory = t#;
+      this.props = t#;
+      this.componentFactory = null;
     },
@@ -3873,3 +3842,3 @@
       t# = consumedProps;
-      A.forwardUnconsumedPropsV2(_this.get$props(_this), new A.MappedListIterable(t#, new A.PropsToForward__propsToForward_closure(), A.instanceType(t#)._eval$###("MappedListIterable<###,List<String>>")), false, propsToUpdate);
+      A.forwardUnconsumedPropsV2(_this.props, new A.MappedListIterable(t#, new A.PropsToForward__propsToForward_closure(), A.instanceType(t#)._eval$###("MappedListIterable<###,List<String>>")), false, propsToUpdate);
       return propsToUpdate;
@@ -3969,8 +3938,5 @@
     },
-    GenericUiProps: function GenericUiProps(t#, t#, t#) {
-      var _ = this;
-      _.props = t#;
-      _.componentFactory = null;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_aria_FI = t#;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_dom_FI = t#;
+    GenericUiProps: function GenericUiProps(t#) {
+      this.props = t#;
+      this.componentFactory = null;
     },
@@ -4695,3 +4661,3 @@
     main() {
-      var t#,
+      var t#, t#,
         t# = A.DomProps$($.$get$div(), null);
@@ -4702,27 +4668,13 @@
       t# = $.$get$Foo0().call$###();
-      t# = J.getInterceptor$x(t#);
-      J.$indexSet$ax(t#.get$props(t#), "Foo0Props.foo0", "");
-      J.$indexSet$ax(t#.get$props(t#), "Foo0Props.foo1", "");
-      J.$indexSet$ax(t#.get$props(t#), "Foo0Props.foo2", "");
-      J.$indexSet$ax(t#.get$props(t#), "Foo0Props.foo3", "");
-      J.$indexSet$ax(t#.get$props(t#), "Foo0Props.foo4", "");
+      t# = t#.props;
+      t# = J.getInterceptor$ax(t#);
+      t#.$indexSet(t#, "Foo0Props.foo0", "");
+      t#.$indexSet(t#, "Foo0Props.foo1", "");
+      t#.$indexSet(t#, "Foo0Props.foo2", "");
+      t#.$indexSet(t#, "Foo0Props.foo3", "");
+      t#.$indexSet(t#, "Foo0Props.foo4", "");
       t#.call$###();
     },
-    _$$Foo0Props__$$Foo0Props(backingMap) {
-      var t#;
-      if (backingMap instanceof A.JsBackedMap)
-        return A._$$Foo0Props$JsMap$(type$.nullable_JsBackedMap._as(backingMap));
-      else {
-        t# = type$.dynamic;
-        t# = new A._$$Foo0Props$PlainMap(A.LinkedHashMap_LinkedHashMap$_empty(t#, t#), $, $, $, $, $, $, $);
-        t#.get$$$isClassGenerated();
-        t#._main$_props = backingMap;
-        return t#;
-      }
-    },
-    _$$Foo0Props$JsMap$(backingMap) {
-      var t# = new A._$$Foo0Props$JsMap(new A.JsBackedMap({}), $, $, $, $, $, $, $);
-      t#.get$$$isClassGenerated();
-      t#._main$_props = backingMap == null ? new A.JsBackedMap({}) : backingMap;
-      return t#;
+    _$$Foo0Props$(backingMap) {
+      return new A._$$Foo0Props(backingMap, $, $, $, $, $);
     },
@@ -4734,18 +4686,5 @@
     _$Foo0Config_closure0: function _$Foo0Config_closure0() {},
-    _$$Foo0Props: function _$$Foo0Props() {},
-    _$$Foo0Props$PlainMap: function _$$Foo0Props$PlainMap(t#, t#, t#, t#, t#, t#, t#, t#) {
+    _$$Foo0Props: function _$$Foo0Props(t#, t#, t#, t#, t#, t#) {
       var _ = this;
-      _._main$_props = t#;
-      _.Foo0Props___Foo0Props_foo0_A = t#;
-      _.Foo0Props___Foo0Props_foo1_A = t#;
-      _.Foo0Props___Foo0Props_foo2_A = t#;
-      _.Foo0Props___Foo0Props_foo3_A = t#;
-      _.Foo0Props___Foo0Props_foo4_A = t#;
-      _.componentFactory = null;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_aria_FI = t#;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_dom_FI = t#;
-    },
-    _$$Foo0Props$JsMap: function _$$Foo0Props$JsMap(t#, t#, t#, t#, t#, t#, t#, t#) {
-      var _ = this;
-      _._main$_props = t#;
+      _.props = t#;
       _.Foo0Props___Foo0Props_foo0_A = t#;
@@ -4756,4 +4695,2 @@
       _.componentFactory = null;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_aria_FI = t#;
-      _.UbiquitousDomPropsMixin___UbiquitousDomPropsMixin_dom_FI = t#;
     },
@@ -4858,4 +4795,4 @@
     forwardUnconsumedProps(props, keySetsToOmit, onlyCopyDomProps, propsToUpdate) {
-      var t#, key, t#;
-      for (t# = props.get$props(props), t# = J.get$iterator$ax(t#.get$keys(t#)); t#.moveNext$###();) {
+      var t#, t#, t#, key, t#;
+      for (t# = props.props, t# = J.getInterceptor$x(t#), t# = J.get$iterator$ax(t#.get$keys(t#)); t#.moveNext$###();) {
         key = t#.get$current(t#);
@@ -4866,3 +4803,3 @@
         if (t# || $.$get$_validDomProps().contains$###(###, key)) {
-          t# = props.get$props(props).$index(###, key);
+          t# = t#.$index(t#, key);
           J.$indexSet$ax(propsToUpdate.get$props(propsToUpdate), key, t#);
@@ -6035,3 +5972,3 @@
     get$length(_) {
-      return this.__js_helper$_length;
+      return this._length;
     },
@@ -6114,3 +6051,3 @@
     get$length(_) {
-      return this._getMap$###().__js_helper$_length;
+      return this._getMap$###()._length;
     }
@@ -6299,6 +6236,6 @@
     get$length(_) {
-      return this.__js_helper$_length;
+      return this._length;
     },
     get$isEmpty(_) {
-      return this.__js_helper$_length === ###;
+      return this._length === ###;
     },
@@ -6428,3 +6365,3 @@
         _this._last = _this._last._next = cell;
-      ++_this.__js_helper$_length;
+      ++_this._length;
       _this._modifications = _this._modifications + ### & ###;
@@ -6476,6 +6413,6 @@
     get$length(_) {
-      return this._map.__js_helper$_length;
+      return this._map._length;
     },
     get$isEmpty(_) {
-      return this._map.__js_helper$_length === ###;
+      return this._map._length === ###;
     },
@@ -8920,3 +8857,3 @@
         nextPosition = _this._position + ###,
-        t# = _this._length;
+        t# = _this._html$_length;
       if (nextPosition < t#) {
@@ -9265,3 +9202,3 @@
     get$defaultProps(_) {
-      var t# = A._$$ResizeSensorProps$JsMap$(new A.JsBackedMap({}));
+      var t# = A._$$ResizeSensorProps$(new A.JsBackedMap({}));
       t#.addProps$###($.$get$ResizeSensorPropsMixin_defaultProps());
@@ -9280,3 +9217,3 @@
       t# === $ && A.throwUnnamedLateFieldNI();
-      t# = t#.get$props(t#).$index(###, "ResizeSensorPropsMixin.quickMount");
+      t# = J.$index$asx(t#.props, "ResizeSensorPropsMixin.quickMount");
       t# = A._asBoolQ(t# == null ? null : t#);
@@ -9323,4 +9260,3 @@
       resizeSensor = t#.call$###(expandSensor, collapseSensor);
-      t# = _this.___$ResizeSensorComponent__cachedTypedProps_A;
-      t# = t#.get$props(t#).$index(###, "ResizeSensorPropsMixin.isFlexChild");
+      t# = J.$index$asx(_this.___$ResizeSensorComponent__cachedTypedProps_A.props, "ResizeSensorPropsMixin.isFlexChild");
       t# = A._asBoolQ(t# == null ? _null : t#);
@@ -9330,4 +9266,3 @@
       else {
-        t# = _this.___$ResizeSensorComponent__cachedTypedProps_A;
-        t# = t#.get$props(t#).$index(###, "ResizeSensorPropsMixin.isFlexContainer");
+        t# = J.$index$asx(_this.___$ResizeSensorComponent__cachedTypedProps_A.props, "ResizeSensorPropsMixin.isFlexContainer");
         t# = A._asBoolQ(t# == null ? _null : t#);
@@ -9396,3 +9331,3 @@
       t# === $ && A.throwUnnamedLateFieldNI();
-      t# = t#.get$props(t#).$index(###, "ResizeSensorPropsMixin.onDidReset");
+      t# = J.$index$asx(t#.props, "ResizeSensorPropsMixin.onDidReset");
       if (t# == null)
@@ -9446,5 +9381,2 @@
   A._$$ResizeSensorProps.prototype = {
-    get$$$isClassGenerated() {
-      return true;
-    },
     get$componentFactory() {
@@ -9456,3 +9388,6 @@
     },
-    $isResizeSensorProps: ###
+    $isResizeSensorProps: ###,
+    get$props(receiver) {
+      return this.props;
+    }
   };
@@ -9460,3 +9395,3 @@
     call$###(map) {
-      return A._$$ResizeSensorProps__$$ResizeSensorProps(map);
+      return A._$$ResizeSensorProps$(map);
     },
@@ -9464,12 +9399,2 @@
   };
-  A._$$ResizeSensorProps$PlainMap.prototype = {
-    get$props(_) {
-      return this._props;
-    }
-  };
-  A._$$ResizeSensorProps$JsMap.prototype = {
-    get$props(_) {
-      return this._props;
-    }
-  };
   A._$ResizeSensorComponent.prototype = {
@@ -9477,3 +9402,3 @@
       this.super$Component2$props(###, value);
-      this.___$ResizeSensorComponent__cachedTypedProps_A = A._$$ResizeSensorProps$JsMap$(A.getBackingMap(value));
+      this.___$ResizeSensorComponent__cachedTypedProps_A = A._$$ResizeSensorProps$(A.getBackingMap(value));
     },
@@ -9512,5 +9437,2 @@
   A.DomProps.prototype = {
-    get$$$isClassGenerated() {
-      return true;
-    },
     get$componentFactory() {
@@ -9778,4 +9700,3 @@
     call$###(backingMap) {
-      var t# = new A.GenericUiProps(backingMap == null ? new A.JsBackedMap({}) : backingMap, $, $);
-      t#.get$$$isClassGenerated();
+      var t# = new A.GenericUiProps(backingMap == null ? new A.JsBackedMap({}) : backingMap);
       t#.componentFactory = this.factory;
@@ -9818,5 +9739,2 @@
   A.GenericUiProps.prototype = {
-    get$$$isClassGenerated() {
-      return true;
-    },
     get$props(receiver) {
@@ -10410,12 +10328,14 @@
     call$###(props) {
-      var t#, t#, t#, t#, _null = null,
-        t# = J.$index$asx(props.get$props(props), "Foo0Props.foo0");
+      var t#, t#, t#, _null = null,
+        t# = props.props,
+        t# = J.getInterceptor$asx(t#),
+        t# = t#.$index(t#, "Foo0Props.foo0");
       t# = A._asString(t# == null ? _null : t#);
-      t# = J.$index$asx(props.get$props(props), "Foo0Props.foo1");
+      t# = t#.$index(t#, "Foo0Props.foo1");
       t# = A._asString(t# == null ? _null : t#);
-      t# = J.$index$asx(props.get$props(props), "Foo0Props.foo2");
+      t# = t#.$index(t#, "Foo0Props.foo2");
       t# = A._asString(t# == null ? _null : t#);
-      t# = J.$index$asx(props.get$props(props), "Foo0Props.foo3");
+      t# = t#.$index(t#, "Foo0Props.foo3");
       t# = A._asString(t# == null ? _null : t#);
-      t# = J.$index$asx(props.get$props(props), "Foo0Props.foo4");
+      t# = t#.$index(t#, "Foo0Props.foo4");
       A.print(A._setArrayType([t#, t#, t#, t#, A._asString(t# == null ? _null : t#)], type$.JSArray_String));
@@ -10431,3 +10351,3 @@
     call$###(p) {
-      var t# = J.$index$asx(p.get$props(p), "id");
+      var t# = J.$index$asx(p.props, "id");
       return A._asStringQ(t# == null ? null : t#);
@@ -10439,3 +10359,3 @@
     call$###(map) {
-      return A._$$Foo0Props__$$Foo0Props(map);
+      return A._$$Foo0Props$(map);
     },
@@ -10445,3 +10365,3 @@
     call$###(map) {
-      return A._$$Foo0Props$JsMap$(map);
+      return A._$$Foo0Props$(map);
     },
@@ -10450,14 +10370,4 @@
   A._$$Foo0Props.prototype = {
-    get$$$isClassGenerated() {
-      return true;
-    }
-  };
-  A._$$Foo0Props$PlainMap.prototype = {
-    get$props(_) {
-      return this._main$_props;
-    }
-  };
-  A._$$Foo0Props$JsMap.prototype = {
-    get$props(_) {
-      return this._main$_props;
+    get$props(receiver) {
+      return this.props;
     }
@@ -11053,6 +10963,2 @@
     _inherit(A._$$ResizeSensorProps, A.__$$ResizeSensorProps__$ResizeSensorProps__$ResizeSensorPropsAccessorsMixin);
-    _inheritMany(A._$$ResizeSensorProps,
-      [A._$$ResizeSensorProps$PlainMap,
-      A._$$ResizeSensorProps$JsMap,
-    ]);
     _inherit(A._$ResizeSensorComponent, A.ResizeSensorComponent);
@@ -11094,6 +11000,2 @@
     _inherit(A._$$Foo0Props, A.__$$Foo0Props_UiProps_Foo0Props_$Foo0Props);
-    _inheritMany(A._$$Foo0Props,
-      [A._$$Foo0Props$PlainMap,
-      A._$$Foo0Props$JsMap,
-    ]);
     _mixin(A._NativeTypedArrayOfDouble_NativeTypedArray_ListMixin, A.ListMixin);
@@ -11216,3 +11118,3 @@
   "Version(NavigatorProvider{namePrefix:String})",
-  "_$$Foo0Props$JsMap(JsBackedMap)",
+  "_$$Foo0Props(JsBackedMap)",
   "_$$Foo0Props(Map<@,@>)",
@@ -12265,26 +12167,2 @@
  "_$$Foo0Props": {
-  "Foo0Props": [],
-  "Map": [
-   "@",
-   "@"
-  ],
-  "MapMixin": [
-   "@",
-   "@"
-  ]
- },
- "_$$Foo0Props$JsMap": {
-  "Foo0Props": [],
-  "Map": [
-   "@",
-   "@"
-  ],
-  "MapMixin": [
-   "@",
-   "@"
-  ],
-  "MapMixin.K": "@",
-  "MapMixin.V": "@"
- },
- "_$$Foo0Props$PlainMap": {
   "Foo0Props": [],
@@ -12302,26 +12180,2 @@
  "_$$ResizeSensorProps": {
-  "Map": [
-   "@",
-   "@"
-  ],
-  "MapMixin": [
-   "@",
-   "@"
-  ],
-  "ResizeSensorProps": []
- },
- "_$$ResizeSensorProps$JsMap": {
-  "Map": [
-   "@",
-   "@"
-  ],
-  "MapMixin": [
-   "@",
-   "@"
-  ],
-  "MapMixin.K": "@",
-  "MapMixin.V": "@",
-  "ResizeSensorProps": []
- },
- "_$$ResizeSensorProps$PlainMap": {
   "Map": [
@@ -12692,3 +12546,2 @@
       nullable_Future_Null: findType("Future<Null>?"),
-      nullable_JsBackedMap: findType("JsBackedMap?"),
       nullable_Object: findType("Object?"),
@@ -13044,6 +12897,6 @@
   };
-  Function.prototype.call$###$### = function(a) {
+  Function.prototype.call$### = function(a) {
     return this(a);
   };
-  Function.prototype.call$### = function(a) {
+  Function.prototype.call$###$### = function(a) {
     return this(a);

Release Notes

Review

See CONTRIBUTING.md for more details on review types (+1 / QA +1 / +10) and code review process.

Please review:

QA Checklist

  • Tests were updated and provide good coverage of the changeset and other affected code
  • Manual testing was performed if needed
    • Steps from PR author:
      • CI passes (testing in this repo should be sufficient to guard against potential regressions)
    • Anything falling under manual testing criteria outlined in CONTRIBUTING.md

Merge Checklist

While we perform many automated checks before auto-merging, some manual checks are needed:

  • A Frontend Frameworks Design member has reviewed these changes
  • There are no unaddressed comments - this check can be automated if reviewers use the "Request Changes" feature
  • For release PRs - Version metadata in Rosie comment is correct

The JsBackedMap specialized subclass was implemented to potentially improve performance
by allowing dart2js to inline/optimize backing map operations, but from inspecting
compiled code, it doesn't seem to have much of an effect.

These two specialized subclasses result in a significant amount of extra compiled code,
so removing it at this time is worth the tradeoff.

This commit also removes workarounds for an old DDC bug.
This way, they don't get compiled as fields, which emit extra code
in each props class's constructor.

In the future, if we wanted to reuse these objects for successive
calls in builders, we could use an expando instead.
@greglittlefield-wf greglittlefield-wf changed the title Optimize generated code size FED-4215 Low-hanging dart2js code side optimizations Dec 3, 2025
@greglittlefield-wf greglittlefield-wf marked this pull request as ready for review December 3, 2025 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants