Optimise builder preview speed and performance and fix components not updating when changing props
This commit is contained in:
parent
cb626d685b
commit
3ee9fee10c
|
@ -22,27 +22,37 @@
|
||||||
? screenPlaceholder
|
? screenPlaceholder
|
||||||
: $store.currentPreviewItem
|
: $store.currentPreviewItem
|
||||||
$: selectedComponentId = $store.currentComponentInfo?._id ?? ""
|
$: selectedComponentId = $store.currentComponentInfo?._id ?? ""
|
||||||
$: previewData = {
|
|
||||||
page,
|
// Saving pages and screens to the DB causes them to have _revs.
|
||||||
screen,
|
// These revisions change every time a save happens and causes
|
||||||
selectedComponentId,
|
// these reactive statements to fire, even though the actual
|
||||||
}
|
// definition hasn't changed.
|
||||||
|
// By deleting all _rev properties we can avoid this and increase
|
||||||
|
// performance.
|
||||||
|
$: json = JSON.stringify({ page, screen, selectedComponentId })
|
||||||
|
$: strippedJson = json.replaceAll(/"_rev":\s*"[^"]+"/g, `"_rev":""`)
|
||||||
|
|
||||||
// Update the iframe with the builder info to render the correct preview
|
// Update the iframe with the builder info to render the correct preview
|
||||||
const refreshContent = () => {
|
const refreshContent = message => {
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
iframe.contentWindow.postMessage(JSON.stringify(previewData))
|
iframe.contentWindow.postMessage(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh the preview when required
|
// Refresh the preview when required
|
||||||
$: refreshContent(previewData)
|
$: refreshContent(strippedJson)
|
||||||
|
|
||||||
// Initialise the app when mounted
|
// Initialise the app when mounted
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
iframe.contentWindow.addEventListener("bb-ready", refreshContent, {
|
iframe.contentWindow.addEventListener(
|
||||||
once: true,
|
"bb-ready",
|
||||||
})
|
() => {
|
||||||
|
refreshContent(strippedJson)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
once: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,11 @@ export default `<html>
|
||||||
selectedComponentStyle.appendChild(document.createTextNode(selectedCss))
|
selectedComponentStyle.appendChild(document.createTextNode(selectedCss))
|
||||||
|
|
||||||
// Set some flags so the app knows we're in the builder
|
// Set some flags so the app knows we're in the builder
|
||||||
window["##BUDIBASE_IN_BUILDER##"] = true;
|
window["##BUDIBASE_IN_BUILDER##"] = true
|
||||||
window["##BUDIBASE_PREVIEW_PAGE##"] = page;
|
window["##BUDIBASE_PREVIEW_PAGE##"] = page
|
||||||
window["##BUDIBASE_PREVIEW_SCREEN##"] = screen;
|
window["##BUDIBASE_PREVIEW_SCREEN##"] = screen
|
||||||
|
window["##BUDIBASE_SELECTED_COMPONENT_ID##"] = selectedComponentId
|
||||||
|
window["##BUDIBASE_PREVIEW_ID##"] = Math.random()
|
||||||
|
|
||||||
// Initialise app
|
// Initialise app
|
||||||
if (window.loadBudibase) {
|
if (window.loadBudibase) {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import * as ComponentLibrary from "@budibase/standard-components"
|
import * as ComponentLibrary from "@budibase/standard-components"
|
||||||
import Router from "./Router.svelte"
|
import Router from "./Router.svelte"
|
||||||
import { enrichProps } from "../utils/componentProps"
|
import { enrichProps } from "../utils/componentProps"
|
||||||
import { bindingStore } from "../store"
|
import { bindingStore, builderStore } from "../store"
|
||||||
|
|
||||||
export let definition = {}
|
export let definition = {}
|
||||||
|
|
||||||
|
@ -32,12 +32,20 @@
|
||||||
const name = split?.[split.length - 1]
|
const name = split?.[split.length - 1]
|
||||||
return name === "screenslot" ? Router : ComponentLibrary[name]
|
return name === "screenslot" ? Router : ComponentLibrary[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a unique key to let svelte know when to remount components.
|
||||||
|
// If a component is selected we want to remount it every time any props
|
||||||
|
// change.
|
||||||
|
const getChildKey = childId => {
|
||||||
|
const selected = childId === $builderStore.selectedComponentId
|
||||||
|
return selected ? `${childId}-${$builderStore.previewId}` : childId
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if constructor}
|
{#if constructor}
|
||||||
<svelte:component this={constructor} {...enrichedProps}>
|
<svelte:component this={constructor} {...enrichedProps}>
|
||||||
{#if children && children.length}
|
{#if children && children.length}
|
||||||
{#each children as child (child._id)}
|
{#each children as child (getChildKey(child._id))}
|
||||||
<svelte:self definition={child} />
|
<svelte:self definition={child} />
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -9,6 +9,8 @@ const loadBudibase = () => {
|
||||||
inBuilder: !!window["##BUDIBASE_IN_BUILDER##"],
|
inBuilder: !!window["##BUDIBASE_IN_BUILDER##"],
|
||||||
page: window["##BUDIBASE_PREVIEW_PAGE##"],
|
page: window["##BUDIBASE_PREVIEW_PAGE##"],
|
||||||
screen: window["##BUDIBASE_PREVIEW_SCREEN##"],
|
screen: window["##BUDIBASE_PREVIEW_SCREEN##"],
|
||||||
|
selectedComponentId: window["##BUDIBASE_SELECTED_COMPONENT_ID##"],
|
||||||
|
previewId: window["##BUDIBASE_PREVIEW_ID##"],
|
||||||
})
|
})
|
||||||
|
|
||||||
// Create app if one hasn't been created yet
|
// Create app if one hasn't been created yet
|
||||||
|
|
|
@ -5,6 +5,8 @@ const createBuilderStore = () => {
|
||||||
inBuilder: false,
|
inBuilder: false,
|
||||||
page: null,
|
page: null,
|
||||||
screen: null,
|
screen: null,
|
||||||
|
selectedComponentId: null,
|
||||||
|
previewId: null,
|
||||||
}
|
}
|
||||||
return writable(initialState)
|
return writable(initialState)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue