diff --git a/packages/core/ui/core/properties/index.ts b/packages/core/ui/core/properties/index.ts index c2d32f471..9b6ca3813 100644 --- a/packages/core/ui/core/properties/index.ts +++ b/packages/core/ui/core/properties/index.ts @@ -1363,6 +1363,8 @@ function inheritableCssPropertyValuesOn(style: Style): Array<{ property: Inherit type PropertyInterface = Property | CssProperty | CssAnimationProperty; export const initNativeView = profile('"properties".initNativeView', function initNativeView(view: ViewBase): void { + const wasSuspended = view.suspendRequestLayout; + view.suspendRequestLayout = true; if (view._suspendedUpdates) { applyPendingNativeSetters(view); } else { @@ -1370,6 +1372,14 @@ export const initNativeView = profile('"properties".initNativeView', function in } // Would it be faster to delete all members of the old object? view._suspendedUpdates = {}; + + // if the view requestLayout was not suspended before + // it means we can request a layout if needed. + // will be done after otherwise + view.suspendRequestLayout = wasSuspended; + if (!wasSuspended && view.isLayoutRequestNeeded) { + view.requestLayout(); + } }); export function applyPendingNativeSetters(view: ViewBase): void { diff --git a/packages/core/ui/core/view-base/index.ts b/packages/core/ui/core/view-base/index.ts index fcce72427..e95f1f14b 100644 --- a/packages/core/ui/core/view-base/index.ts +++ b/packages/core/ui/core/view-base/index.ts @@ -431,7 +431,10 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition if (this._isLoaded) { return; } - + // the view is going to be layed out after + // no need for requestLayout which can be pretty slow because + // called a lot and going all up the chain to the page + this.suspendRequestLayout = true; this._isLoaded = true; this._cssState.onLoaded(); this._resumeNativeUpdates(SuspendType.Loaded); @@ -442,6 +445,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition return true; }); + this.suspendRequestLayout = false; this._emit('loaded'); } @@ -658,6 +662,20 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition } } + _requestLayoutNeeded = false; + + get isLayoutRequestNeeded() { + return this._requestLayoutNeeded; + } + + _suspendRequestLayout = false; + set suspendRequestLayout(value: boolean) { + this._suspendRequestLayout = value; + } + get suspendRequestLayout() { + return this._suspendRequestLayout; + } + @profile public requestLayout(): void { // Default implementation for non View instances (like TabViewItem). diff --git a/packages/core/ui/core/view/index.android.ts b/packages/core/ui/core/view/index.android.ts index 3fe65b87c..e7a2910d5 100644 --- a/packages/core/ui/core/view/index.android.ts +++ b/packages/core/ui/core/view/index.android.ts @@ -530,6 +530,11 @@ export class View extends ViewCommon { @profile public requestLayout(): void { + if (this._suspendRequestLayout) { + this._requestLayoutNeeded = true; + return; + } + this._requestLayoutNeeded = false; super.requestLayout(); if (this.nativeViewProtected) { this.nativeViewProtected.requestLayout(); diff --git a/packages/core/ui/core/view/index.ios.ts b/packages/core/ui/core/view/index.ios.ts index 862db9f0e..574f50f26 100644 --- a/packages/core/ui/core/view/index.ios.ts +++ b/packages/core/ui/core/view/index.ios.ts @@ -63,9 +63,21 @@ export class View extends ViewCommon implements ViewDefinition { this.once(View.loadedEvent, () => setupAccessibleView(this)); } + requestLayoutIfNeeded() { + if (this.isLayoutRequired) { + this._requestLayoutNeeded = false; + this.requestLayout(); + } + } + public requestLayout(): void { - super.requestLayout(); + if (this._suspendRequestLayout) { + this._requestLayoutNeeded = true; + return; + } + this._requestLayoutNeeded = false; this._privateFlags |= PFLAG_FORCE_LAYOUT; + super.requestLayout(); const nativeView = this.nativeViewProtected; if (nativeView && nativeView.setNeedsLayout) {