feat: eager app mode

This commit is contained in:
Ruben Fiszel
2025-03-19 17:02:32 +01:00
parent 08d7567d42
commit e00cb430b0
5 changed files with 89 additions and 35 deletions
@@ -1,11 +1,13 @@
<script lang="ts">
import { getContext } from 'svelte'
import { getContext, onDestroy } from 'svelte'
import { initConfig, initOutput } from '../../editor/appUtils'
import type {
AppViewerContext,
ComponentCustomCSS,
VerticalAlignment,
RichConfigurations
RichConfigurations,
ListContext,
ListInputs
} from '../../types'
import { initCss } from '../../utils'
import AlignWrapper from '../helpers/AlignWrapper.svelte'
@@ -27,24 +29,36 @@
const { app, worldStore, componentControl, selectedComponent } =
getContext<AppViewerContext>('AppViewerContext')
const iterContext = getContext<ListContext>('ListWrapperContext')
const listInputs: ListInputs | undefined = getContext<ListInputs>('ListInputs')
let resolvedConfig = initConfig(
components['datetimeinputcomponent'].initialData.configuration,
configuration
)
let value: string | undefined = undefined
$componentControl[id] = {
setValue(nvalue: string) {
value = nvalue
}
}
let outputs = initOutput($worldStore, id, {
result: undefined as string | undefined,
validity: true as boolean | undefined
})
let initValue = outputs?.result.peak()
let value: string | undefined =
!iterContext && initValue != undefined ? initValue : resolvedConfig.defaultValue
$componentControl[id] = {
setValue(nvalue: string) {
value = nvalue
outputs?.result.set(value)
}
}
onDestroy(() => {
listInputs?.remove(id)
})
let initialHandleDefault = true
$: handleDefault(resolvedConfig.defaultValue)
function formatDate(dateString: string, formatString: string = 'dd.MM.yyyy HH:mm') {
@@ -62,7 +76,8 @@
$: {
if (value) {
outputs?.result.set(formatDate(value, resolvedConfig.outputFormat))
const r = formatDate(value, resolvedConfig.outputFormat)
outputs?.result.set(r)
const valueDate = new Date(value)
if (resolvedConfig.minDateTime) {
@@ -95,12 +110,24 @@
outputs?.validity.set(false)
}
}
if (iterContext && listInputs) {
listInputs.set(id, value)
}
} else {
outputs?.result.set(undefined)
if (iterContext && listInputs) {
listInputs.set(id, undefined)
}
}
}
function handleDefault(defaultValue: string | undefined) {
if (initialHandleDefault) {
initialHandleDefault = false
if (value != undefined) {
return
}
}
value = defaultValue
}
@@ -40,7 +40,7 @@
// initialized?.length ==
// allItems(app.grid, app.subgrids).length + (app.hiddenInlineScripts?.length ?? 0)
// )
if (app.lazyInitRequire == undefined) {
if (app.eagerRendering || app.lazyInitRequire == undefined) {
return (
initialized?.length ==
allItems(app.grid, app.subgrids).length + (app.hiddenInlineScripts?.length ?? 0)
@@ -177,7 +177,7 @@
}
</script>
{#if everVisible}
{#if everVisible || $app.eagerRendering}
<div
class="translate-x-0 translate-y-0 w-full subgrid {visible
? 'visible'
@@ -3,12 +3,19 @@
import type { AppViewerContext } from '../../types'
import Alert from '$lib/components/common/alert/Alert.svelte'
import Toggle from '$lib/components/Toggle.svelte'
import JsonEditor from '$lib/components/JsonEditor.svelte'
import Section from '$lib/components/Section.svelte'
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
const { app } = getContext<AppViewerContext>('AppViewerContext')
let code = JSON.stringify($app.lazyInitRequire)
let selectedRendering = $app.eagerRendering
? 'eager'
: $app.lazyInitRequire
? 'lazy'
: 'semi-lazy'
</script>
<div class="flex flex-col gap-8" style="all:none;">
@@ -19,32 +26,51 @@
When lazy mode is enabled, components are not rendered until they are needed. This can significantly
improve the performance of your app, especially on mobile devices.
<br />
You can enable lazy mode below, but you will need to declare the list of components whose initialization
is expected to see initialized before the initial refresh of the app happens.
Semi-Lazy mode is enabled by default, where components are initialized but are in a hidden state.
Lazy mode is when components are not initialized at all.
</Alert>
<Toggle
label="Lazy mode"
checked={Boolean($app.lazyInitRequire != undefined)}
on:change={(e) => {
$app.lazyInitRequire = e.detail ? [] : undefined
code = JSON.stringify($app.lazyInitRequire)
<ToggleButtonGroup
label="Rendering"
bind:selected={selectedRendering}
on:selected={(e) => {
if (e.detail == 'eager') {
$app.eagerRendering = true
$app.lazyInitRequire = undefined
} else if (e.detail == 'semi-lazy') {
$app.eagerRendering = undefined
$app.lazyInitRequire = undefined
} else {
$app.eagerRendering = undefined
$app.lazyInitRequire = []
code = JSON.stringify($app.lazyInitRequire)
}
}}
options={{
right: 'Lazy mode'
}}
/>
<Section label="Component ids to wait the initialization of before the initial refresh">
{#if $app.lazyInitRequire != undefined}
let:item
>
<ToggleButton value="eager" label="Eager" {item} />
<ToggleButton value="semi-lazy" label="Semi-Lazy" {item} />
<ToggleButton value="lazy" label="Lazy" {item} />
</ToggleButtonGroup>
{#if selectedRendering == 'eager'}
<Section label="Eager mode">
<span class="text-tertiary"
>In eager mode, all components will be fully initialized, even when they are not visible.</span
>
</Section>
{:else if selectedRendering == 'semi-lazy'}
<Section label="Semi-Lazy mode">
<span class="text-tertiary"
>In semi-lazy mode, components will be semi-initialized when hidden. That is the default
mode.</span
>
</Section>
{:else if selectedRendering == 'lazy'}
<Section label="Component ids to wait the initialization of before the initial refresh">
<JsonEditor bind:value={$app.lazyInitRequire} {code} />
<span class="text-tertiary text-xs">
{'e.g: ["a", "b"]'}, no need to put background runnables ids
</span>
{:else}
<span class="text-tertiary"
>Without lazy mode, all components' initialization will be waited on the initial refresh.</span
>
{/if}
</Section>
</Section>
{/if}
</div>
@@ -165,6 +165,7 @@ export type App = {
subgrids?: Record<string, GridItem[]>
theme: AppTheme | undefined
lazyInitRequire?: string[] | undefined
eagerRendering?: boolean | undefined
hideLegacyTopBar?: boolean | undefined
mobileViewOnSmallerScreens?: boolean | undefined
version?: number