Performance improvements

This commit is contained in:
Andrew Kingston 2024-08-10 18:52:24 +01:00
parent 34448cfca2
commit 533a597a0b
No known key found for this signature in database
6 changed files with 59 additions and 59 deletions

View File

@ -40,6 +40,7 @@
getActionDependentContextKeys, getActionDependentContextKeys,
} from "../utils/buttonActions.js" } from "../utils/buttonActions.js"
import { gridLayout } from "utils/grid.js" import { gridLayout } from "utils/grid.js"
import { memo } from "@budibase/frontend-core"
export let instance = {} export let instance = {}
export let parent = null export let parent = null
@ -53,7 +54,7 @@
const component = getContext("component") const component = getContext("component")
// Create component context // Create component context
const store = writable({}) const store = memo({})
setContext("component", store) setContext("component", store)
// Ref to the svelte component // Ref to the svelte component
@ -206,7 +207,8 @@
} }
// Metadata to pass into grid action to apply CSS // Metadata to pass into grid action to apply CSS
$: gridMetadata = { let gridMetadata = memo()
$: gridMetadata.set({
active: active:
parent?._component.endsWith("/container") && parent?.layout === "grid", parent?._component.endsWith("/container") && parent?.layout === "grid",
id, id,
@ -215,7 +217,7 @@
draggable, draggable,
definition, definition,
errored: errorState, errored: errorState,
} })
// Update component context // Update component context
$: store.set({ $: store.set({
@ -668,7 +670,7 @@
data-name={name} data-name={name}
data-icon={icon} data-icon={icon}
data-parent={$component.id} data-parent={$component.id}
use:gridLayout={gridMetadata} use:gridLayout={$gridMetadata}
> >
{#if errorState} {#if errorState}
<ComponentErrorState <ComponentErrorState

View File

@ -2,6 +2,7 @@
import { getContext, onMount } from "svelte" import { getContext, onMount } from "svelte"
import { writable } from "svelte/store" import { writable } from "svelte/store"
import { GridRowHeight, GridColumns } from "constants" import { GridRowHeight, GridColumns } from "constants"
import { memo } from "@budibase/frontend-core"
const component = getContext("component") const component = getContext("component")
const { styleable, builderStore } = getContext("sdk") const { styleable, builderStore } = getContext("sdk")
@ -12,12 +13,25 @@
let rows = 1 let rows = 1
let children = writable({}) let children = writable({})
let mounted = false let mounted = false
let styles = memo({})
$: rows = calculateRequiredRows($children, mobile) $: rows = calculateRequiredRows($children, mobile)
$: mobile = $context.device.mobile $: mobile = $context.device.mobile
$: empty = $component.empty $: empty = $component.empty
$: colSize = width / GridColumns $: colSize = width / GridColumns
$: height = rows * GridRowHeight $: height = rows * GridRowHeight
$: styles.set({
...$component.styles,
normal: {
...$component.styles?.normal,
"--height": `${height}px`,
"--cols": GridColumns,
"--rows": rows,
"--col-size": colSize,
"--row-size": GridRowHeight,
},
empty: false,
})
// Calculates the minimum number of rows required to render all child // Calculates the minimum number of rows required to render all child
// components, on a certain device type // components, on a certain device type
@ -104,18 +118,7 @@
class="grid" class="grid"
class:mobile class:mobile
bind:clientWidth={width} bind:clientWidth={width}
use:styleable={{ use:styleable={$styles}
...$component.styles,
normal: {
...$component.styles?.normal,
"--height": `${height}px`,
"--cols": GridColumns,
"--rows": rows,
"--col-size": colSize,
"--row-size": GridRowHeight,
},
empty: false,
}}
data-cols={GridColumns} data-cols={GridColumns}
data-col-size={colSize} data-col-size={colSize}
> >
@ -134,9 +137,6 @@
</div> </div>
<style> <style>
.grid {
position: relative;
}
.grid, .grid,
.underlay { .underlay {
height: var(--height) !important; height: var(--height) !important;

View File

@ -20,7 +20,6 @@
let dragInfo let dragInfo
let styles = memo() let styles = memo()
let gridStyles = memo()
// Grid CSS variables // Grid CSS variables
$: device = $context.device.mobile ? Devices.Mobile : Devices.Desktop $: device = $context.device.mobile ? Devices.Mobile : Devices.Desktop
@ -33,13 +32,11 @@
// Some memoisation of primitive types for performance // Some memoisation of primitive types for performance
$: id = dragInfo?.id $: id = dragInfo?.id
$: gridId = dragInfo?.gridId
// Set ephemeral styles // Set ephemeral styles
$: instance = componentStore.actions.getComponentInstance(id) $: instance = componentStore.actions.getComponentInstance(id)
$: gridInstance = componentStore.actions.getComponentInstance(gridId)
$: $instance?.setEphemeralStyles(enrichComponentStyles($styles)) $: $instance?.setEphemeralStyles(enrichComponentStyles($styles))
$: $gridInstance?.setEphemeralStyles($gridStyles) $: $styles, console.log("new styles")
// Sugar for a combination of both min and max // Sugar for a combination of both min and max
const minMax = (value, min, max) => Math.min(max, Math.max(min, value)) const minMax = (value, min, max) => Math.min(max, Math.max(min, value))
@ -188,7 +185,7 @@
if (!dragInfo) { if (!dragInfo) {
return return
} }
const { id, gridId, domTarget, domGrid, domComponent } = dragInfo const { id, domTarget, domGrid, domComponent } = dragInfo
// Reset DOM // Reset DOM
domComponent.parentNode.classList.remove("dragging") domComponent.parentNode.classList.remove("dragging")
@ -199,14 +196,10 @@
if ($styles) { if ($styles) {
await builderStore.actions.updateStyles($styles, id) await builderStore.actions.updateStyles($styles, id)
} }
if ($gridStyles) {
await builderStore.actions.updateStyles($gridStyles, gridId)
}
// Reset state // Reset state
dragInfo = null dragInfo = null
styles.set(null) styles.set(null)
gridStyles.set(null)
} }
onMount(() => { onMount(() => {

View File

@ -7,9 +7,7 @@
export let icon export let icon
export let title export let title
export let componentId export let componentId
export let computedStyles export let active
$: active = computedStyles?.getPropertyValue(style) === value
</script> </script>
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->

View File

@ -1,14 +1,14 @@
<script> <script>
import { onMount, onDestroy } from "svelte" import { onMount, onDestroy, getContext } from "svelte"
import SettingsButton from "./SettingsButton.svelte" import SettingsButton from "./SettingsButton.svelte"
import GridStylesButton from "./GridStylesButton.svelte" import GridStylesButton from "./GridStylesButton.svelte"
import SettingsColorPicker from "./SettingsColorPicker.svelte" import SettingsColorPicker from "./SettingsColorPicker.svelte"
import SettingsPicker from "./SettingsPicker.svelte" import SettingsPicker from "./SettingsPicker.svelte"
import { builderStore, componentStore, dndIsDragging } from "stores" import { builderStore, componentStore, dndIsDragging } from "stores"
import { Utils, shouldDisplaySetting } from "@budibase/frontend-core" import { Utils, shouldDisplaySetting } from "@budibase/frontend-core"
import { findComponentParent } from "utils/components" import { getGridVar, GridParams, Devices } from "utils/grid"
import { getGridVar, GridParams } from "utils/grid"
const context = getContext("context")
const verticalOffset = 36 const verticalOffset = 36
const horizontalOffset = 2 const horizontalOffset = 2
@ -18,7 +18,10 @@
let self let self
let measured = false let measured = false
let observer let observer
let computedStyles
let insideGrid = false
let gridHAlign
let gridVAlign
// TODO: respect dependsOn keys // TODO: respect dependsOn keys
@ -26,7 +29,6 @@
$: measured, observeComputedStyles(componentId) $: measured, observeComputedStyles(componentId)
$: component = $componentStore.selectedComponent $: component = $componentStore.selectedComponent
$: definition = $componentStore.selectedComponentDefinition $: definition = $componentStore.selectedComponentDefinition
$: parent = findComponentParent($builderStore.screen.props, componentId)
$: instance = componentStore.actions.getComponentInstance(componentId) $: instance = componentStore.actions.getComponentInstance(componentId)
$: state = $instance?.state $: state = $instance?.state
$: showBar = $: showBar =
@ -34,20 +36,14 @@
!$dndIsDragging && !$dndIsDragging &&
definition && definition &&
!$state?.errorState !$state?.errorState
$: {
if (!showBar) {
measured = false
}
}
$: settings = getBarSettings(component, definition) $: settings = getBarSettings(component, definition)
$: isRoot = componentId === $builderStore.screen?.props?._id $: isRoot = componentId === $builderStore.screen?.props?._id
$: insideGrid =
parent?._component.endsWith("/container") && parent.layout === "grid"
$: showGridStyles = $: showGridStyles =
insideGrid && insideGrid &&
(definition?.grid?.hAlign !== "stretch" || (definition?.grid?.hAlign !== "stretch" ||
definition?.grid?.vAlign !== "stretch") definition?.grid?.vAlign !== "stretch")
$: device = $builderStore.previewDevice $: mobile = $context.device.mobile
$: device = mobile ? Devices.Mobile : Devices.Desktop
$: gridHAlignVar = getGridVar(device, GridParams.HAlign) $: gridHAlignVar = getGridVar(device, GridParams.HAlign)
$: gridVAlignVar = getGridVar(device, GridParams.VAlign) $: gridVAlignVar = getGridVar(device, GridParams.VAlign)
@ -74,6 +70,9 @@
} }
const id = $builderStore.selectedComponentId const id = $builderStore.selectedComponentId
let element = document.getElementsByClassName(id)?.[0] let element = document.getElementsByClassName(id)?.[0]
// Check if we're inside a grid
insideGrid = element.parentNode.classList.contains("grid")
if (!insideGrid) { if (!insideGrid) {
element = element?.children?.[0] element = element?.children?.[0]
} }
@ -92,6 +91,17 @@
const height = self.offsetHeight const height = self.offsetHeight
const { scrollX, scrollY, innerWidth } = window const { scrollX, scrollY, innerWidth } = window
// Read grid metadata from data attributes
if (insideGrid) {
if (mobile) {
gridHAlign = element.dataset.gridMobileHAlign
gridVAlign = element.dataset.gridMobileVAlign
} else {
gridHAlign = element.dataset.gridDesktopHAlign
gridVAlign = element.dataset.gridDesktopVAlign
}
}
// Vertically, always render above unless no room, then render inside // Vertically, always render above unless no room, then render inside
let newTop = elBounds.top + scrollY - verticalOffset - height let newTop = elBounds.top + scrollY - verticalOffset - height
if (newTop < deviceBounds.top - 50) { if (newTop < deviceBounds.top - 50) {
@ -143,18 +153,13 @@
observer?.disconnect() observer?.disconnect()
const node = document.getElementsByClassName(`${id}-dom`)[0]?.parentNode const node = document.getElementsByClassName(`${id}-dom`)[0]?.parentNode
if (node) { if (node) {
observer = new MutationObserver(() => { observer = new MutationObserver(updatePosition)
console.log("get computed")
computedStyles = getComputedStyle(node)
updatePosition()
})
observer.observe(node, { observer.observe(node, {
attributes: true, attributes: true,
attributeFilter: ["style"], attributeFilter: ["style"],
childList: false, childList: false,
subtree: false, subtree: false,
}) })
computedStyles = getComputedStyle(node)
} }
} }
@ -184,32 +189,32 @@
value="start" value="start"
icon="AlignLeft" icon="AlignLeft"
title="Align left" title="Align left"
active={gridHAlign === "start"}
{componentId} {componentId}
{computedStyles}
/> />
<GridStylesButton <GridStylesButton
style={gridHAlignVar} style={gridHAlignVar}
value="center" value="center"
icon="AlignCenter" icon="AlignCenter"
title="Align center" title="Align center"
active={gridHAlign === "center"}
{componentId} {componentId}
{computedStyles}
/> />
<GridStylesButton <GridStylesButton
style={gridHAlignVar} style={gridHAlignVar}
value="end" value="end"
icon="AlignRight" icon="AlignRight"
title="Align right" title="Align right"
active={gridHAlign === "end"}
{componentId} {componentId}
{computedStyles}
/> />
<GridStylesButton <GridStylesButton
style={gridHAlignVar} style={gridHAlignVar}
value="stretch" value="stretch"
icon="MoveLeftRight" icon="MoveLeftRight"
title="Stretch horizontally" title="Stretch horizontally"
active={gridHAlign === "stretch"}
{componentId} {componentId}
{computedStyles}
/> />
<div class="divider" /> <div class="divider" />
<GridStylesButton <GridStylesButton
@ -217,32 +222,32 @@
value="start" value="start"
icon="AlignTop" icon="AlignTop"
title="Align top" title="Align top"
active={gridVAlign === "start"}
{componentId} {componentId}
{computedStyles}
/> />
<GridStylesButton <GridStylesButton
style={gridVAlignVar} style={gridVAlignVar}
value="center" value="center"
icon="AlignMiddle" icon="AlignMiddle"
title="Align middle" title="Align middle"
active={gridVAlign === "center"}
{componentId} {componentId}
{computedStyles}
/> />
<GridStylesButton <GridStylesButton
style={gridVAlignVar} style={gridVAlignVar}
value="end" value="end"
icon="AlignBottom" icon="AlignBottom"
title="Align bottom" title="Align bottom"
active={gridVAlign === "end"}
{componentId} {componentId}
{computedStyles}
/> />
<GridStylesButton <GridStylesButton
style={gridVAlignVar} style={gridVAlignVar}
value="stretch" value="stretch"
icon="MoveUpDown" icon="MoveUpDown"
title="Stretch vertically" title="Stretch vertically"
active={gridVAlign === "stretch"}
{componentId} {componentId}
{computedStyles}
/> />
<div class="divider" /> <div class="divider" />
{/if} {/if}

View File

@ -132,6 +132,8 @@ export const gridLayout = (node, metadata) => {
} }
addDataTag("gridDesktopRowEnd", Devices.Desktop, GridParams.RowEnd) addDataTag("gridDesktopRowEnd", Devices.Desktop, GridParams.RowEnd)
addDataTag("gridMobileRowEnd", Devices.Mobile, GridParams.RowEnd) addDataTag("gridMobileRowEnd", Devices.Mobile, GridParams.RowEnd)
addDataTag("gridDesktopHAlign", Devices.Desktop, GridParams.HAlign)
addDataTag("gridMobileHAlign", Devices.Mobile, GridParams.HAlign)
addDataTag("gridDesktopVAlign", Devices.Desktop, GridParams.VAlign) addDataTag("gridDesktopVAlign", Devices.Desktop, GridParams.VAlign)
addDataTag("gridMobileVAlign", Devices.Mobile, GridParams.VAlign) addDataTag("gridMobileVAlign", Devices.Mobile, GridParams.VAlign)
@ -149,7 +151,7 @@ export const gridLayout = (node, metadata) => {
// Removes the previously set up listeners // Removes the previously set up listeners
const removeListeners = () => { const removeListeners = () => {
node.removeEventListener("click", selectComponent) node.removeEventListener("click", selectComponent, false)
} }
applyMetadata(metadata) applyMetadata(metadata)