Vastly improve game loading time

pull/1415/merge
tobspr 2 years ago
parent 400cc5fe81
commit dfa392907d

@ -76,15 +76,23 @@ function gulptasksHTML($, gulp, buildFolder) {
// Do not need to preload in app or standalone // Do not need to preload in app or standalone
if (!hasLocalFiles) { if (!hasLocalFiles) {
// Preload essentials // Preload essentials
const preloads = ["fonts/GameFont.woff2"]; const preloads = [
"res/fonts/GameFont.woff2",
"async-resources.css",
"res/sounds/music/theme-short.mp3",
];
preloads.forEach(src => { preloads.forEach(src => {
const preloadLink = document.createElement("link"); const preloadLink = document.createElement("link");
preloadLink.rel = "preload"; preloadLink.rel = "preload";
preloadLink.href = cachebust("res/" + src); preloadLink.href = cachebust(src);
if (src.endsWith(".woff2")) { if (src.endsWith(".woff2")) {
preloadLink.setAttribute("crossorigin", "anonymous"); preloadLink.setAttribute("crossorigin", "anonymous");
preloadLink.setAttribute("as", "font"); preloadLink.setAttribute("as", "font");
} else if (src.endsWith(".css")) {
preloadLink.setAttribute("as", "style");
} else if (src.endsWith(".mp3")) {
preloadLink.setAttribute("as", "audio");
} else { } else {
preloadLink.setAttribute("as", "image"); preloadLink.setAttribute("as", "image");
} }

@ -60,7 +60,6 @@
} }
& { & {
/* @load-async */
background: rgba($mainBgColor, 0.9) uiResource("loading.svg") center center / #{D(60px)} no-repeat; background: rgba($mainBgColor, 0.9) uiResource("loading.svg") center center / #{D(60px)} no-repeat;
} }
} }

@ -398,7 +398,6 @@ canvas {
vertical-align: middle; vertical-align: middle;
& { & {
/* @load-async */
background: uiResource("loading.svg") center center / contain no-repeat; background: uiResource("loading.svg") center center / contain no-repeat;
} }
} }
@ -483,7 +482,6 @@ canvas {
} }
& { & {
/* @load-async */
background: uiResource("loading.svg") center center / #{D(40px)} no-repeat; background: uiResource("loading.svg") center center / #{D(40px)} no-repeat;
} }
} }

