Skip to content
Permalink
Browse files

perf(ivy): split view processing into render (create) and refresh (up…

…date) pass (#32020)

PR Close #32020
  • Loading branch information...
pkozlowski-opensource authored and kara committed Aug 2, 2019
1 parent 4d96cf5 commit b9dfe66028676ab2e47805fccac88918f2320289
@@ -17,17 +17,17 @@ import {assertComponentType} from './assert';
import {getComponentDef} from './definition';
import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di';
import {registerPostOrderHooks, registerPreOrderHooks} from './hooks';
import {CLEAN_PROMISE, addToViewTree, createLView, createTView, getOrCreateTNode, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, markAsComponentHost, refreshDescendantViews} from './instructions/shared';
import {CLEAN_PROMISE, addToViewTree, createLView, createTView, getOrCreateTNode, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, markAsComponentHost, refreshView, renderView} from './instructions/shared';
import {ComponentDef, ComponentType, RenderFlags} from './interfaces/definition';
import {TElementNode, TNode, TNodeType} from './interfaces/node';
import {PlayerHandler} from './interfaces/player';
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
import {CONTEXT, FLAGS, HEADER_OFFSET, LView, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
import {CONTEXT, HEADER_OFFSET, LView, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
import {enterView, getPreviousOrParentTNode, leaveView, resetComponentState, setActiveHostElement} from './state';
import {publishDefaultGlobalUtils} from './util/global_utils';
import {defaultScheduler, stringifyForError} from './util/misc_utils';
import {getRootContext} from './util/view_traversal_utils';
import {readPatchedLView, resetPreOrderHookFlags} from './util/view_utils';
import {readPatchedLView} from './util/view_utils';



@@ -128,29 +128,28 @@ export function renderComponent<T>(
const rootContext = createRootContext(opts.scheduler, opts.playerHandler);

const renderer = rendererFactory.createRenderer(hostRNode, componentDef);
const rootTView = createTView(-1, null, 1, 0, null, null, null, null);
const rootView: LView = createLView(
null, createTView(-1, null, 1, 0, null, null, null, null), rootContext, rootFlags, null, null,
rendererFactory, renderer, undefined, opts.injector || null);
null, rootTView, rootContext, rootFlags, null, null, rendererFactory, renderer, undefined,
opts.injector || null);

const oldView = enterView(rootView, null);
let component: T;

// Will become true if the `try` block executes with no errors.
let safeToRunHooks = false;
try {
if (rendererFactory.begin) rendererFactory.begin();
const componentView = createRootComponentView(
hostRNode, componentDef, rootView, rendererFactory, renderer, sanitizer);
component = createRootComponent(
componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);

refreshDescendantViews(rootView); // creation mode pass
rootView[FLAGS] &= ~LViewFlags.CreationMode;
resetPreOrderHookFlags(rootView);
refreshDescendantViews(rootView); // update mode pass
safeToRunHooks = true;
// create mode pass
renderView(rootView, rootTView, null);
// update mode pass
refreshView(rootView, rootTView, null, null);

} finally {
leaveView(oldView, safeToRunHooks);
leaveView(oldView);
if (rendererFactory.end) rendererFactory.end();
}

@@ -24,7 +24,7 @@ import {assertComponentType} from './assert';
import {LifecycleHooksFeature, createRootComponent, createRootComponentView, createRootContext} from './component';
import {getComponentDef} from './definition';
import {NodeInjector} from './di';
import {addToViewTree, assignTViewNodeToLView, createLView, createTView, elementCreate, locateHostElement, refreshDescendantViews} from './instructions/shared';
import {assignTViewNodeToLView, createLView, createTView, elementCreate, locateHostElement, renderView} from './instructions/shared';
import {ComponentDef} from './interfaces/definition';
import {TContainerNode, TElementContainerNode, TElementNode} from './interfaces/node';
import {RNode, RendererFactory3, domRendererFactory3, isProceduralRenderer} from './interfaces/renderer';
@@ -161,18 +161,17 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
}

// Create the root view. Uses empty TView and ContentTemplate.
const rootTView = createTView(-1, null, 1, 0, null, null, null, null);
const rootLView = createLView(
null, createTView(-1, null, 1, 0, null, null, null, null), rootContext, rootFlags, null,
null, rendererFactory, renderer, sanitizer, rootViewInjector);
null, rootTView, rootContext, rootFlags, null, null, rendererFactory, renderer, sanitizer,
rootViewInjector);

// rootView is the parent when bootstrapping
const oldLView = enterView(rootLView, null);

let component: T;
let tElementNode: TElementNode;

// Will become true if the `try` block executes with no errors.
let safeToRunHooks = false;
try {
const componentView = createRootComponentView(
hostRNode, this.componentDef, rootLView, rendererFactory, renderer);
@@ -193,10 +192,9 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
component = createRootComponent(
componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);

refreshDescendantViews(rootLView);
safeToRunHooks = true;
renderView(rootLView, rootTView, null);
} finally {
leaveView(oldLView, safeToRunHooks);
leaveView(oldLView);
}

const componentRef = new ComponentRef(
@@ -705,7 +705,7 @@ function createDynamicNodeAtIndex(

// We are creating a dynamic node, the previous tNode might not be pointing at this node.
// We will link ourselves into the tree later with `appendI18nNode`.
if (previousOrParentTNode.next === tNode) {
if (previousOrParentTNode && previousOrParentTNode.next === tNode) {
previousOrParentTNode.next = null;
}

@@ -11,12 +11,14 @@ import {assertLContainerOrUndefined} from '../assert';
import {ACTIVE_INDEX, CONTAINER_HEADER_OFFSET, LContainer} from '../interfaces/container';
import {RenderFlags} from '../interfaces/definition';
import {TContainerNode, TNodeType} from '../interfaces/node';
import {FLAGS, LView, LViewFlags, PARENT, TVIEW, TView, T_HOST} from '../interfaces/view';
import {CONTEXT, LView, LViewFlags, PARENT, TVIEW, TView, T_HOST} from '../interfaces/view';
import {assertNodeType} from '../node_assert';
import {insertView, removeView} from '../node_manipulation';
import {enterView, getIsParent, getLView, getPreviousOrParentTNode, leaveView, setIsParent, setPreviousOrParentTNode} from '../state';
import {isCreationMode, resetPreOrderHookFlags} from '../util/view_utils';
import {assignTViewNodeToLView, createLView, createTView, refreshDescendantViews} from './shared';
import {isCreationMode} from '../util/view_utils';

import {assignTViewNodeToLView, createLView, createTView, refreshView, renderView} from './shared';


/**
* Marks the start of an embedded view.
@@ -126,19 +128,17 @@ function scanForView(lContainer: LContainer, startIdx: number, viewBlockId: numb
*/
export function ɵɵembeddedViewEnd(): void {
const lView = getLView();
const tView = lView[TVIEW];
const viewHost = lView[T_HOST];
const context = lView[CONTEXT];

if (isCreationMode(lView)) {
refreshDescendantViews(lView); // creation mode pass
lView[FLAGS] &= ~LViewFlags.CreationMode;
renderView(lView, tView, context); // creation mode pass
}
resetPreOrderHookFlags(lView);
refreshDescendantViews(lView); // update mode pass
refreshView(lView, tView, tView.template, context); // update mode pass

const lContainer = lView[PARENT] as LContainer;
ngDevMode && assertLContainerOrUndefined(lContainer);
// It's always safe to run hooks here, as `leaveView` is not called during the 'finally' block
// of a try-catch-finally statement, so it can never be reached while unwinding the stack due to
// an error being thrown.
leaveView(lContainer[PARENT] !, /* safeToRunHooks */ true);
leaveView(lContainer[PARENT] !);
setPreviousOrParentTNode(viewHost !, false);
}

0 comments on commit b9dfe66

Please sign in to comment.
You can’t perform that action at this time.