Performance

Two different problems — compile speed and runtime FPS — with different levers.

Runtime FPS

  • Lists: a plain v-for over NCard/NFlex keeps every item as a live, permanent native view forever. <ListView> (real, confirmed view recycling — backed by Android's RecyclerView / iOS's UITableView cell reuse) is the single biggest lever for scroll smoothness once a list goes past ~20–30 items.
  • Image decode size: an <Image> with no decode-width/decode-height fully decodes the source resolution into memory even when displayed much smaller. Matters most on image-heavy scrolling lists — <NetworkImage>/<CachedImage> already set these for you.
  • Animations should be native, not JS-driven: NSkeleton's shimmer uses View.animate(), which hands the animation off to the platform's own compositor instead of a JS per-frame loop — this is what lets it track a 120Hz display for free.
  • Layout nesting depth: NativeScript's layout is a real native measure/layout pass per nesting level — flattening deeply nested NFlex-in-NFlex-in-NCard chains into GridLayout cells reduces layout-pass cost on every scroll frame.

Build speed

ts-loader already runs with transpileOnly: true and a memory-tuned ForkTsCheckerWebpackPlugin. Adding cache: { type: 'filesystem' } to a project's webpack.config.cjs is the next real win for incremental dev rebuilds.

Gradle memory tuning

vastx-native init patches platforms/android/gradle.properties once, right after ns platform add scaffolds it: the stock @nativescript/android template ships a flat 16 GB Gradle daemon heap ceiling, regardless of the machine actually running the build. The replacement is computed from the machine's actual total RAM (35% of it, clamped to 768 MB–3 GB), written once and never touched again.

The generated webpack.config.cjs gets the same treatment for ForkTsCheckerWebpackPlugin: on a machine with less than 8 GB of RAM it's removed entirely, and above that threshold its memory limit is scaled to the machine instead of left at a flat default.