@ -142,7 +142,6 @@
opacity: 0.4; opacity: 0.4;
} }
& { & {
/* @load-async */
background: uiResource("icons/close.png") center center / 80% no-repeat; background: uiResource("icons/close.png") center center / 80% no-repeat;
} }
} }
@ -292,7 +291,7 @@
content: " "; content: " ";
display: inline-block; display: inline-block;
background: rgba(#fff, 0.6); background: rgba(#fff, 0.6);
@include InlineAnimation(3s linear) { @include InlineAnimation(1s linear) {
0% { 0% {
width: 100%; width: 100%;
} }

@ -75,12 +75,10 @@ $languages: en, de, cs, da, et, es-419, fr, it, pt-BR, sv, tr, el, ru, uk, zh-TW
@each $language in $languages { @each $language in $languages {
[data-languageicon="#{$language}"] { [data-languageicon="#{$language}"] {
/* @load-async */
background-image: uiResource("languages/#{$language}.svg") !important; background-image: uiResource("languages/#{$language}.svg") !important;
} }
} }
.steam_dlbtn_0 { .steam_dlbtn_0 {
/* @load-async */
background-image: uiResource("steam_link_btn/0.png") !important; background-image: uiResource("steam_link_btn/0.png") !important;
} }

@ -36,12 +36,10 @@
background: transparent center center / 40% no-repeat; background: transparent center center / 40% no-repeat;
opacity: 0.9; opacity: 0.9;
&.editKeybinding { &.editKeybinding {
/* @load-async */
background-image: uiResource("icons/edit_key.png"); background-image: uiResource("icons/edit_key.png");
} }
&.resetKeybinding { &.resetKeybinding {
/* @load-async */
background-image: uiResource("icons/reset_key.png"); background-image: uiResource("icons/reset_key.png");
} }

@ -23,7 +23,6 @@
pointer-events: all; pointer-events: all;
cursor: pointer; cursor: pointer;
& { & {
/* @load-async */
background: uiResource("icons/main_menu_settings.png") center center / contain no-repeat; background: uiResource("icons/main_menu_settings.png") center center / contain no-repeat;
} }
transition: opacity 0.12s ease-in-out; transition: opacity 0.12s ease-in-out;
@ -35,7 +34,6 @@
} }
.exitAppButton { .exitAppButton {
/* @load-async */
background-image: uiResource("icons/main_menu_exit.png"); background-image: uiResource("icons/main_menu_exit.png");
background-size: 90%; background-size: 90%;
} }
@ -350,7 +348,6 @@
opacity: 0.5; opacity: 0.5;
background: transparent center center/ 80% no-repeat; background: transparent center center/ 80% no-repeat;
& { & {
/* @load-async */
background-image: uiResource("icons/edit_key.png") !important; background-image: uiResource("icons/edit_key.png") !important;
} }
@include DarkThemeInvert; @include DarkThemeInvert;
@ -501,10 +498,6 @@
// @include S(width, 20px); // @include S(width, 20px);
// & {
// /* @load-async */
// background-image: uiResource("res/ui/icons/mods_white.png") !important;
// }
background-position: center center; background-position: center center;
background-size: D(15px); background-size: D(15px);
background-color: $modsColor !important; background-color: $modsColor !important;
@ -574,7 +567,6 @@
button.resumeGame { button.resumeGame {
background-color: #44484a; background-color: #44484a;
& { & {
/* @load-async */
background-image: uiResource("icons/play.png"); background-image: uiResource("icons/play.png");
} }
} }
@ -585,7 +577,6 @@
background-color: transparent; background-color: transparent;
& { & {
/* @load-async */
background-image: uiResource("icons/download.png"); background-image: uiResource("icons/download.png");
} }
@include S(width, 15px); @include S(width, 15px);
@ -609,7 +600,6 @@
@include IncreasedClickArea(0px); @include IncreasedClickArea(0px);
& { & {
/* @load-async */
background-image: uiResource("icons/delete.png"); background-image: uiResource("icons/delete.png");
} }
@include S(width, 15px); @include S(width, 15px);
@ -630,7 +620,6 @@
@include IncreasedClickArea(2px); @include IncreasedClickArea(2px);
& { & {
/* @load-async */
background-image: uiResource("icons/edit_key.png"); background-image: uiResource("icons/edit_key.png");
} }
@include S(width, 10px); @include S(width, 10px);
@ -724,7 +713,6 @@
overflow: hidden; overflow: hidden;
& { & {
/* @load-async */
background: #fff uiResource("wegame_isbn_rating.jpg") center center / contain no-repeat; background: #fff uiResource("wegame_isbn_rating.jpg") center center / contain no-repeat;
} }
} }
@ -791,11 +779,9 @@
@include S(height, 50px); @include S(height, 50px);
background: center center / 80% no-repeat; background: center center / 80% no-repeat;
&.githubLogo { &.githubLogo {
/* @load-async */
background-image: uiResource("main_menu/github.png"); background-image: uiResource("main_menu/github.png");
} }
&.discordLogo { &.discordLogo {
/* @load-async */
background-image: uiResource("main_menu/discord.png"); background-image: uiResource("main_menu/discord.png");
background-size: 95%; background-size: 95%;
} }
@ -837,15 +823,12 @@
transition: background-color 0.12s ease-in-out; transition: background-color 0.12s ease-in-out;
&.redditLink { &.redditLink {
/* @load-async */
background-image: uiResource("main_menu/reddit.svg"); background-image: uiResource("main_menu/reddit.svg");
} }
&.changelog { &.changelog {
/* @load-async */
background-image: uiResource("main_menu/changelog.svg"); background-image: uiResource("main_menu/changelog.svg");
} }
&.helpTranslate { &.helpTranslate {
/* @load-async */
background-image: uiResource("main_menu/translate.svg"); background-image: uiResource("main_menu/translate.svg");
} }
} }

@ -31,7 +31,6 @@
height: 80px; height: 80px;
min-height: 40px; min-height: 40px;
& { & {
/* @load-async */
background: uiResource("steam_link_btn/0.png") center center / contain no-repeat; background: uiResource("steam_link_btn/0.png") center center / contain no-repeat;
} }
overflow: hidden; overflow: hidden;

@ -77,7 +77,6 @@
opacity: 0.2; opacity: 0.2;
} }
&::before { &::before {
/* @load-async */
background-image: uiResource("res/ui/icons/mods.png") !important; background-image: uiResource("res/ui/icons/mods.png") !important;
} }
} }

