X Tutup
The Wayback Machine - https://web.archive.org/web/20231208092554/https://github.com/NativeScript/NativeScript/issues/8926
Skip to content
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

Removal of Snapshots support from NS 7.x #8926

Open
NathanaelA opened this issue Oct 2, 2020 · 4 comments
Open

Removal of Snapshots support from NS 7.x #8926

NathanaelA opened this issue Oct 2, 2020 · 4 comments
Assignees

Comments

@NathanaelA
Copy link
Contributor

NathanaelA commented Oct 2, 2020

Reason why we are removing...

Reasons for removal:

  • High Support cost (> 800 issues)
  • High dev costs (breaks frequently, OS changes like Mac requires Docker, Arm64 mac... etc)
  • Bugs with Snapshots (snapshots are imperfect; they normally work -- but occasionally we have seen issues)
  • Having to create additional wrappers to keep native code from being snapshotted; snapshots have to be pure JS. Meaning plugins can easily break your snapshots, and we are constrained on how to write certain pieces of code.
  • Inflates app distribution size
  • Inflates app on device size
  • Android Only
  • On modern devices, snapshots are actually slower than having no snapshots.
  • Snapshots are not optimizable. Meaning all running code from inside a snapshot cannot take advantage of many v8 optimization features while running, so their is a constant runtime performance hit.

Replaced with Code Cache

  • Built into the v8 engine (supported by v8 maintainers), no additional support costs to us at all.
  • Faster than Snapshots in every instance except the very first boot. Very first boot, is slower because it has to build the cache.
  • Faster than Snapshots on Slower devices by a wide %.
  • Supported on both iOS and Android
  • Code-Cache built is native to the device, app space used is considerably less than w/ snapshots
  • Not inflating apk/ipk with snapshots for the the different platforms.
  • No runtime speed hit, all code is fully optimizable by v8

Actual Raw Numbers: (Lots of numbers)
I used the NS Grocery App under NS 6, because it has multiple screens, and uses Angular and of course snapshots work. I built all apps as tns --release. I did NOT uglify nor do --env.production as the idea was to create the slowest possible app with the most JS code easily. 😀

So I have a couple different sets of numbers

App Sizes

Stock App (no code cache, no snapshots just the app as is)
APK Size: 22.2m - Install Size: 7.5m

Code Cache App
APK Size: 22.2m - Install Size: 10m (after code cache is built)

Snapshot App
APK Size: 28.4m - Install Size: 21m

As you can see; not only is the APK w/ snapshots is 27% larger and on disk it actually is way over 200% larger than code cache and almost 300% larger than stock.

Time to JS Executed in Milliseconds (on real devices):

Fast number is on a very fast modern android device (Samsung S9, Android 10), Slow number is very old slow device (Samsung A3, Android 5.0.2) -- All numbers were averaged, took between 5 to 12 samples depending on the variation seen in the numbers).

Type First JS Fast First JS Slow Complete JS Fast Complete JS Slow
Stock Application 467 1646 835 3194
Code Cache First Only 695 2152 1100 3726
Code Cache All Boots (except first) 298 924 673 2392
Snapshots 487 1310 970 2980

Note: Using Code Cache with Snapshot is even slower than either; because first startup you still have to build the cache & each startup after you have to load in TWO files, the snapshot and the cache; which kills your startup performance.

Explaining the Numbers:

First JS means the time for the engine to startup and the point where snapshots / caches have loaded -- this is before anything has loaded, basically the very first line of JS executed.

Complete JS means that the JS has parsed, caches/snapshots have parsed and the app is actually running -- this is when we actually hit the login screen. (So this is probably the more important number to consider as it is what your clients will think as the speed of your app.)

So on a fast device, the stock app will get to the login screen in 835ms, and on a very slow device 3194ms (or 3.194sec).

A couple interesting things, on a reasonably modern fast device, using snapshots are actually > 16% SLOWER than no snapshots. However on a slow device the speed difference is around 7% faster.

With Code Cache there is a performance hit for the very first time your app runs. As you can see even on a fast device the hit is 265ms slower (31%) on the first boot than the stock app. However, every app start after that the speed is 20% faster. On a slow device this hit is about 16% but again on all the rest of the startups, the speed up is 33% faster than the stock...


To us at the TSC, it does not make any sense to continue maintaining complex tooling that as you can see it considerably slower than code cache in all areas except a single app start.


To enable code cache in NS 6 (Android only):

Edit the main app/package.json and add the key
"codeCache": "true"
to the android key. like so:
image

To enable code cache in NS 7 (Android and iOS)
Edit your main nativescript.config.ts file, and add
"codeCache": "true" to the android and/or ios sections.
image

@NathanaelA NathanaelA self-assigned this Oct 2, 2020
@NativeScript NativeScript locked as resolved and limited conversation to collaborators Oct 2, 2020
@NathanaelA
Copy link
Contributor Author

