Skip to content

Conversation

@wjhsf
Copy link
Contributor

@wjhsf wjhsf commented Nov 20, 2025

Details

In our runtime packages, we have an established pattern of using detached prototype methods instead of writing normal code. As an example, we would replace arr.push(value) with ArrayPush.call(arr, value). There are two reasons cited for this. The first is security. Prototypes can be mutated, so users can theoretically change the push that we're calling to something that we don't expect. By taking a snapshot before executing any user code, we can avoid this. The second reason is performance. At some point, using detached methods may have been faster. But, when I removed them and ran the perf benchmarks, writing code the normal way was more than 20% faster for some of the benchmarks. Curiously, it is 20% slower for the create-rows-1k benchmark. That is a relatively common use case (far more common than the create-rows-10k that gets the best perf boost), so that alone may be enough to scuttle this idea.

We also have a pattern of using utility functions like isUndefined(x) instead of directly checking x === undefined. This reduces file sizes (function calls can be minified to f(x); direct comparisons cannot) at the expense of performance (extra function call). A much more marginal change, but I still saw some improvement when I ran the perf benchmarks with this change on top of the prototype change.

Benchmark results: no detached prototype
Benchmark Before (low) Before (high) Before (avg) After (low) After (high) After (avg) Delta (low) Delta (high) Delta (avg) Delta % (low) Delta % (high) Delta % (avg)
engine-dom/benchmark-expression/expression 15.28 15.54 15.41 15.47 15.72 15.59 0.00 0.36 0.18 0.00% 2.34% 1.17%
engine-dom/benchmark-mutation-observer-ss/ss-mutation-observer-10k 1300.90 1305.63 1303.26 1291.55 1296.06 1293.80 -12.72 -6.19 -9.46 -0.98% -0.48% -0.73%
engine-dom/benchmark-slot-light/light-slot-create-container-5k 265.65 267.35 266.50 264.13 266.63 265.38 -2.64 0.39 -1.12 -0.99% 0.15% -0.42%
engine-dom/benchmark-slot-light/light-slot-update-slotted-content-5k 176.94 179.26 178.10 176.89 179.36 178.12 -1.67 1.72 0.02 -0.94% 0.97% 0.01%
engine-dom/benchmark-slot-ss/ss-slot-create-container-5k 342.88 345.93 344.40 342.54 345.88 344.21 -2.46 2.07 -0.19 -0.71% 0.60% -0.06%
engine-dom/benchmark-slot-ss/ss-slot-update-slotted-content-5k 218.06 219.28 218.67 216.52 217.65 217.08 -2.41 -0.76 -1.59 -1.10% -0.35% -0.72%
engine-dom/benchmark-styled-component/light-styled-component-create-10k-same 84.50 85.51 85.01 84.63 85.57 85.10 -0.60 0.78 0.09 -0.70% 0.92% 0.11%
engine-dom/benchmark-styled-component/light-styled-component-create-1k-different 140.50 141.66 141.08 140.46 141.58 141.02 -0.86 0.74 -0.06 -0.61% 0.53% -0.04%
engine-dom/benchmark-styled-component/ss-styled-component-create-10k-same 129.77 130.96 130.37 130.21 131.41 130.81 -0.40 1.29 0.44 -0.31% 0.99% 0.34%
engine-dom/benchmark-styled-component/ss-styled-component-create-1k-different 161.75 162.71 162.23 161.89 163.02 162.46 -0.51 0.96 0.22 -0.32% 0.59% 0.14%
engine-dom/benchmark-styled-component/styled-component-create-10k-same 149.46 151.43 150.44 149.53 150.76 150.14 -1.46 0.86 -0.30 -0.97% 0.57% -0.20%
engine-dom/benchmark-styled-component/styled-component-create-1k-different 154.61 155.83 155.22 154.99 156.06 155.53 -0.51 1.12 0.31 -0.33% 0.72% 0.20%
engine-dom/benchmark-table-component/tablecmp-append-1k 35.79 36.09 35.94 35.65 36.01 35.83 -0.34 0.13 -0.11 -0.96% 0.35% -0.30%
engine-dom/benchmark-table-component/tablecmp-create-10k 305.70 307.99 306.85 304.44 306.88 305.66 -2.86 0.49 -1.18 -0.93% 0.16% -0.39%
engine-dom/benchmark-table-component/tablecmp-create-1k 49.91 50.49 50.20 49.83 50.44 50.13 -0.48 0.35 -0.07 -0.96% 0.70% -0.13%
engine-dom/benchmark-table-ss/ss-table-create-10k 137.37 138.20 137.78 136.59 137.45 137.02 -1.36 -0.17 -0.76 -0.98% -0.12% -0.55%
engine-dom/benchmark-table/table-create-10k 102.66 103.23 102.95 102.06 102.65 102.36 -1.00 -0.18 -0.59 -0.97% -0.18% -0.57%
engine-dom/benchmark-tracked-component/trackedcmp-create-10k 276.91 279.37 278.14 277.86 280.31 279.08 -0.80 2.68 0.94 -0.29% 0.96% 0.34%
engine-dom/benchmark-tracked-component/trackedcmp-update-10k 122.30 123.63 122.97 119.97 121.41 120.69 -3.25 -1.29 -2.27 -2.64% -1.06% -1.85%
engine-dom/benchmark-tree/tree-create-3k 106.33 107.04 106.69 105.78 106.51 106.14 -1.05 -0.04 -0.54 -0.99% -0.04% -0.51%
engine-dom/benchmark-tree/tree-remove-3k 42.87 43.32 43.09 42.98 43.42 43.20 -0.21 0.42 0.10 -0.48% 0.97% 0.24%
engine-dom/benchmark-wired-component/wireslist-create-10k 266.35 267.84 267.10 264.75 266.98 265.86 -2.58 0.11 -1.23 -0.96% 0.04% -0.46%
engine-dom/js-framework-benchmark/append-rows-1k 15.20 15.91 15.56 11.46 11.85 11.66 -4.30 -3.50 -3.90 -27.17% -22.95% -25.06%
engine-dom/js-framework-benchmark/clear-rows-1k 4.11 4.85 4.48 3.69 3.87 3.78 -1.09 -0.32 -0.70 -22.98% -8.44% -15.71%
engine-dom/js-framework-benchmark/create-rows-10k 155.19 164.17 159.68 109.57 122.84 116.20 -51.49 -35.46 -43.48 -31.86% -22.60% -27.23%
engine-dom/js-framework-benchmark/create-rows-1k 11.50 11.98 11.74 14.31 14.70 14.51 2.46 3.08 2.77 20.56% 26.64% 23.60%
engine-dom/js-framework-benchmark/partial-update-1k 9.74 10.12 9.93 7.66 8.08 7.87 -2.34 -1.78 -2.06 -23.37% -18.13% -20.75%
engine-dom/js-framework-benchmark/remove-row-1k 5.06 5.22 5.14 3.97 4.11 4.04 -1.21 -0.99 -1.10 -23.27% -19.61% -21.44%
engine-dom/js-framework-benchmark/replace-rows-1k 15.76 16.28 16.02 13.72 14.12 13.92 -2.43 -1.77 -2.10 -14.98% -11.22% -13.10%
engine-dom/js-framework-benchmark/select-row-1k 8.72 9.06 8.89 7.85 8.65 8.25 -1.08 -0.21 -0.64 -12.06% -2.36% -7.21%
engine-dom/js-framework-benchmark/swap-rows-1k 8.74 9.15 8.95 6.92 7.32 7.12 -2.11 -1.54 -1.83 -23.28% -17.51% -20.40%
engine-server/table-render-10k 51.39 51.87 51.63 51.22 51.69 51.45 -0.51 0.16 -0.18 -0.99% 0.30% -0.34%
engine-server/tablecmp-render-10k 187.64 190.41 189.02 187.94 190.10 189.02 -1.76 1.75 -0.00 -0.93% 0.93% -0.00%
hydration/table-hydrate-1k 46.90 47.41 47.16 46.83 47.31 47.07 -0.44 0.27 -0.08 -0.92% 0.57% -0.18%
hydration/tablecmp-hydrate-1k 46.84 47.03 46.94 47.33 47.51 47.42 0.35 0.61 0.48 0.75% 1.31% 1.03%
ssr/slots/light-slot-create-container-5k 37.58 37.92 37.75 37.45 37.78 37.61 -0.37 0.10 -0.14 -0.99% 0.26% -0.36%
ssr/slots/slot-create-container-5k 64.77 65.69 65.23 64.83 65.68 65.25 -0.60 0.65 0.02 -0.92% 0.99% 0.03%
ssr/styled/deduped/light-styled-component-create-10k-same 27.99 28.32 28.15 28.02 28.35 28.19 -0.20 0.27 0.03 -0.71% 0.95% 0.12%
ssr/styled/deduped/light-styled-component-create-1k-different 100.05 100.81 100.43 100.07 100.82 100.44 -0.52 0.55 0.01 -0.52% 0.54% 0.01%
ssr/styled/deduped/styled-component-create-10k-same 28.58 28.83 28.71 28.70 28.92 28.81 -0.06 0.27 0.10 -0.22% 0.94% 0.36%
ssr/styled/deduped/styled-component-create-1k-different 100.03 100.74 100.39 100.13 101.02 100.57 -0.38 0.76 0.19 -0.38% 0.76% 0.19%
ssr/styled/light-styled-component-create-10k-same 28.50 28.78 28.64 28.57 28.86 28.71 -0.13 0.28 0.08 -0.44% 0.97% 0.26%
ssr/styled/light-styled-component-create-1k-different 99.21 100.05 99.63 98.86 99.61 99.23 -0.96 0.17 -0.39 -0.96% 0.17% -0.40%
ssr/styled/styled-component-create-10k-same 27.10 27.55 27.32 26.61 26.94 26.78 -0.83 -0.27 -0.55 -3.01% -1.00% -2.01%
ssr/styled/styled-component-create-1k-different 99.09 99.89 99.49 99.21 99.97 99.59 -0.46 0.65 0.10 -0.46% 0.65% 0.10%
ssr/table/table-render-10k 48.71 49.20 48.96 48.83 49.34 49.08 -0.22 0.48 0.13 -0.46% 0.98% 0.26%
ssr/table/tablecmp-render-10k 74.79 75.64 75.21 74.64 75.57 75.10 -0.74 0.52 -0.11 -0.99% 0.69% -0.15%
Benchmark results: no detached prototype + no util functions
Benchmark Before (low) Before (high) Before (avg) After (low) After (high) After (avg) Delta (low) Delta (high) Delta (avg) Delta % (low) Delta % (high) Delta % (avg)
engine-dom/benchmark-expression/expression 16.28 16.55 16.41 16.64 16.92 16.78 0.17 0.56 0.36 1.02% 3.41% 2.22%
engine-dom/benchmark-mutation-observer-ss/ss-mutation-observer-10k 1347.49 1355.12 1351.31 1345.38 1354.31 1349.84 -7.34 4.41 -1.46 -0.54% 0.33% -0.11%
engine-dom/benchmark-slot-light/light-slot-create-container-5k 286.57 288.70 287.63 282.83 284.15 283.49 -5.40 -2.89 -4.15 -1.87% -1.01% -1.44%
engine-dom/benchmark-slot-light/light-slot-update-slotted-content-5k 189.02 190.18 189.60 187.51 188.72 188.11 -2.33 -0.65 -1.49 -1.23% -0.34% -0.78%
engine-dom/benchmark-slot-ss/ss-slot-create-container-5k 383.22 384.43 383.83 378.98 380.14 379.56 -5.10 -3.43 -4.26 -1.33% -0.89% -1.11%
engine-dom/benchmark-slot-ss/ss-slot-update-slotted-content-5k 242.35 243.95 243.15 239.63 241.18 240.41 -3.86 -1.63 -2.74 -1.58% -0.67% -1.13%
engine-dom/benchmark-styled-component/light-styled-component-create-10k-same 93.15 94.44 93.80 90.94 92.00 91.47 -3.16 -1.49 -2.33 -3.36% -1.60% -2.48%
engine-dom/benchmark-styled-component/light-styled-component-create-1k-different 149.39 150.60 149.99 146.84 147.87 147.35 -3.44 -1.84 -2.64 -2.29% -1.24% -1.76%
engine-dom/benchmark-styled-component/ss-styled-component-create-10k-same 148.64 150.99 149.81 145.27 147.50 146.38 -5.05 -1.81 -3.43 -3.36% -1.22% -2.29%
engine-dom/benchmark-styled-component/ss-styled-component-create-1k-different 171.03 172.22 171.63 168.01 169.66 168.84 -3.81 -1.77 -2.79 -2.22% -1.03% -1.62%
engine-dom/benchmark-styled-component/styled-component-create-10k-same 167.96 169.20 168.58 165.36 166.61 165.98 -3.48 -1.71 -2.59 -2.06% -1.02% -1.54%
engine-dom/benchmark-styled-component/styled-component-create-1k-different 162.32 163.59 162.95 159.86 161.01 160.44 -3.37 -1.67 -2.52 -2.07% -1.03% -1.55%
engine-dom/benchmark-table-component/tablecmp-append-1k 39.56 40.27 39.92 38.75 39.36 39.05 -1.33 -0.40 -0.86 -3.31% -1.00% -2.16%
engine-dom/benchmark-table-component/tablecmp-create-10k 336.77 340.25 338.51 330.38 333.64 332.01 -8.89 -4.12 -6.50 -2.62% -1.22% -1.92%
engine-dom/benchmark-table-component/tablecmp-create-1k 53.85 55.00 54.43 51.86 52.90 52.38 -2.82 -1.27 -2.05 -5.16% -2.37% -3.76%
engine-dom/benchmark-table-ss/ss-table-create-10k 142.86 144.45 143.66 142.99 144.60 143.80 -0.99 1.27 0.14 -0.69% 0.89% 0.10%
engine-dom/benchmark-table/table-create-10k 107.74 109.46 108.60 112.91 114.57 113.74 3.94 6.34 5.14 3.60% 5.87% 4.73%
engine-dom/benchmark-tracked-component/trackedcmp-create-10k 305.29 308.84 307.06 299.74 302.90 301.32 -8.12 -3.37 -5.75 -2.64% -1.10% -1.87%
engine-dom/benchmark-tracked-component/trackedcmp-update-10k 139.67 142.15 140.91 135.88 138.70 137.29 -5.50 -1.75 -3.62 -3.89% -1.25% -2.57%
engine-dom/benchmark-tree/tree-create-3k 112.64 113.01 112.83 111.53 111.90 111.72 -1.37 -0.85 -1.11 -1.21% -0.76% -0.98%
engine-dom/benchmark-tree/tree-remove-3k 46.86 47.20 47.03 46.58 46.87 46.72 -0.53 -0.08 -0.31 -1.13% -0.18% -0.65%
engine-dom/benchmark-wired-component/wireslist-create-10k 290.81 293.80 292.30 285.66 288.42 287.04 -7.30 -3.23 -5.26 -2.49% -1.11% -1.80%
engine-dom/js-framework-benchmark/append-rows-1k 17.69 18.45 18.07 13.00 13.44 13.22 -5.29 -4.41 -4.85 -28.81% -24.89% -26.85%
engine-dom/js-framework-benchmark/clear-rows-1k 5.02 6.34 5.68 4.56 4.75 4.65 -1.70 -0.36 -1.03 -27.77% -8.45% -18.11%
engine-dom/js-framework-benchmark/create-rows-10k 174.45 187.75 181.10 105.94 118.56 112.25 -78.02 -59.69 -68.85 -42.18% -33.86% -38.02%
engine-dom/js-framework-benchmark/create-rows-1k 13.21 13.73 13.47 16.45 16.84 16.65 2.85 3.50 3.18 20.82% 26.36% 23.59%
engine-dom/js-framework-benchmark/partial-update-1k 11.76 12.34 12.05 9.62 10.22 9.92 -2.54 -1.71 -2.12 -20.81% -14.45% -17.63%
engine-dom/js-framework-benchmark/remove-row-1k 6.41 6.70 6.56 5.17 5.41 5.29 -1.45 -1.08 -1.26 -21.79% -16.74% -19.26%
engine-dom/js-framework-benchmark/replace-rows-1k 17.98 18.31 18.14 15.39 15.71 15.55 -2.82 -2.36 -2.59 -15.48% -13.10% -14.29%
engine-dom/js-framework-benchmark/select-row-1k 11.89 12.46 12.18 10.36 11.24 10.80 -1.90 -0.85 -1.37 -15.45% -7.13% -11.29%
engine-dom/js-framework-benchmark/swap-rows-1k 12.95 13.55 13.25 10.34 11.04 10.69 -3.02 -2.10 -2.56 -22.53% -16.11% -19.32%
engine-server/table-render-10k 53.85 55.02 54.43 55.23 56.65 55.94 0.59 2.42 1.50 1.06% 4.46% 2.76%
engine-server/tablecmp-render-10k 206.71 210.05 208.38 202.24 205.38 203.81 -6.87 -2.28 -4.57 -3.28% -1.10% -2.19%
hydration/table-hydrate-1k 49.99 50.88 50.44 47.92 48.84 48.38 -2.70 -1.41 -2.05 -5.32% -2.83% -4.07%
hydration/tablecmp-hydrate-1k 49.26 49.90 49.58 47.62 48.38 48.00 -2.07 -1.08 -1.58 -4.16% -2.20% -3.18%
ssr/slots/light-slot-create-container-5k 40.87 41.08 40.97 40.48 40.69 40.58 -0.53 -0.24 -0.39 -1.30% -0.59% -0.94%
ssr/slots/slot-create-container-5k 72.30 72.67 72.49 71.34 71.68 71.51 -1.23 -0.73 -0.98 -1.69% -1.01% -1.35%
ssr/styled/deduped/light-styled-component-create-10k-same 29.15 29.36 29.26 29.01 29.22 29.11 -0.29 0.00 -0.14 -0.99% 0.01% -0.49%
ssr/styled/deduped/light-styled-component-create-1k-different 101.40 102.16 101.78 101.63 102.50 102.07 -0.29 0.87 0.29 -0.28% 0.85% 0.28%
ssr/styled/deduped/styled-component-create-10k-same 28.90 29.25 29.08 28.88 29.14 29.01 -0.29 0.16 -0.07 -0.99% 0.54% -0.23%
ssr/styled/deduped/styled-component-create-1k-different 103.82 104.93 104.37 103.62 104.49 104.05 -1.02 0.38 -0.32 -0.98% 0.37% -0.31%
ssr/styled/light-styled-component-create-10k-same 29.27 29.54 29.40 29.18 29.45 29.32 -0.28 0.10 -0.09 -0.95% 0.34% -0.30%
ssr/styled/light-styled-component-create-1k-different 99.89 100.77 100.33 99.54 100.48 100.01 -0.97 0.32 -0.32 -0.96% 0.32% -0.32%
ssr/styled/styled-component-create-10k-same 27.60 27.89 27.74 27.52 27.86 27.69 -0.28 0.17 -0.05 -1.00% 0.62% -0.19%
ssr/styled/styled-component-create-1k-different 102.99 103.91 103.45 102.72 103.54 103.13 -0.94 0.29 -0.32 -0.91% 0.28% -0.31%
ssr/table/table-render-10k 51.83 52.51 52.17 51.84 52.53 52.18 -0.47 0.50 0.02 -0.90% 0.96% 0.03%
ssr/table/tablecmp-render-10k 80.79 81.16 80.98 80.15 80.52 80.34 -0.90 -0.38 -0.64 -1.11% -0.47% -0.79%

