Monthly Archives: May 2016

NativeScript: TypeScript Speed/Memory usage

For those who may have seen some post of mine on Slack about TypeScript being not a performant as JavaScript; I have finally done the real benchmarks and spent the time totally de-typescriptifing the NativeScript 2.00 runtimes.  And here is my startling results....

everythingyouknowiswrong

(c) 2010, Jan-Willem Reusink - https://www.flickr.com/photos/jimmybenson

Oh, wait; that is not right -- I was the one wrong.  😉

The actual real numbers do not bear out what I had believed based on some TypeScript tests that I had done in Node a while back.  I am still not sure why my initial tests in Node behaved differently; but after spending a couple days building the tests, using a large JS application and a totally de-typescriptified the NativeScript runtime, I can say without a doubt in my mind that TS add little to no meaningful hit to the runtimes.  On iOS I actually didn't see a memory difference at all, the GC seems to collect the memory so quickly, that it wasn't even showing up.    On android it takes about 40-60 more megabytes of memory for everything; however after the first GC, all the memory is reclaimed.     So yes, you do end up with a small amount wasted memory and GC pressure added.  However, with it ALL being reclaimed at the first GC; 40mb temporarily wasted really is a drop in the bucket for what TS does offer you.

The other thing that I was surprised by was that the TS runtimes actually started up faster than the pure JS versions.  Now that I had to reason through why TS code was starting faster than raw JS; it makes a lot of sense -- The reason why is because most classes are lazy instantiated.  So the amount of JS code actually compiled and ran by the v8/JSC engines are a lot smaller in TS compiled code because the majority of the code is inside the function that wraps each class.   So if a class isn't needed yet during startup (but is loaded via the require statements) then the time it spends running it is minuscule compared to a runtime that actually builds all the classes while it is loading each one.  So, even though the difference was in literally milliseconds, it still was measurable.  Eventually when you do have that class instanciated; you will have more time used their; but since each class being created later is literally measured in NanoSeconds, the hit later actually "feels" faster to the user since time to first pixel ended up being faster using TypeScript code...

Actual numbers (best of):

Startup time TS: 393,675,213 (NanoSeconds)
Startup time JS:  399,058,778 (NanoSeconds)

Memory Usage TS: 7,544,460 (Bytes)
Memory Usage JS: 7,488,292 (Bytes)

Memory after GC TS: 4,979,548 (Bytes)
Memory after GC JS: 4,993,268 (Bytes)

Please note the reason why GC JS is actually bigger than GC'd TS is more (all) classes have been defined, created and are in memory as real objects vs the raw un-instanciated source code in TS if they haven't been used yet.

So, guess what I am going to be using more of....  😉

NativeScript, TypeScript and accessing native Android runtimes

When you are trying to access any of the native android platform using TypeScript, TS will complain about the root name --
TS2304: Cannot find name 'zzzz' at line yyyy

TypeScript is unaware that those variables exist and are actually global in scope; so to make TypeScript happy; in your code you will want to do something like this:

declare var android: any;
declare var com: any;
declare var java: any;

This will tell TypeScript that these are global, so it will no longer throw an error when you try to access any classes that start with android, java, or com. If you are accessing any other classes that Android publishes, you can also use the same technique: declare var zzzz: any;

Small update; Josh mentioned it via twitter about installing the tns-platform-declarations.  I'm not sure why I didn't post this here also -- so I'm updating the post a tad -- installing the tns-platform-declarations will get you intellisense for the android & ios platforms.  It is well worth the download if you are using native ios or android calls.

Downgrading NativeScript

You might have decided to be an early adopter of the awesome new version of NativeScript release and then unfortunately do to some bug regretted that choice.   Well here is how to easily downgrade back to a version you prefer.

First of all, you normally do NOT need to downgrade the actual TNS / nativescript command, it is normally backwards compatible.  However if you do need to downgrade the command line utility you need to type:

npm remove -g nativescript

and then
npm install -g nativescript@version --- where version is the version you want.

Ok, now onto the two pieces that you should do at the same time.  So lets say you want to downgrade to the latest v1.6; you change to your apps main directory and would type:
npm install tns-core-modules@1.6.2

then type for android:
tns platform remove android
tns platform add android@1.6.3

and finally if for iOS:
tns platform remove ios
tns platform add ios@1.6.0

By doing these items, you will fully downgrade your app to a prior version of NativeScript.

Please note to get the version numbers of all the releases of a particular item; you can do:

npm info tns-android versions
npm info tns-ios versions
npm info tns-core-modules versions

You typically want the latest of a point release version, so you find the latest "z" version in the x.y.z branch you are looking to install. Please note the versions 2.0.0-YYYY-MM-DD-VVV like 2.0.0-2016-05-03-553 is a alpha/beta/test releases; all these dated versions you can safely ignore them.