NathanaelA commented Oct 2, 2020

Tracking Issue:

  • - Remove any docs referencing it
  • - Remove cli / webpack support for --env.snapshot

@JacobFJ
Copy link

JacobFJ commented Nov 7, 2020

@NathanaelA please tag it the docs 6.0 that snapshot was deprecating I wasted my time for installing docker and other tools needed to create snapshot when I realize to upgrade to NS 7.0. 👍

Big Thanks!

@ujwal-setlur
Copy link

Is this supported on iOS? TypeScript complains:

Type '{ codeCache: true; }' is not assignable to type 'IConfigIOS'.
  Object literal may only specify known properties, and 'codeCache' does not exist in type 'IConfigIOS'.ts(2322)

@NathanWalker NathanWalker unpinned this issue Apr 25, 2021
@fpaaske
Copy link

fpaaske commented Jan 13, 2022

Can anyone confirm if this is supported on iOS or not? I don't see the same compilation error as @ujwal-setlur (probably more relaxed rules), but do I see that the option is missing from IConfigIOS.

I also don't see any difference in startup time with this setting on or off on a medium sized app on iPhone 6, nor iPhone Xs.

ptomato added a commit to ptomato/ns-android-v8 that referenced this issue Feb 25, 2023
This is already switched off in release mode, and as per
NativeScript/NativeScript#8926 it's not
supported anymore in client code, so we should not have anything depending
on it in debug mode either.

TODO: try removing v8_snapshot from the static archive as well
ptomato added a commit to ptomato/ns-android that referenced this issue Feb 28, 2023
As per NativeScript/NativeScript#8926, this
isn't supported. "heapSnapshotScript" and "heapSnapshotBlob" keys in
package.json will be ignored, but I believe this isn't a breaking change
because I think they were already nonfunctional.
ptomato added a commit to ptomato/ns-android that referenced this issue Apr 19, 2023
As per NativeScript/NativeScript#8926, this
isn't supported. "heapSnapshotScript" and "heapSnapshotBlob" keys in
package.json will be ignored, but I believe this isn't a breaking change
because I think they were already nonfunctional.

The V8 library is updated with a build configured with
v8_use_external_startup_data=false, and we can remove the snapshot_blob.h
files because the snapshot data no longer needs to be compiled into the
runtime.
ptomato added a commit to ptomato/ns-android that referenced this issue May 5, 2023
As per NativeScript/NativeScript#8926, this
isn't supported. "heapSnapshotScript" and "heapSnapshotBlob" keys in
package.json will be ignored, but I believe this isn't a breaking change
because I think they were already nonfunctional.

The V8 library is updated with a build configured with
v8_use_external_startup_data=false, and we can remove the snapshot_blob.h
files because the snapshot data no longer needs to be compiled into the
runtime.

The V8 artifacts were built using NativeScript/v8-buildscripts and GitHub
Actions, with the following provenance:

arm64: commit 0368bca, job https://github.com/NativeScript/v8-buildscripts/actions/runs/4895461273
arm: commit b074e10, job https://github.com/NativeScript/v8-buildscripts/actions/runs/4895462464
x86_64: commit a9bf41b, job https://github.com/NativeScript/v8-buildscripts/actions/runs/4895463287
x86: commit e7aa7ed, job https://github.com/NativeScript/v8-buildscripts/actions/runs/4895464030
triniwiz pushed a commit to NativeScript/android that referenced this issue May 16, 2023
* feat: Remove V8 heap snapshot machinery

As per NativeScript/NativeScript#8926, this
isn't supported. "heapSnapshotScript" and "heapSnapshotBlob" keys in
package.json will be ignored, but I believe this isn't a breaking change
because I think they were already nonfunctional.

The V8 library is updated with a build configured with
v8_use_external_startup_data=false, and we can remove the snapshot_blob.h
files because the snapshot data no longer needs to be compiled into the
runtime.

The V8 artifacts were built using NativeScript/v8-buildscripts and GitHub
Actions, with the following provenance:

arm64: commit 0368bca, job https://github.com/NativeScript/v8-buildscripts/actions/runs/4895461273
arm: commit b074e10, job https://github.com/NativeScript/v8-buildscripts/actions/runs/4895462464
x86_64: commit a9bf41b, job https://github.com/NativeScript/v8-buildscripts/actions/runs/4895463287
x86: commit e7aa7ed, job https://github.com/NativeScript/v8-buildscripts/actions/runs/4895464030

* chore: Remove File::Exists()

This was primarily used by the heap snapshot code which is now removed.

It was also used internally in File::ReadBinary(), but that wasn't
necessary, as fopen() also handles the file not existing.

In new code, it's probably a good idea to perform operations without
checking if the file exists first anyway, as otherwise it can lead to race
conditions if the file is deleted.

* chore: Remove MemoryMappedFile

This was only used by the snapshot code, which is now removed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
X Tutup