Speed up first load by preloading recorder info (#18412)

This commit is contained in:
J. Nick Koston 2023-10-25 14:29:44 -05:00 committed by GitHub
parent e16a101de8
commit c3743b57ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 24 deletions

View File

@ -348,11 +348,6 @@ export const getLegacyLovelaceCollection = (conn: Connection) =>
) )
); );
export interface WindowWithLovelaceProm extends Window {
llConfProm?: Promise<LovelaceConfig>;
llResProm?: Promise<LovelaceResource[]>;
}
export interface ActionHandlerOptions { export interface ActionHandlerOptions {
hasHold?: boolean; hasHold?: boolean;
hasDoubleClick?: boolean; hasDoubleClick?: boolean;

8
src/data/preloads.ts Normal file
View File

@ -0,0 +1,8 @@
import { LovelaceConfig, LovelaceResource } from "./lovelace";
import { RecorderInfo } from "./recorder";
export interface WindowWithPreloads extends Window {
llConfProm?: Promise<LovelaceConfig>;
llResProm?: Promise<LovelaceResource[]>;
recorderInfoProm?: Promise<RecorderInfo>;
}

View File

@ -1,3 +1,4 @@
import { Connection } from "home-assistant-js-websocket";
import { computeStateName } from "../common/entity/compute_state_name"; import { computeStateName } from "../common/entity/compute_state_name";
import { HaDurationData } from "../components/ha-duration-input"; import { HaDurationData } from "../components/ha-duration-input";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
@ -115,8 +116,8 @@ export interface StatisticsValidationResults {
[statisticId: string]: StatisticsValidationResult[]; [statisticId: string]: StatisticsValidationResult[];
} }
export const getRecorderInfo = (hass: HomeAssistant) => export const getRecorderInfo = (conn: Connection) =>
hass.callWS<RecorderInfo>({ conn.sendMessagePromise<RecorderInfo>({
type: "recorder/info", type: "recorder/info",
}); });

View File

@ -13,12 +13,9 @@ import {
import { loadTokens, saveTokens } from "../common/auth/token_storage"; import { loadTokens, saveTokens } from "../common/auth/token_storage";
import { hassUrl } from "../data/auth"; import { hassUrl } from "../data/auth";
import { isExternal } from "../data/external"; import { isExternal } from "../data/external";
import { getRecorderInfo } from "../data/recorder";
import { subscribeFrontendUserData } from "../data/frontend"; import { subscribeFrontendUserData } from "../data/frontend";
import { import { fetchConfig, fetchResources } from "../data/lovelace";
fetchConfig,
fetchResources,
WindowWithLovelaceProm,
} from "../data/lovelace";
import { subscribePanels } from "../data/ws-panels"; import { subscribePanels } from "../data/ws-panels";
import { subscribeThemes } from "../data/ws-themes"; import { subscribeThemes } from "../data/ws-themes";
import { subscribeRepairsIssueRegistry } from "../data/repairs"; import { subscribeRepairsIssueRegistry } from "../data/repairs";
@ -27,6 +24,7 @@ import type { ExternalAuth } from "../external_app/external_auth";
import "../resources/array.flat.polyfill"; import "../resources/array.flat.polyfill";
import "../resources/safari-14-attachshadow-patch"; import "../resources/safari-14-attachshadow-patch";
import { MAIN_WINDOW_NAME } from "../data/main_window"; import { MAIN_WINDOW_NAME } from "../data/main_window";
import { WindowWithPreloads } from "../data/preloads";
window.name = MAIN_WINDOW_NAME; window.name = MAIN_WINDOW_NAME;
(window as any).frontendVersion = __VERSION__; (window as any).frontendVersion = __VERSION__;
@ -124,12 +122,14 @@ window.hassConnection.then(({ conn }) => {
subscribeFrontendUserData(conn, "core", noop); subscribeFrontendUserData(conn, "core", noop);
subscribeRepairsIssueRegistry(conn, noop); subscribeRepairsIssueRegistry(conn, noop);
const preloadWindow = window as WindowWithPreloads;
preloadWindow.recorderInfoProm = getRecorderInfo(conn);
if (location.pathname === "/" || location.pathname.startsWith("/lovelace/")) { if (location.pathname === "/" || location.pathname.startsWith("/lovelace/")) {
const llWindow = window as WindowWithLovelaceProm; preloadWindow.llConfProm = fetchConfig(conn, null, false);
llWindow.llConfProm = fetchConfig(conn, null, false); preloadWindow.llConfProm.catch(() => {
llWindow.llConfProm.catch(() => {
// Ignore it, it is handled by Lovelace panel. // Ignore it, it is handled by Lovelace panel.
}); });
llWindow.llResProm = fetchResources(conn); preloadWindow.llResProm = fetchResources(conn);
} }
}); });

