GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — perf(ios): lay out views with fewer native calls by triniwiz · Pull Request #11544 · NativeScript/NativeScript Conversation
|
| Case | main | this PR | main / PR |
|---|---|---|---|
| relayout-resize grow | 144.2 | 80.0 | 1.80 |
| relayout-resize shrink | 116.1 | 64.2 | 1.81 |
| relayout-style restyle | 171.7 | 102.9 | 1.67 |
| relayout-style restore | 141.3 | 90.6 | 1.56 |
| insert-remove remove | 277.4 | 178.3 | 1.56 |
| insert-remove insert | 364.1 | 281.4 | 1.29 |
| tree-fanout mount | 248.9 | 181.2 | 1.37 |
| grid-dashboard mount | 217.9 | 190.2 | 1.15 |
| styled-cards mount | 289.8 | 260.5 | 1.11 |
| flex-wrap-tiles mount | 817.5 | 742.8 | 1.10 |
| nested-chain mount | 24.5 | 22.8 | 1.07 |
| text-flow mount | 158.0 | 153.4 | 1.03 |
view-helper/safe-area-expansion.spec.ts runs the new expandBeyondSafeArea and the previous computation (getAvailableSpaceFromParent + getPositionFromFrame) on 2,000 generated frames inside a scroll view and a view controller, with notched insets and fractional positions, and requires identical rects (over 200 of them expanded).view-helper/frame-position.spec.ts checks the JS position against reading it back from the frame.apps/automated passes on the iOS 26.4 simulator (1827 OK, 0 failed), including the 137 SAFEAREA layout, list view, scroll view, repeater and web view tests. The source changes are iOS-only (.ios.ts files, plus two declarations in view-helper/index.d.ts).
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Laying out a tree on iOS spent most of its time marshalling between JS and UIKit rather than in UIKit itself. Containers (layouts, ScrollView, Page content) default to iosOverflowSafeArea, so every time a container's frame changed, expandBeyondSafeArea built four CGRects (the safe area, the full area, the frame in the window, the frame) and read each one back through getPositionFromFrame: about 70 native getter calls per view, for a result that is the frame itself unless the view touches the edge of the safe area. - expandBeyondSafeArea reads each native value once (the reference's insets, content size and offset or safe-area guide, the view's location in the window, the frame) and computes the positions in JS with the same arithmetic, so the result is identical. When nothing is expanded and the frame is already on device pixels, it returns the frame itself, and the frame is not set a second time. - layout() uses the position of a frame it has just set, unadjusted and untransformed, instead of reading the native frame back. - layoutNativeView() skips the native calls when the position is the one it last laid out, which _setNativeViewFrame would leave alone anyway. - getSafeAreaInsets() checks iosIgnoreSafeArea and the managed-inset ancestor before reading the native insets. - measureNativeView() and Label's text measure return plain objects instead of writing into the CGSize, which goes through native struct setters. On the xplat-benchmarks ns-core app (iPhone 17 Pro Max simulator, size M, 3 interleaved rounds), resizing a 1,093-view tree went from 148 ms to 81 ms (grow) and 118 ms to 65 ms (shrink), restyling it from 174 ms to 103 ms, and mounting it from 250 ms to 181 ms.
There was an error while loading. Please reload this page.
|
View your CI Pipeline Execution ↗ for commit b24f3e8
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗ ☁️ Nx Cloud last updated this comment at |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
commit: |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| right, | ||
| bottom, | ||
| }); | ||
| this._pendingFramePosition = IOSHelper.getPositionFromFramePosition(left, top, right, bottom); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
isnt it a duplicate cost as you already go through parents in getFrameFromPosition? Cant we get position from frame?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| // get the frame and adjust the position, so that onLayout works correctly | ||
| position = IOSHelper.getPositionFromFrame(this.nativeViewProtected.frame); | ||
| // get the frame and adjust the position, so that onLayout works correctly. | ||
| // A frame set here without adjustment is known without reading it back |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Those AI comments are too long. In the end it will pollute the code. We should keep them small
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if (IOSHelper.hasIOSManagedInsetAncestor(this)) { | ||
| return insets; | ||
| } | ||
| const safeAreaInsets = this.nativeViewProtected && this.nativeViewProtected.safeAreaInsets; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
const safeAreaInsets = this.nativeViewProtected?.safeAreaInsets
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
A few of these optimizations might not be needed anymore since accessing structs is now a few ns. Some paths had 20x speedup so what you're doing might even have become suboptimal now under jitless |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@edusperoni nice I'll rerun the benchmarks to see new numbers. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.