Skip to content

Commit

Permalink
Lazy load interactive or static variants of a component individually,…
Browse files Browse the repository at this point in the history
… rather than loading both variants regardless. This change will improve performance for many applications. (#5215)

* lazy load compoennts more granularly

* add changeset

* format

* add changeset

* fix casing

* fix casing

* fix casing

* revert changelog formatting

* add changeset

* revert changelog formatting

* add changeset

* make interactive updates work

* revert changelog stuff

* fix order

* fix static dataframe

* revert demo change

---------

Co-authored-by: gradio-pr-bot <[email protected]>
  • Loading branch information
pngwn and gradio-pr-bot authored Aug 15, 2023
1 parent 3b80534 commit fbdad78
Show file tree
Hide file tree
Showing 120 changed files with 342 additions and 235 deletions.
33 changes: 33 additions & 0 deletions .changeset/forty-cases-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
"@gradio/accordion": patch
"@gradio/annotatedimage": patch
"@gradio/app": patch
"@gradio/audio": patch
"@gradio/box": patch
"@gradio/chatbot": patch
"@gradio/checkbox": patch
"@gradio/checkboxgroup": patch
"@gradio/code": patch
"@gradio/colorpicker": patch
"@gradio/dataframe": patch
"@gradio/dropdown": patch
"@gradio/file": patch
"@gradio/gallery": patch
"@gradio/highlightedtext": patch
"@gradio/html": patch
"@gradio/image": patch
"@gradio/json": patch
"@gradio/label": patch
"@gradio/markdown": patch
"@gradio/model3d": patch
"@gradio/number": patch
"@gradio/plot": patch
"@gradio/radio": patch
"@gradio/slider": patch
"@gradio/statustracker": patch
"@gradio/timeseries": patch
"@gradio/video": patch
"gradio": patch
---

feat:Lazy load interactive or static variants of a component individually, rather than loading both variants regardless. This change will improve performance for many applications.
3 changes: 2 additions & 1 deletion .config/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@
**/storybook-static/**
**/.vscode/**
sweep.yaml
**/.vercel/**
**/.vercel/**
**/build/**
2 changes: 1 addition & 1 deletion js/accordion/static/StaticAccordion.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import Accordion from "./Accordion.svelte";
import { Block } from "@gradio/atoms";
import { StatusTracker } from "@gradio/statustracker";
import type { LoadingStatus } from "@gradio/statustracker/types";
import type { LoadingStatus } from "@gradio/statustracker";
import Column from "@gradio/column";
Expand Down
2 changes: 1 addition & 1 deletion js/annotatedimage/static/AnnotatedImage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { Block, BlockLabel, Empty } from "@gradio/atoms";
import { Image } from "@gradio/icons";
import { StatusTracker } from "@gradio/statustracker";
import type { LoadingStatus } from "@gradio/statustracker/types";
import type { LoadingStatus } from "@gradio/statustracker";
import { type FileData, normalise_file } from "@gradio/upload";
import type { SelectData } from "@gradio/utils";
Expand Down
99 changes: 77 additions & 22 deletions js/app/src/Blocks.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
let rootNode: ComponentMeta = {
id: layout.id,
type: "column",
props: {},
props: { mode: "static" },
has_modes: false,
instance: {} as ComponentMeta["instance"],
component: {} as ComponentMeta["component"]
Expand Down Expand Up @@ -134,59 +134,82 @@
);
type LoadedComponent = {
Component: ComponentMeta["component"];
modes?: string[];
document?: (arg0: Record<string, unknown>) => Documentation;
default: ComponentMeta["component"];
};
async function load_component<T extends ComponentMeta["type"]>(
name: T
name: T,
mode: ComponentMeta["props"]["mode"]
): Promise<{
name: T;
component: LoadedComponent;
}> {
try {
const c = await component_map[name]();
//@ts-ignore
const c = await component_map[name][mode]();
return {
name,
component: c as LoadedComponent
};
} catch (e) {
console.error(`failed to load: ${name}`);
console.error(e);
throw e;
if (mode === "interactive") {
try {
const c = await component_map[name]["static"]();
return {
name,
component: c as LoadedComponent
};
} catch (e) {
console.error(`failed to load: ${name}`);
console.error(e);
throw e;
}
} else {
console.error(`failed to load: ${name}`);
console.error(e);
throw e;
}
}
}
const component_set = new Set<
Promise<{ name: ComponentMeta["type"]; component: LoadedComponent }>
>();
const _component_map = new Map<
ComponentMeta["type"],
`${ComponentMeta["type"]}_${ComponentMeta["props"]["mode"]}`,
Promise<{ name: ComponentMeta["type"]; component: LoadedComponent }>
>();
const _type_for_id = new Map<number, ComponentMeta["props"]["mode"]>();
async function walk_layout(node: LayoutNode): Promise<void> {
let instance = instance_map[node.id];
const _component = (await _component_map.get(instance.type))!.component;
instance.component = _component.Component;
if (_component.document) {
instance.documentation = _component.document(instance.props);
}
if (_component.modes && _component.modes.length > 1) {
instance.has_modes = true;
}
const _component = (await _component_map.get(
`${instance.type}_${_type_for_id.get(node.id) || "static"}`
))!.component;
instance.component = _component.default;
if (node.children) {
instance.children = node.children.map((v) => instance_map[v.id]);
await Promise.all(node.children.map((v) => walk_layout(v)));
}
}
components.forEach(async (c) => {
const _c = load_component(c.type);
components.forEach((c) => {
if ((c.props as any).interactive === false) {
(c.props as any).mode = "static";
} else if ((c.props as any).interactive === true) {
(c.props as any).mode = "interactive";
} else if (dynamic_ids.has(c.id)) {
(c.props as any).mode = "interactive";
} else {
(c.props as any).mode = "static";
}
_type_for_id.set(c.id, c.props.mode);
const _c = load_component(c.type, c.props.mode);
component_set.add(_c);
_component_map.set(c.type, _c);
_component_map.set(`${c.type}_${c.props.mode}`, _c);
});
export let ready = false;
Expand All @@ -200,6 +223,32 @@
});
});
async function update_interactive_mode(
instance: ComponentMeta,
mode: "dynamic" | "interactive" | "static"
): Promise<void> {
let new_mode: "interactive" | "static" =
mode === "dynamic" ? "interactive" : mode;
if (instance.props.mode === new_mode) return;
instance.props.mode = new_mode;
const _c = load_component(instance.type, instance.props.mode);
component_set.add(_c);
_component_map.set(
`${instance.type}_${instance.props.mode}`,
_c as Promise<{
name: ComponentMeta["type"];
component: LoadedComponent;
}>
);
_c.then((c) => {
instance.component = c.component.default;
rootNode = rootNode;
});
}
function handle_update(data: any, fn_index: number): void {
const outputs = dependencies[fn_index].outputs;
data?.forEach((value: any, i: number) => {
Expand All @@ -214,6 +263,12 @@
if (update_key === "__type__") {
continue;
} else {
if (update_key === "mode") {
update_interactive_mode(
output,
update_value as "dynamic" | "static"
);
}
output.props[update_key] = update_value;
}
}
Expand All @@ -232,6 +287,7 @@
val: any
): void {
if (!obj?.props) {
// @ts-ignore
obj.props = {};
}
obj.props[prop] = val;
Expand Down Expand Up @@ -570,7 +626,6 @@
<div class="contain" style:flex-grow={app_mode ? "1" : "auto"}>
{#if ready}
<Render
has_modes={rootNode.has_modes}
component={rootNode.component}
id={rootNode.id}
props={rootNode.props}
Expand Down
2 changes: 1 addition & 1 deletion js/app/src/Login.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import Form from "@gradio/form";
import Textbox from "@gradio/textbox";
import { BaseButton } from "@gradio/button/static";
import { Component as Column } from "./components/Column";
import Column from "@gradio/column";
export let root: string;
export let auth_message: string | null;
export let app_mode: boolean;
Expand Down
13 changes: 0 additions & 13 deletions js/app/src/Render.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,12 @@
export let children: ComponentMeta["children"];
export let dynamic_ids: Set<number>;
export let has_modes: boolean | undefined;
export let parent: string | null = null;
export let target: HTMLElement;
export let theme_mode: ThemeMode;
const dispatch = createEventDispatcher<{ mount: number; destroy: number }>();
if (has_modes) {
if ((props as any).interactive === false) {
(props as any).mode = "static";
} else if ((props as any).interactive === true) {
(props as any).mode = "dynamic";
} else if (dynamic_ids.has(id)) {
(props as any).mode = "dynamic";
} else {
(props as any).mode = "static";
}
}
onMount(() => {
dispatch("mount", id);
Expand Down
2 changes: 0 additions & 2 deletions js/app/src/components/Accordion/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/AnnotatedImage/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Audio/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Box/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Button/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Chatbot/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Checkbox/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/CheckboxGroup/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Code/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/ColorPicker/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Column/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/DataFrame/index.ts

This file was deleted.

3 changes: 1 addition & 2 deletions js/app/src/components/Dataset/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { default as Component } from "./Dataset.svelte";
export const modes = ["dynamic"];
export { default } from "./Dataset.svelte";
2 changes: 0 additions & 2 deletions js/app/src/components/Dropdown/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/File/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Form/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Gallery/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Group/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/HTML/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/HighlightedText/index.ts

This file was deleted.

3 changes: 0 additions & 3 deletions js/app/src/components/Image/index.ts

This file was deleted.

3 changes: 1 addition & 2 deletions js/app/src/components/Interpretation/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { default as Component } from "./Interpretation.svelte";
export const modes = ["dynamic"];
export { default } from "./Interpretation.svelte";
2 changes: 0 additions & 2 deletions js/app/src/components/Json/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Label/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Markdown/index.ts

This file was deleted.

3 changes: 0 additions & 3 deletions js/app/src/components/Model3D/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Number/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Plot/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Radio/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Row/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Slider/index.ts

This file was deleted.

3 changes: 1 addition & 2 deletions js/app/src/components/State/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { default as Component } from "@gradio/state";
export const modes = ["static"];
export { default } from "@gradio/state";
2 changes: 0 additions & 2 deletions js/app/src/components/StatusTracker/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/TabItem/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Tabs/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Textbox/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/TimeSeries/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/UploadButton/index.ts

This file was deleted.

2 changes: 0 additions & 2 deletions js/app/src/components/Video/index.ts

This file was deleted.

Loading

0 comments on commit fbdad78

Please sign in to comment.