View File

@ -3,11 +3,12 @@ import { customElement, state } from "lit/decorators";
import { isNavigationClick } from "../common/dom/is-navigation-click"; import { isNavigationClick } from "../common/dom/is-navigation-click";
import { navigate } from "../common/navigate"; import { navigate } from "../common/navigate";
import { getStorageDefaultPanelUrlPath } from "../data/panel"; import { getStorageDefaultPanelUrlPath } from "../data/panel";
import { getRecorderInfo } from "../data/recorder"; import { getRecorderInfo, RecorderInfo } from "../data/recorder";
import "../resources/custom-card-support"; import "../resources/custom-card-support";
import { HassElement } from "../state/hass-element"; import { HassElement } from "../state/hass-element";
import QuickBarMixin from "../state/quick-bar-mixin"; import QuickBarMixin from "../state/quick-bar-mixin";
import { HomeAssistant, Route } from "../types"; import { HomeAssistant, Route } from "../types";
import { WindowWithPreloads } from "../data/preloads";
import { storeState } from "../util/ha-pref-storage"; import { storeState } from "../util/ha-pref-storage";
import { import {
renderLaunchScreenInfoBox, renderLaunchScreenInfoBox,
@ -204,7 +205,15 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
protected async checkDataBaseMigration() { protected async checkDataBaseMigration() {
if (this.hass?.config?.components.includes("recorder")) { if (this.hass?.config?.components.includes("recorder")) {
const info = await getRecorderInfo(this.hass); let recorderInfoProm: Promise<RecorderInfo> | 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 = this._databaseMigration =
info.migration_in_progress && !info.migration_is_live; info.migration_in_progress && !info.migration_is_live;
if (this._databaseMigration) { if (this._databaseMigration) {

View File

@ -15,8 +15,8 @@ import {
LovelaceConfig, LovelaceConfig,
saveConfig, saveConfig,
subscribeLovelaceUpdates, subscribeLovelaceUpdates,
WindowWithLovelaceProm,
} from "../../data/lovelace"; } from "../../data/lovelace";
import { WindowWithPreloads } from "../../data/preloads";
import "../../layouts/hass-error-screen"; import "../../layouts/hass-error-screen";
import "../../layouts/hass-loading-screen"; import "../../layouts/hass-loading-screen";
import { HomeAssistant, PanelInfo, Route } from "../../types"; import { HomeAssistant, PanelInfo, Route } from "../../types";
@ -220,16 +220,16 @@ export class LovelacePanel extends LitElement {
let rawConf: LovelaceConfig | undefined; let rawConf: LovelaceConfig | undefined;
let confMode: Lovelace["mode"] = this.panel!.config.mode; let confMode: Lovelace["mode"] = this.panel!.config.mode;
let confProm: Promise<LovelaceConfig> | undefined; let confProm: Promise<LovelaceConfig> | undefined;
const llWindow = window as WindowWithLovelaceProm; const preloadWindow = window as WindowWithPreloads;
// On first load, we speed up loading page by having LL promise ready // On first load, we speed up loading page by having LL promise ready
if (llWindow.llConfProm) { if (preloadWindow.llConfProm) {
confProm = llWindow.llConfProm; confProm = preloadWindow.llConfProm;
llWindow.llConfProm = undefined; preloadWindow.llConfProm = undefined;
} }
if (!resourcesLoaded) { if (!resourcesLoaded) {
resourcesLoaded = true; resourcesLoaded = true;
const resources = await (llWindow.llResProm || const resources = await (preloadWindow.llResProm ||
fetchResources(this.hass!.connection)); fetchResources(this.hass!.connection));
loadLovelaceResources(resources, this.hass!); loadLovelaceResources(resources, this.hass!);
} }