@ -247,7 +247,6 @@
@include DarkThemeInvert; @include DarkThemeInvert;
& { & {
/* @load-async */
background-image: uiResource("icons/delete.png") !important; background-image: uiResource("icons/delete.png") !important;
} }
} }
@ -275,7 +274,6 @@
@include DarkThemeInvert; @include DarkThemeInvert;
& { & {
/* @load-async */
background: uiResource("icons/puzzle_plays.png") #{D(2px)} #{D(2.5px)} / #{D( background: uiResource("icons/puzzle_plays.png") #{D(2px)} #{D(2.5px)} / #{D(
8px 8px
)} #{D(8px)} no-repeat; )} #{D(8px)} no-repeat;
@ -293,7 +291,6 @@
@include DarkThemeInvert; @include DarkThemeInvert;
& { & {
/* @load-async */
background: uiResource("icons/puzzle_upvotes.png") #{D(2px)} #{D(2.4px)} / #{D( background: uiResource("icons/puzzle_upvotes.png") #{D(2px)} #{D(2.4px)} / #{D(
9px 9px
)} #{D(9px)} no-repeat; )} #{D(9px)} no-repeat;
@ -349,14 +346,12 @@
opacity: 0.1; opacity: 0.1;
& { & {
/* @load-async */
background: uiResource("icons/puzzle_complete_indicator.png") center center / background: uiResource("icons/puzzle_complete_indicator.png") center center /
contain no-repeat; contain no-repeat;
} }
} }
@include DarkThemeOverride { @include DarkThemeOverride {
&::after { &::after {
/* @load-async */
background: uiResource("icons/puzzle_complete_indicator_inverse.png") center background: uiResource("icons/puzzle_complete_indicator_inverse.png") center
center / contain no-repeat; center / contain no-repeat;
} }

@ -202,7 +202,6 @@
@include S(padding-right, 15px); @include S(padding-right, 15px);
& { & {
/* @load-async */
background: #fff uiResource("icons/enum_selector.png") calc(100% - #{D(5px)}) background: #fff uiResource("icons/enum_selector.png") calc(100% - #{D(5px)})
calc(50% + #{D(1px)}) / #{D(15px)} no-repeat; calc(50% + #{D(1px)}) / #{D(15px)} no-repeat;
} }
@ -244,7 +243,6 @@
background-color: $darkModeControlsBackground; background-color: $darkModeControlsBackground;
& { & {
/* @load-async */
background-image: uiResource("icons/enum_selector_white.png"); background-image: uiResource("icons/enum_selector_white.png");
} }
color: #ddd; color: #ddd;

@ -27,7 +27,6 @@
@include S(margin-right, 10px); @include S(margin-right, 10px);
@include S(margin-left, -5px); @include S(margin-left, -5px);
& { & {
/* @load-async */
background: uiResource("icons/state_back_button.png") center center / 70% no-repeat; background: uiResource("icons/state_back_button.png") center center / 70% no-repeat;
} }
} }

@ -78,6 +78,8 @@ export class BackgroundResourcesLoader {
// Avoid loading stuff twice // Avoid loading stuff twice
this.spritesLoaded = []; this.spritesLoaded = [];
this.soundsLoaded = []; this.soundsLoaded = [];
this.atlasesLoaded = [];
this.cssLoaded = [];
} }
getNumAssetsLoaded() { getNumAssetsLoaded() {
@ -122,7 +124,6 @@ export class BackgroundResourcesLoader {
logger.log("⏰ Finish load: main menu"); logger.log("⏰ Finish load: main menu");
this.mainMenuReady = true; this.mainMenuReady = true;
this.signalMainMenuLoaded.dispatch(); this.signalMainMenuLoaded.dispatch();
this.internalStartLoadingEssentialsForBareGame();
}); });
} }
@ -161,6 +162,10 @@ export class BackgroundResourcesLoader {
} }
internalPreloadCss(name) { internalPreloadCss(name) {
if (this.cssLoaded.includes(name)) {
return;
}
this.cssLoaded.push(name);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const link = document.createElement("link"); const link = document.createElement("link");
@ -225,10 +230,16 @@ export class BackgroundResourcesLoader {
for (let i = 0; i < atlases.length; ++i) { for (let i = 0; i < atlases.length; ++i) {
const atlas = atlases[i]; const atlas = atlases[i];
if (this.atlasesLoaded.includes(atlas)) {
// Already loaded
continue;
}
this.atlasesLoaded.push(atlas);
promises.push( promises.push(
Loader.preloadAtlas(atlas) Loader.preloadAtlas(atlas)
.catch(err => { .catch(err => {
logger.warn("Failed to load atlas:", atlas.sourceFileName); logger.warn("Failed to load atlas:", atlas.sourceFileName, err);
}) })
.then(() => { .then(() => {
this.numAssetsLoaded++; this.numAssetsLoaded++;
@ -236,19 +247,9 @@ export class BackgroundResourcesLoader {
); );
} }
return ( return Promise.all(promises).then(() => {
Promise.all(promises) this.numAssetsToLoadTotal = 0;
this.numAssetsLoaded = 0;
// // Remove some pressure by waiting a bit });
// .then(() => {
// return new Promise(resolve => {
// setTimeout(resolve, 200);
// });
// })
.then(() => {
this.numAssetsToLoadTotal = 0;
this.numAssetsLoaded = 0;
})
);
} }
} }

@ -178,7 +178,7 @@ export class Dialog {
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
button.classList.remove("timedButton"); button.classList.remove("timedButton");
arrayDeleteValue(this.timeouts, timeout); arrayDeleteValue(this.timeouts, timeout);
}, 3000); }, 1000);
this.timeouts.push(timeout); this.timeouts.push(timeout);
} }
if (isEnter || isEscape) { if (isEnter || isEscape) {

@ -32,10 +32,13 @@ export const MUSIC = {
// The theme always depends on the standalone only, even if running the full // The theme always depends on the standalone only, even if running the full
// version in the browser // version in the browser
theme: G_IS_STANDALONE ? "theme-full" : "theme-short", theme: G_IS_STANDALONE ? "theme-full" : "theme-short",
menu: "menu",
}; };
if (G_IS_STANDALONE || G_IS_DEV) { if (G_IS_STANDALONE) {
MUSIC.menu = "menu";
}
if (G_IS_STANDALONE) {
MUSIC.puzzle = "puzzle-full"; MUSIC.puzzle = "puzzle-full";
} }
@ -152,7 +155,7 @@ export class SoundInterface {
} else if (this.music[key]) { } else if (this.music[key]) {
return this.music[key].load(); return this.music[key].load();
} else { } else {
logger.error("Sound/Music by key not found:", key); logger.warn("Sound/Music by key not found:", key);
return Promise.resolve(); return Promise.resolve();
} }
} }

