From c3743b57eabbbde3e7a9f73da48e86f6d99ea358 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 25 Oct 2023 14:29:44 -0500 Subject: [PATCH] Speed up first load by preloading recorder info (#18412) --- src/data/lovelace.ts | 5 ----- src/data/preloads.ts | 8 ++++++++ src/data/recorder.ts | 5 +++-- src/entrypoints/core.ts | 18 +++++++++--------- src/layouts/home-assistant.ts | 13 +++++++++++-- src/panels/lovelace/ha-panel-lovelace.ts | 12 ++++++------ 6 files changed, 37 insertions(+), 24 deletions(-) create mode 100644 src/data/preloads.ts diff --git a/src/data/lovelace.ts b/src/data/lovelace.ts index b8d13b2004..87279bc2b0 100644 --- a/src/data/lovelace.ts +++ b/src/data/lovelace.ts @@ -348,11 +348,6 @@ export const getLegacyLovelaceCollection = (conn: Connection) => ) ); -export interface WindowWithLovelaceProm extends Window { - llConfProm?: Promise; - llResProm?: Promise; -} - export interface ActionHandlerOptions { hasHold?: boolean; hasDoubleClick?: boolean; diff --git a/src/data/preloads.ts b/src/data/preloads.ts new file mode 100644 index 0000000000..ab2c472813 --- /dev/null +++ b/src/data/preloads.ts @@ -0,0 +1,8 @@ +import { LovelaceConfig, LovelaceResource } from "./lovelace"; +import { RecorderInfo } from "./recorder"; + +export interface WindowWithPreloads extends Window { + llConfProm?: Promise; + llResProm?: Promise; + recorderInfoProm?: Promise; +} diff --git a/src/data/recorder.ts b/src/data/recorder.ts index 32b471f4a7..23b63a6d1c 100644 --- a/src/data/recorder.ts +++ b/src/data/recorder.ts @@ -1,3 +1,4 @@ +import { Connection } from "home-assistant-js-websocket"; import { computeStateName } from "../common/entity/compute_state_name"; import { HaDurationData } from "../components/ha-duration-input"; import { HomeAssistant } from "../types"; @@ -115,8 +116,8 @@ export interface StatisticsValidationResults { [statisticId: string]: StatisticsValidationResult[]; } -export const getRecorderInfo = (hass: HomeAssistant) => - hass.callWS({ +export const getRecorderInfo = (conn: Connection) => + conn.sendMessagePromise({ type: "recorder/info", }); diff --git a/src/entrypoints/core.ts b/src/entrypoints/core.ts index 5353a14243..a5083b2b2a 100644 --- a/src/entrypoints/core.ts +++ b/src/entrypoints/core.ts @@ -13,12 +13,9 @@ import { import { loadTokens, saveTokens } from "../common/auth/token_storage"; import { hassUrl } from "../data/auth"; import { isExternal } from "../data/external"; +import { getRecorderInfo } from "../data/recorder"; import { subscribeFrontendUserData } from "../data/frontend"; -import { - fetchConfig, - fetchResources, - WindowWithLovelaceProm, -} from "../data/lovelace"; +import { fetchConfig, fetchResources } from "../data/lovelace"; import { subscribePanels } from "../data/ws-panels"; import { subscribeThemes } from "../data/ws-themes"; import { subscribeRepairsIssueRegistry } from "../data/repairs"; @@ -27,6 +24,7 @@ import type { ExternalAuth } from "../external_app/external_auth"; import "../resources/array.flat.polyfill"; import "../resources/safari-14-attachshadow-patch"; import { MAIN_WINDOW_NAME } from "../data/main_window"; +import { WindowWithPreloads } from "../data/preloads"; window.name = MAIN_WINDOW_NAME; (window as any).frontendVersion = __VERSION__; @@ -124,12 +122,14 @@ window.hassConnection.then(({ conn }) => { subscribeFrontendUserData(conn, "core", noop); subscribeRepairsIssueRegistry(conn, noop); + const preloadWindow = window as WindowWithPreloads; + preloadWindow.recorderInfoProm = getRecorderInfo(conn); + if (location.pathname === "/" || location.pathname.startsWith("/lovelace/")) { - const llWindow = window as WindowWithLovelaceProm; - llWindow.llConfProm = fetchConfig(conn, null, false); - llWindow.llConfProm.catch(() => { + preloadWindow.llConfProm = fetchConfig(conn, null, false); + preloadWindow.llConfProm.catch(() => { // Ignore it, it is handled by Lovelace panel. }); - llWindow.llResProm = fetchResources(conn); + preloadWindow.llResProm = fetchResources(conn); } }); diff --git a/src/layouts/home-assistant.ts b/src/layouts/home-assistant.ts index ba9f321c79..f9781eef5d 100644 --- a/src/layouts/home-assistant.ts +++ b/src/layouts/home-assistant.ts @@ -3,11 +3,12 @@ import { customElement, state } from "lit/decorators"; import { isNavigationClick } from "../common/dom/is-navigation-click"; import { navigate } from "../common/navigate"; import { getStorageDefaultPanelUrlPath } from "../data/panel"; -import { getRecorderInfo } from "../data/recorder"; +import { getRecorderInfo, RecorderInfo } from "../data/recorder"; import "../resources/custom-card-support"; import { HassElement } from "../state/hass-element"; import QuickBarMixin from "../state/quick-bar-mixin"; import { HomeAssistant, Route } from "../types"; +import { WindowWithPreloads } from "../data/preloads"; import { storeState } from "../util/ha-pref-storage"; import { renderLaunchScreenInfoBox, @@ -204,7 +205,15 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) { protected async checkDataBaseMigration() { if (this.hass?.config?.components.includes("recorder")) { - const info = await getRecorderInfo(this.hass); + let recorderInfoProm: Promise | undefined; + const preloadWindow = window as WindowWithPreloads; + // On first load, we speed up loading page by having recorderInfoProm ready + if (preloadWindow.recorderInfoProm) { + recorderInfoProm = preloadWindow.recorderInfoProm; + preloadWindow.recorderInfoProm = undefined; + } + const info = await (recorderInfoProm || + getRecorderInfo(this.hass.connection)); this._databaseMigration = info.migration_in_progress && !info.migration_is_live; if (this._databaseMigration) { diff --git a/src/panels/lovelace/ha-panel-lovelace.ts b/src/panels/lovelace/ha-panel-lovelace.ts index 9fd8da1d9d..ae6bc209ed 100644 --- a/src/panels/lovelace/ha-panel-lovelace.ts +++ b/src/panels/lovelace/ha-panel-lovelace.ts @@ -15,8 +15,8 @@ import { LovelaceConfig, saveConfig, subscribeLovelaceUpdates, - WindowWithLovelaceProm, } from "../../data/lovelace"; +import { WindowWithPreloads } from "../../data/preloads"; import "../../layouts/hass-error-screen"; import "../../layouts/hass-loading-screen"; import { HomeAssistant, PanelInfo, Route } from "../../types"; @@ -220,16 +220,16 @@ export class LovelacePanel extends LitElement { let rawConf: LovelaceConfig | undefined; let confMode: Lovelace["mode"] = this.panel!.config.mode; let confProm: Promise | undefined; - const llWindow = window as WindowWithLovelaceProm; + const preloadWindow = window as WindowWithPreloads; // On first load, we speed up loading page by having LL promise ready - if (llWindow.llConfProm) { - confProm = llWindow.llConfProm; - llWindow.llConfProm = undefined; + if (preloadWindow.llConfProm) { + confProm = preloadWindow.llConfProm; + preloadWindow.llConfProm = undefined; } if (!resourcesLoaded) { resourcesLoaded = true; - const resources = await (llWindow.llResProm || + const resources = await (preloadWindow.llResProm || fetchResources(this.hass!.connection)); loadLovelaceResources(resources, this.hass!); }