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 {
hasHold?: 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 { 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<RecorderInfo>({
export const getRecorderInfo = (conn: Connection) =>
conn.sendMessagePromise<RecorderInfo>({
type: "recorder/info",
});

View File

@ -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);
}
});

View File

@ -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<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 =
info.migration_in_progress && !info.migration_is_live;
if (this._databaseMigration) {

View File

@ -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<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
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!);
}