@ -237,17 +237,21 @@ export class InGameState extends GameState {
*/ */
stage3CreateCore() { stage3CreateCore() {
if (this.switchStage(GAME_LOADING_STATES.s3_createCore)) { if (this.switchStage(GAME_LOADING_STATES.s3_createCore)) {
logger.log("Creating new game core"); logger.log("Waiting for resources to load");
this.core = new GameCore(this.app);
this.core.initializeRoot(this, this.savegame, this.gameModeId); this.app.backgroundResourceLoader.getPromiseForBareGame().then(() => {
logger.log("Creating new game core");
this.core = new GameCore(this.app);
if (this.savegame.hasGameDump()) { this.core.initializeRoot(this, this.savegame, this.gameModeId);
this.stage4bResumeGame();
} else { if (this.savegame.hasGameDump()) {
this.app.gameAnalytics.handleGameStarted(); this.stage4bResumeGame();
this.stage4aInitEmptyGame(); } else {
} this.app.gameAnalytics.handleGameStarted();
this.stage4aInitEmptyGame();
}
});
} }
} }

@ -315,6 +315,9 @@ export class MainMenuState extends GameState {
} }
onEnter(payload) { onEnter(payload) {
const app = this.app;
setTimeout(() => app.backgroundResourceLoader.internalStartLoadingEssentialsForBareGame(), 10);
this.dialogs = new HUDModalDialogs(null, this.app); this.dialogs = new HUDModalDialogs(null, this.app);
const dialogsElement = document.body.querySelector(".modalDialogParent"); const dialogsElement = document.body.querySelector(".modalDialogParent");
this.dialogs.initializeToElement(dialogsElement); this.dialogs.initializeToElement(dialogsElement);

@ -163,7 +163,7 @@ export class PreloadState extends GameState {
.then(() => this.setStatus("Downloading resources")) .then(() => this.setStatus("Downloading resources"))
.then(() => { .then(() => {
return this.app.backgroundResourceLoader.getPromiseForBareGame(); return this.app.backgroundResourceLoader.getPromiseForMainMenu();
}) })
.then(() => this.setStatus("Checking changelog")) .then(() => this.setStatus("Checking changelog"))

Loading…
Cancel
Save