Skip to content

Add profiling for some key points in the nativescript-angular lifecycle #837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions nativescript-angular/directives/list-view-comp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ListView, ItemEventData } from "tns-core-modules/ui/list-view";
import { View, KeyedTemplate } from "tns-core-modules/ui/core/view";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { LayoutBase } from "tns-core-modules/ui/layouts/layout-base";
import { profile } from "tns-core-modules/profiling";

import { CommentNode } from "../element-registry";
import { isListLikeIterable } from "../collection-facade";
Expand Down Expand Up @@ -148,6 +149,7 @@ export class ListViewComponent implements DoCheck, OnDestroy, AfterContentInit {
this._templateMap.set(key, keyedTemplate);
}

@profile
public onItemLoading(args: ItemEventData) {
if (!args.view && !this.itemTemplate) {
return;
Expand Down Expand Up @@ -195,6 +197,7 @@ export class ListViewComponent implements DoCheck, OnDestroy, AfterContentInit {
this.setupItemView.next({ view: viewRef, data: data, index: index, context: context });
}

@profile
private detectChangesOnChild(viewRef: EmbeddedViewRef<ListItemContext>, index: number) {
listViewLog("Manually detect changes in child: " + index);
viewRef.markForCheck();
Expand Down
22 changes: 16 additions & 6 deletions nativescript-angular/platform-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "./zone-js/dist/zone-nativescript";
import "reflect-metadata";
import "./polyfills/array";
import "./polyfills/console";
import { profile } from "tns-core-modules/profiling";

import {
Type,
Expand Down Expand Up @@ -68,6 +69,7 @@ export class NativeScriptPlatformRef extends PlatformRef {
super();
}

@profile
bootstrapModuleFactory<M>(moduleFactory: NgModuleFactory<M>): Promise<NgModuleRef<M>> {
this._bootstrapper = () => this.platform.bootstrapModuleFactory(moduleFactory);

Expand All @@ -76,6 +78,7 @@ export class NativeScriptPlatformRef extends PlatformRef {
return null; // Make the compiler happy
}

@profile
bootstrapModule<M>(
moduleType: Type<M>,
compilerOptions: CompilerOptions | CompilerOptions[] = []
Expand All @@ -87,6 +90,7 @@ export class NativeScriptPlatformRef extends PlatformRef {
return null; // Make the compiler happy
}

@profile
private bootstrapApp() {
(<any>global).__onLiveSyncCore = () => this.livesyncModule();

Expand Down Expand Up @@ -139,6 +143,7 @@ export class NativeScriptPlatformRef extends PlatformRef {
return this.platform.destroyed;
}

@profile
private createNavigationEntry(
bootstrapAction: BootstrapperAction,
resolve?: (comp: NgModuleRef<any>) => void,
Expand All @@ -150,20 +155,25 @@ export class NativeScriptPlatformRef extends PlatformRef {

const navEntry: NavigationEntry = {
create: (): Page => {
let page = pageFactory({ isBootstrap: true, isLivesync });
const page = pageFactory({ isBootstrap: true, isLivesync });
setRootPage(page);
if (this.appOptions) {
page.actionBarHidden = this.appOptions.startPageActionBarHidden;
}

let initHandler = function () {
const initHandlerMethodName =
"nativescript-angular/platform-common.initHandler";
const initHandler = profile(initHandlerMethodName, () => {
page.off(Page.navigatingToEvent, initHandler);
// profiling.stop("application-start");
rendererLog("Page loaded");

// profiling.start("ng-bootstrap");
rendererLog("BOOTSTRAPPING...");
bootstrapAction().then((moduleRef) => {

const bootstrapMethodName =
"nativescript-angular/platform-common.postBootstrapAction";
bootstrapAction().then(profile(bootstrapMethodName, moduleRef => {
// profiling.stop("ng-bootstrap");
rendererLog("ANGULAR BOOTSTRAP DONE.");
lastBootstrappedModule = new WeakRef(moduleRef);
Expand All @@ -172,9 +182,9 @@ export class NativeScriptPlatformRef extends PlatformRef {
resolve(moduleRef);
}
return moduleRef;
}, (err) => {
}), err => {
rendererError("ERROR BOOTSTRAPPING ANGULAR");
let errorMessage = err.message + "\n\n" + err.stack;
const errorMessage = err.message + "\n\n" + err.stack;
rendererError(errorMessage);

let view = new TextView();
Expand All @@ -185,7 +195,7 @@ export class NativeScriptPlatformRef extends PlatformRef {
reject(err);
}
});
};
});

page.on(Page.navigatingToEvent, initHandler);

Expand Down
30 changes: 28 additions & 2 deletions nativescript-angular/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Device } from "tns-core-modules/platform";
import { View } from "tns-core-modules/ui/core/view";
import { addCss } from "tns-core-modules/application";
import { topmost } from "tns-core-modules/ui/frame";
import { profile } from "tns-core-modules/profiling";

import { APP_ROOT_VIEW, DEVICE, getRootPage } from "./platform-providers";
import { isBlank } from "./lang-facade";
Expand Down Expand Up @@ -83,119 +84,143 @@ export class NativeScriptRenderer extends Renderer2 {
traceLog("NativeScriptRenderer created");
}

@profile
appendChild(parent: any, newChild: NgView): void {
traceLog(`NativeScriptRenderer.appendChild child: ${newChild} parent: ${parent}`);
this.viewUtil.insertChild(parent, newChild);
}

@profile
insertBefore(parent: NgView, newChild: NgView, refChildIndex: number): void {
traceLog(`NativeScriptRenderer.insertBefore child: ${newChild} parent: ${parent}`);
this.viewUtil.insertChild(parent, newChild, refChildIndex);
}

@profile
removeChild(parent: any, oldChild: NgView): void {
traceLog(`NativeScriptRenderer.removeChild child: ${oldChild} parent: ${parent}`);
this.viewUtil.removeChild(parent, oldChild);
}

@profile
selectRootElement(selector: string): NgView {
traceLog("selectRootElement: " + selector);
return this.rootView;
}

@profile
parentNode(node: NgView): any {
return node.parent || node.templateParent;
}

@profile
nextSibling(node: NgView): number {
traceLog(`NativeScriptRenderer.nextSibling ${node}`);
return this.viewUtil.nextSiblingIndex(node);
}

@profile
createComment(_value: any): CommentNode {
traceLog(`NativeScriptRenderer.createComment ${_value}`);
return this.viewUtil.createComment();
}

@profile
createElement(name: any, _namespace: string): NgView {
traceLog(`NativeScriptRenderer.createElement: ${name}`);
return this.viewUtil.createView(name);
}

@profile
createText(_value: string): CommentNode {
traceLog(`NativeScriptRenderer.createText ${_value}`);
return this.viewUtil.createText();
}

@profile
createViewRoot(hostElement: NgView): NgView {
traceLog(`NativeScriptRenderer.createViewRoot ${hostElement.nodeName}`);
return hostElement;
}

@profile
projectNodes(parentElement: NgView, nodes: NgView[]): void {
traceLog("NativeScriptRenderer.projectNodes");
nodes.forEach((node) => this.viewUtil.insertChild(parentElement, node));
}

@profile
destroy() {
traceLog("NativeScriptRenderer.destroy");
// Seems to be called on component dispose only (router outlet)
// TODO: handle this when we resolve routing and navigation.
}

@profile
setAttribute(view: NgView, name: string, value: string, namespace?: string) {
traceLog(`NativeScriptRenderer.setAttribute ${view} : ${name} = ${value}, namespace: ${namespace}`);
return this.viewUtil.setProperty(view, name, value, namespace);
}

@profile
removeAttribute(_el: NgView, _name: string): void {
traceLog(`NativeScriptRenderer.removeAttribute ${_el}: ${_name}`);
}

@profile
setProperty(view: any, name: string, value: any) {
traceLog(`NativeScriptRenderer.setProperty ${view} : ${name} = ${value}`);
return this.viewUtil.setProperty(view, name, value);
}

@profile
addClass(view: NgView, name: string): void {
traceLog(`NativeScriptRenderer.addClass ${name}`);
this.viewUtil.addClass(view, name);
}

@profile
removeClass(view: NgView, name: string): void {
traceLog(`NativeScriptRenderer.removeClass ${name}`);
this.viewUtil.removeClass(view, name);
}

@profile
setStyle(view: NgView, styleName: string, value: any, _flags?: RendererStyleFlags2): void {
traceLog(`NativeScriptRenderer.setStyle: ${styleName} = ${value}`);
this.viewUtil.setStyle(view, styleName, value);
}

@profile
removeStyle(view: NgView, styleName: string, _flags?: RendererStyleFlags2): void {
traceLog("NativeScriptRenderer.removeStyle: ${styleName}");
this.viewUtil.removeStyle(view, styleName);
}

// Used only in debug mode to serialize property changes to comment nodes,
// such as <template> placeholders.
@profile
setBindingDebugInfo(renderElement: NgView, propertyName: string, propertyValue: string): void {
traceLog("NativeScriptRenderer.setBindingDebugInfo: " + renderElement + ", " +
propertyName + " = " + propertyValue);
}

@profile
setElementDebugInfo(renderElement: any, _info: any /*RenderDebugInfo*/): void {
traceLog("NativeScriptRenderer.setElementDebugInfo: " + renderElement);
}

@profile
invokeElementMethod(_renderElement: NgView, methodName: string, args: Array<any>) {
traceLog("NativeScriptRenderer.invokeElementMethod " + methodName + " " + args);
}

@profile
setValue(_renderNode: any, _value: string) {
traceLog("NativeScriptRenderer.setValue");
}

@profile
listen(renderElement: any, eventName: string, callback: (event: any) => boolean):
() => void {
traceLog("NativeScriptRenderer.listen: " + eventName);
Expand Down Expand Up @@ -251,16 +276,17 @@ class EmulatedRenderer extends NativeScriptRenderer {
return view;
}

@profile
private addStyles(styles: (string | any[])[], componentId: string) {
styles.map(s => s.toString())
.map(s => replaceNgAttribute(s, componentId))
.forEach(addStyleToCss);
}
}

function addStyleToCss(style: string): void {
const addStyleToCss = profile('"renderer".addStyleToCss', function addStyleToCss(style: string): void {
addCss(style);
}
});

function replaceNgAttribute(input: string, componentId: string): string {
return input.replace(COMPONENT_REGEX, componentId);
Expand Down
3 changes: 3 additions & 0 deletions nativescript-angular/router/page-router-outlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ViewContainerRef, Type, InjectionToken,
Inject, ComponentFactoryResolver, Injector
} from "@angular/core";
import { profile } from "tns-core-modules/profiling";
import { RouterOutletMap, ActivatedRoute, PRIMARY_OUTLET } from "@angular/router";
import { Device } from "tns-core-modules/platform";
import { Frame } from "tns-core-modules/ui/frame";
Expand Down Expand Up @@ -148,6 +149,7 @@ export class PageRouterOutlet { // tslint:disable-line:directive-class-suffix
* Called by the Router to instantiate a new component during the commit phase of a navigation.
* This method in turn is responsible for calling the `routerOnActivate` hook of its child.
*/
@profile
activateWith(
activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver|null,
outletMap: RouterOutletMap): void {
Expand Down Expand Up @@ -231,6 +233,7 @@ export class PageRouterOutlet { // tslint:disable-line:directive-class-suffix
this.currentActivatedComp = cacheItem.componentRef;
}

@profile
private loadComponentInPage(page: Page, componentRef: ComponentRef<any>): void {
// Component loaded. Find its root native view.
const componentView = componentRef.location.nativeElement;
Expand Down