Preload when ticked means it downloads before the app starts (ie during the orange loading screen).
The app size when you export the project is not the same as the amount of data that the user downloads when viewing the app.
Take this example: https://developer.playcanvas.com/en/tutorials/load-assets-with-a-progress-bar/
All the assets have preload unticked so it only loads the engine, scripts and scene JSON file as part of the preload step (orange loading bar). This is 290KB.
This gets us into the app quickly.
When the app starts, there’s a script that requests the assets to be loaded:
// More information about streaming assets at runtime can be found here
// http://developer.playcanvas.com/en/user-manual/assets/preloading-and-streaming/
// Note: All the texture and material assets that would like to be streamed at runtime
// should have 'level' unticked and in this demo's case, have been tagged with
// 'level'
var Preloader = pc.createScript('preloader');
Preloader.attributes.add("loadingBar", {type: "entity", title: "Loading Bar"});
Preloader.attributes.add("runeCards", {type: "entity", title: "Rune Cards"});
// initialize code called once per entity
Preloader.prototype.initialize = function() {
this.loadAssets();
};
Preloader.prototype.loadAssets = function() {
var self = this;
// Find all the assets that have been tagged 'level'
// In this example, they are in the 'assets-to-load' folder
var assets = this.app.assets.findByTag('level');
var assetsLoaded = 0;
var assestTotal = assets.length;
// Callback function when an asset is loaded
var onAssetLoad = function() {
assetsLoaded += 1;
// Update the progress bar
self.setLoadingBarProgress(assetsLoaded / assestTotal);
// Once we have loaded all the assets
if (assetsLoaded === assestTotal) {
self.onAssetsLoaded();
}
};
// Start loading all the assets
for(var i = 0; i < assets.length; i++) {
if (assets[i].resource) {
onAssetLoad();
} else {
assets[i].once('load', onAssetLoad);
this.app.assets.load(assets[i]);
}
}
if (!assets.length) {
this.onAssetsLoaded();
}
};
Preloader.prototype.onAssetsLoaded = function() {
// Disable the loading bar so it is no longer in view
this.loadingBar.enabled = false;
// Show the runes now that all the assets are loaded
this.runeCards.enabled = true;
};
Preloader.prototype.setLoadingBarProgress = function(progress) {
var localScale = this.loadingBar.getLocalScale();
localScale.x = pc.math.clamp(progress, 0, 1);
this.loadingBar.setLocalScale(localScale);
};
And that loads the rest of the assets (which in this case is not very much) (97KB)
There’s a bit more nuance to this but that’s the general idea. This means that the developer can ensure that only the assets needed for what the user would see first (eg, a title screen with a menu) is loaded during the orange bar loading screen. And later can load/unload asset on demand depending on what the user does.