Does this pull request introduce a breaking change?

  • 😮‍💨 No, it does not introduce a breaking change.
  • 💔 Yes, it does introduce a breaking change.

Does this pull request introduce an observable change?

  • 🤞 No, it does not introduce an observable change.
  • 🔬 Yes, it does include an observable change.

GUS work item

@wjhsf wjhsf requested a review from a team as a code owner November 20, 2025 20:12
@salesforce salesforce deleted a comment from git2gus bot Nov 20, 2025
@git2gus
Copy link

git2gus bot commented Nov 20, 2025

Error while creating work item!

@wjhsf
Copy link
Contributor Author

wjhsf commented Nov 20, 2025

/nucleus ignore --reason "Nah."

@salesforce-nucleus
Copy link
Contributor

⚠ The test stage has a status of running, which cannot be ignored.

@jye-sf
Copy link
Contributor

jye-sf commented Nov 20, 2025

I'm unfortunately not going to be able to follow up on this question, but I was wondering if we know why the engine-dom/js-framework-benchmark/create-rows-1k benchmark regressed 20%+?

The other numbers look great, but the create-rows use case is probably the primary contributor to the EPT / page load performance of some of our heaviest pages (list views) on LEX. Apparently a very large number of user sessions also don't go past the first page load, which means those sessions won't benefit from update/clear perf improvements to offset the regression to create.

It looks like the regression is amortized and eventually offset as the tables get larger (as seen from the perf improvement on the create-rows-10k benchmark), but I believe the vast majority of list views are closer to 1k than 10k rows.

All this to say the perf improvements look great, but the biggest gains seem to be with less common use cases and the biggest regression is potentially with one of the biggest (or most visible) use cases. We should validate what the impact might be on those end use cases.

@wjhsf
Copy link
Contributor Author

wjhsf commented Nov 21, 2025

/nucleus ignore --reason "soon it shall be gone"

@wjhsf wjhsf closed this Dec 2, 2025
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.

3 participants