Skip to content

Commit 90b7040

Browse files
author
Vladimir Enchev
committed
Merge pull request NativeScript#207 from NativeScript/feature/optimizations
Optimizations
2 parents 776959d + 3b8e27e commit 90b7040

11 files changed

Lines changed: 231 additions & 49 deletions

File tree

CrossPlatformModules.csproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@
131131
<TypeScriptCompile Include="apps\tests\layouts\dock-layout-tests.ts" />
132132
<TypeScriptCompile Include="apps\tests\pages\app.ts" />
133133
<TypeScriptCompile Include="apps\tests\pages\file-load-test.ts" />
134+
<TypeScriptCompile Include="apps\tests\pages\page-load-performance\start.ts" />
135+
<TypeScriptCompile Include="apps\tests\pages\page-load-performance\test-big.ts" />
136+
<TypeScriptCompile Include="apps\tests\pages\page-load-performance\test-small.ts" />
134137
<TypeScriptCompile Include="apps\tests\pages\page12.ts" />
135138
<TypeScriptCompile Include="apps\tests\layouts\absolute-layout-tests.ts" />
136139
<TypeScriptCompile Include="apps\tests\layouts\layout-helper.ts" />
@@ -618,6 +621,13 @@
618621
<Content Include="apps\TelerikNEXT\images\background.jpg" />
619622
<Content Include="apps\template-settings\app.css" />
620623
<Content Include="apps\tests\app\location-example.xml" />
624+
<Content Include="apps\tests\pages\page-load-performance\start.xml">
625+
<SubType>Designer</SubType>
626+
</Content>
627+
<Content Include="apps\tests\pages\page-load-performance\test-big.xml">
628+
<SubType>Designer</SubType>
629+
</Content>
630+
<Content Include="apps\tests\pages\page-load-performance\test-small.xml" />
621631
<Content Include="apps\tests\pages\page18.xml" />
622632
<Content Include="apps\tests\ui\bindingContext_testPage.xml" />
623633
<Content Include="apps\tests\ui\bindingContext_testPage1.xml" />
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import frame = require("ui/frame");
2+
import observable = require("data/observable");
3+
4+
declare function __startCPUProfiler(name: string);
5+
6+
export function navigate(args: observable.EventData) {
7+
var tag = "" + args.object.get("tag");
8+
__startCPUProfiler("xml-performance-" + tag);
9+
frame.topmost().navigate({
10+
moduleName: tag,
11+
});
12+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Page loaded="pageLoaded" >
2+
<StackLayout>
3+
<Button text="test small" tag="test-small" tap="navigate" />
4+
<Button text="test big" tag="test-big" tap="navigate" />
5+
<Button text="telerik next session" tag="telerik-next-session" tap="navigate" />
6+
</StackLayout>
7+
</Page>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import observable = require("data/observable");
2+
3+
declare function __stopCPUProfiler(name: string);
4+
5+
export function pageLoaded(args: observable.EventData) {
6+
__stopCPUProfiler("xml-performance-test-big");
7+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<Page loaded="pageLoaded" unloaded="pageUnloaded" backgroundColor="red">
2+
<StackLayout>
3+
<StackLayout>
4+
<Button text="1button1" />
5+
<Button text="1button2" />
6+
<Button text="1button3" />
7+
<Button text="1button4" />
8+
<Button text="1button5" />
9+
<Button text="1button6" />
10+
<Button text="1button7" />
11+
<Button text="1button8" />
12+
</StackLayout>
13+
<StackLayout>
14+
<Button text="2button1" />
15+
<Button text="2button2" />
16+
<Button text="2button3" />
17+
<Button text="2button4" />
18+
<Button text="2button5" />
19+
<Button text="2button6" />
20+
<Button text="2button7" />
21+
<Button text="2button8" />
22+
</StackLayout>
23+
<StackLayout>
24+
<Button text="3button1" />
25+
<Button text="3button2" />
26+
<Button text="3button3" />
27+
<Button text="3button4" />
28+
<Button text="3button5" />
29+
<Button text="3button6" />
30+
<Button text="3button7" />
31+
<Button text="3button8" />
32+
</StackLayout>
33+
<StackLayout>
34+
<Button text="4button1" />
35+
<Button text="4button2" />
36+
<Button text="4button3" />
37+
<Button text="4button4" />
38+
<Button text="4button5" />
39+
<Button text="4button6" />
40+
<Button text="4button7" />
41+
<Button text="4button8" />
42+
</StackLayout>
43+
<StackLayout>
44+
<Button text="5button1" />
45+
<Button text="5button2" />
46+
<Button text="5button3" />
47+
<Button text="5button4" />
48+
<Button text="5button5" />
49+
<Button text="5button6" />
50+
<Button text="5button7" />
51+
<Button text="5button8" />
52+
</StackLayout>
53+
</StackLayout>
54+
</Page>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import observable = require("data/observable");
2+
3+
declare function __stopCPUProfiler(name: string);
4+
5+
export function pageLoaded(args: observable.EventData) {
6+
__stopCPUProfiler("xml-performance-test-small");
7+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Page loaded="pageLoaded" unloaded="pageUnloaded" backgroundColor="green">
2+
<StackLayout>
3+
<Button text="button1" />
4+
<Button text="button2" />
5+
<Button text="button3" />
6+
<Button text="button4" />
7+
<Button text="button5" />
8+
<Button text="button6" />
9+
<Button text="button7" />
10+
<Button text="button8" />
11+
</StackLayout>
12+
</Page>

ui/core/dependency-observable.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ function validateRegisterParameters(name: string, ownerType: string) {
2424
}
2525

2626
function getPropertyByNameAndType(name: string, owner: any): Property {
27-
var baseClasses = types.getBaseClasses(owner);
28-
var i;
2927
var result;
3028
var key;
31-
for (i = 0; i < baseClasses.length; i++) {
32-
key = generatePropertyKey(name, baseClasses[i]);
29+
var classInfo = types.getClassInfo(owner);
30+
while (classInfo) {
31+
key = generatePropertyKey(name, classInfo.name);
3332
result = propertyFromKey[key];
3433
if (result) {
3534
break;
3635
}
36+
classInfo = classInfo.baseClassInfo;
3737
}
3838
return result;
3939
}

ui/styling/style.ts

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ import imageSource = require("image-source");
1313
import utils = require("utils/utils");
1414

1515
// key is the property id and value is Dictionary<string, StylePropertyChangedHandler>;
16-
var _registeredHandlers = {};
16+
var _registeredHandlers = Array<Object>();
17+
1718
// key is a className + property id and value is StylePropertyChangedHandler;
1819
var _handlersCache = {};
20+
1921
// classes like Frame that does not need to handle styling properties.
2022
var noStylingClasses = {};
2123

@@ -292,48 +294,53 @@ export function registerHandler(property: dependencyObservable.Property,
292294
handler: styling.stylers.StylePropertyChangedHandler,
293295
className?: string) {
294296
var realClassName = className ? className : "default";
295-
if (_registeredHandlers.hasOwnProperty(property.id + "")) {
296-
_registeredHandlers[property.id][realClassName] = handler;
297-
}
298-
else {
299-
var handlerRecord = {};
300-
handlerRecord[realClassName] = handler;
297+
298+
var handlerRecord = _registeredHandlers[property.id];
299+
if (!handlerRecord) {
300+
handlerRecord = {};
301301
_registeredHandlers[property.id] = handlerRecord;
302302
}
303+
304+
handlerRecord[realClassName] = handler;
303305
}
304306

305307
export function registerNoStylingClass(className) {
306308
noStylingClasses[className] = 1;
307309
}
308310

309311
export function getHandler(property: dependencyObservable.Property, view: view.View): styling.stylers.StylePropertyChangedHandler {
310-
var classNames = types.getBaseClasses(view);
311-
// adding default as last class name if no other class is found default handler will be used
312-
classNames.push("default");
313-
if (_handlersCache.hasOwnProperty(classNames[0] + property.id)) {
314-
return _handlersCache[classNames[0] + property.id];
312+
return getHandlerInternal(property.id, types.getClassInfo(view));
313+
}
314+
315+
function getHandlerInternal(propertyId: number, classInfo: types.ClassInfo): styling.stylers.StylePropertyChangedHandler {
316+
var className = classInfo ? classInfo.name : "default";
317+
var handlerKey = className + propertyId;
318+
319+
// try the cache first
320+
var result = _handlersCache[handlerKey];
321+
if (types.isDefined(result)) {
322+
return result;
323+
}
324+
325+
var propertyHandlers = _registeredHandlers[propertyId];
326+
if (noStylingClasses.hasOwnProperty(className) || !propertyHandlers) {
327+
// Reached 'no-styling' class or no property handlers are registered for this proeprtyID
328+
result = null;
329+
}
330+
else if (propertyHandlers.hasOwnProperty(className)) {
331+
// Found handler for this class
332+
result = propertyHandlers[className];
333+
}
334+
else if (classInfo) {
335+
// Check the base class
336+
result = getHandlerInternal(propertyId, classInfo.baseClassInfo);
315337
}
316338
else {
317-
var i;
318-
var propertyHandlers;
319-
var handler;
320-
propertyHandlers = _registeredHandlers[property.id];
321-
for (i = 0; i < classNames.length; i++) {
322-
if (propertyHandlers) {
323-
var loopClassName = classNames[i];
324-
if (noStylingClasses.hasOwnProperty(loopClassName)) {
325-
_handlersCache[loopClassName + property.id] = null;
326-
return null;
327-
}
328-
if (propertyHandlers.hasOwnProperty(loopClassName)) {
329-
handler = propertyHandlers[loopClassName];
330-
_handlersCache[loopClassName + property.id] = handler;
331-
return handler;
332-
}
333-
}
334-
}
339+
result = null;
335340
}
336-
return null;
341+
342+
_handlersCache[handlerKey] = result;
343+
return result;
337344
}
338345

339346
// Property registration

utils/types.d.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,26 @@
6161
* Return an array of strings with the name of all classes.
6262
*/
6363
export function getBaseClasses(object): Array<string>;
64+
65+
/**
66+
* A function that gets the ClassInfo for an object.
67+
* @param object The object for which the ClassInfo will be get.
68+
* Returns a ClassInfo for the object.
69+
*/
70+
export function getClassInfo(object: Object): ClassInfo;
71+
72+
/**
73+
* A Class holding information about a class
74+
*/
75+
export class ClassInfo {
76+
/**
77+
* Gets the name of the class.
78+
*/
79+
name: string;
80+
81+
/**
82+
* Gets the ClassInfo for the base class of the current info.
83+
*/
84+
baseClassInfo: ClassInfo;
85+
}
6486
}

0 commit comments

Comments
 (0)