From 3ee9fee10c3a6d662cb51ae8c3c9b126527a29ab Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 30 Nov 2020 12:11:50 +0000 Subject: [PATCH 1/3] Optimise builder preview speed and performance and fix components not updating when changing props --- .../AppPreview/CurrentItemPreview.svelte | 32 ++++++++++++------- .../AppPreview/iframeTemplate.js | 8 +++-- .../client/src/components/Component.svelte | 12 +++++-- packages/client/src/index.js | 2 ++ packages/client/src/store/builder.js | 2 ++ 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/packages/builder/src/components/userInterface/AppPreview/CurrentItemPreview.svelte b/packages/builder/src/components/userInterface/AppPreview/CurrentItemPreview.svelte index 243817dfda..535b947f5f 100644 --- a/packages/builder/src/components/userInterface/AppPreview/CurrentItemPreview.svelte +++ b/packages/builder/src/components/userInterface/AppPreview/CurrentItemPreview.svelte @@ -22,27 +22,37 @@ ? screenPlaceholder : $store.currentPreviewItem $: selectedComponentId = $store.currentComponentInfo?._id ?? "" - $: previewData = { - page, - screen, - selectedComponentId, - } + + // Saving pages and screens to the DB causes them to have _revs. + // These revisions change every time a save happens and causes + // 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 - const refreshContent = () => { + const refreshContent = message => { if (iframe) { - iframe.contentWindow.postMessage(JSON.stringify(previewData)) + iframe.contentWindow.postMessage(message) } } // Refresh the preview when required - $: refreshContent(previewData) + $: refreshContent(strippedJson) // Initialise the app when mounted onMount(() => { - iframe.contentWindow.addEventListener("bb-ready", refreshContent, { - once: true, - }) + iframe.contentWindow.addEventListener( + "bb-ready", + () => { + refreshContent(strippedJson) + }, + { + once: true, + } + ) }) diff --git a/packages/builder/src/components/userInterface/AppPreview/iframeTemplate.js b/packages/builder/src/components/userInterface/AppPreview/iframeTemplate.js index 2d25aea92b..6c18def11b 100644 --- a/packages/builder/src/components/userInterface/AppPreview/iframeTemplate.js +++ b/packages/builder/src/components/userInterface/AppPreview/iframeTemplate.js @@ -32,9 +32,11 @@ export default ` selectedComponentStyle.appendChild(document.createTextNode(selectedCss)) // Set some flags so the app knows we're in the builder - window["##BUDIBASE_IN_BUILDER##"] = true; - window["##BUDIBASE_PREVIEW_PAGE##"] = page; - window["##BUDIBASE_PREVIEW_SCREEN##"] = screen; + window["##BUDIBASE_IN_BUILDER##"] = true + window["##BUDIBASE_PREVIEW_PAGE##"] = page + window["##BUDIBASE_PREVIEW_SCREEN##"] = screen + window["##BUDIBASE_SELECTED_COMPONENT_ID##"] = selectedComponentId + window["##BUDIBASE_PREVIEW_ID##"] = Math.random() // Initialise app if (window.loadBudibase) { diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index 1d9308ca26..90428dbf34 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -4,7 +4,7 @@ import * as ComponentLibrary from "@budibase/standard-components" import Router from "./Router.svelte" import { enrichProps } from "../utils/componentProps" - import { bindingStore } from "../store" + import { bindingStore, builderStore } from "../store" export let definition = {} @@ -32,12 +32,20 @@ const name = split?.[split.length - 1] 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 + } {#if constructor} {#if children && children.length} - {#each children as child (child._id)} + {#each children as child (getChildKey(child._id))} {/each} {/if} diff --git a/packages/client/src/index.js b/packages/client/src/index.js index 2925e950f6..fa0e3177f4 100644 --- a/packages/client/src/index.js +++ b/packages/client/src/index.js @@ -9,6 +9,8 @@ const loadBudibase = () => { inBuilder: !!window["##BUDIBASE_IN_BUILDER##"], page: window["##BUDIBASE_PREVIEW_PAGE##"], 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 diff --git a/packages/client/src/store/builder.js b/packages/client/src/store/builder.js index 4b197596be..04363263c3 100644 --- a/packages/client/src/store/builder.js +++ b/packages/client/src/store/builder.js @@ -5,6 +5,8 @@ const createBuilderStore = () => { inBuilder: false, page: null, screen: null, + selectedComponentId: null, + previewId: null, } return writable(initialState) } From ce18e253babbcc2dfcf74a4b22083b6ccb85cce7 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 30 Nov 2020 15:05:36 +0000 Subject: [PATCH 2/3] Remove deprecated props, fix warnings, remove old code --- .../store/screenTemplates/utils/Component.js | 2 - .../EventsEditor/EventsEditor.svelte | 127 ------------------ .../EventsEditor/StateBindingCascader.svelte | 53 -------- packages/client/src/components/Screen.svelte | 2 +- packages/server/src/constants/pages.js | 23 ---- packages/server/src/constants/screens.js | 5 - packages/standard-components/components.json | 124 +---------------- .../standard-components/src/Container.svelte | 1 - .../standard-components/src/Navigation.svelte | 2 - .../standard-components/src/Textfield.svelte | 10 -- packages/standard-components/src/index.js | 1 - 11 files changed, 7 insertions(+), 343 deletions(-) delete mode 100644 packages/builder/src/components/userInterface/EventsEditor/EventsEditor.svelte delete mode 100644 packages/builder/src/components/userInterface/EventsEditor/StateBindingCascader.svelte delete mode 100644 packages/standard-components/src/Textfield.svelte diff --git a/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js b/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js index 0a40c62dc7..84de7e15ea 100644 --- a/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js +++ b/packages/builder/src/builderStore/store/screenTemplates/utils/Component.js @@ -15,8 +15,6 @@ export class Component extends BaseStructure { selected: {}, }, _code: "", - className: "", - onLoad: [], type: "", _instanceName: "", _children: [], diff --git a/packages/builder/src/components/userInterface/EventsEditor/EventsEditor.svelte b/packages/builder/src/components/userInterface/EventsEditor/EventsEditor.svelte deleted file mode 100644 index 4df9a0d62e..0000000000 --- a/packages/builder/src/components/userInterface/EventsEditor/EventsEditor.svelte +++ /dev/null @@ -1,127 +0,0 @@ - - - - -
-
- {#each events as event, index} - {#if event.handlers.length > 0} -
openModal({ ...event, index })}> - {event.name} - EDIT -
- {/if} - {/each} -
-
- - - - - - diff --git a/packages/builder/src/components/userInterface/EventsEditor/StateBindingCascader.svelte b/packages/builder/src/components/userInterface/EventsEditor/StateBindingCascader.svelte deleted file mode 100644 index 3475a14eed..0000000000 --- a/packages/builder/src/components/userInterface/EventsEditor/StateBindingCascader.svelte +++ /dev/null @@ -1,53 +0,0 @@ - - -
- {#if parameter.name === 'automation'}{parameter.name}{/if} - {#if parameter.name === 'automation'} - - {:else if parameter.name === 'url'} - - - {/each} - - {:else} - - {/if} -
- - diff --git a/packages/client/src/components/Screen.svelte b/packages/client/src/components/Screen.svelte index b79becc9cf..33dd3b3427 100644 --- a/packages/client/src/components/Screen.svelte +++ b/packages/client/src/components/Screen.svelte @@ -4,7 +4,7 @@ import Component from "./Component.svelte" // Keep route params up to date - export let params + export let params = {} $: routeStore.actions.setRouteParams(params || {}) // Get the screen definition for the current route diff --git a/packages/server/src/constants/pages.js b/packages/server/src/constants/pages.js index e017885b49..3923d6b5c3 100644 --- a/packages/server/src/constants/pages.js +++ b/packages/server/src/constants/pages.js @@ -31,8 +31,6 @@ const MAIN = { selected: {}, }, _code: "", - className: "", - onLoad: [], type: "div", _appId: "inst_app_80b_f158d4057d2c4bedb0042d42fda8abaf", _instanceName: "Header", @@ -58,12 +56,6 @@ const MAIN = { _code: "", logoUrl: "https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg", - title: "", - backgroundColor: "", - color: "", - borderWidth: "", - borderColor: "", - borderStyle: "", _appId: "inst_cf8ace4_69efc0d72e6f443db2d4c902c14d9394", _instanceName: "Navigation", _children: [ @@ -88,11 +80,6 @@ const MAIN = { url: "/", openInNewTab: false, text: "Home", - color: "", - hoverColor: "", - underline: false, - fontSize: "", - fontFamily: "initial", _appId: "inst_cf8ace4_69efc0d72e6f443db2d4c902c14d9394", _instanceName: "Home Link", _children: [], @@ -143,8 +130,6 @@ const MAIN = { selected: {}, }, _code: "", - className: "", - onLoad: [], }, } @@ -181,13 +166,7 @@ const UNAUTHENTICATED = { selected: {}, }, _code: "", - loginRedirect: "", - usernameLabel: "Username", - passwordLabel: "Password", - loginButtonLabel: "Login", - buttonClass: "", _instanceName: "Login", - inputClass: "", _children: [], title: "Log in to {{ name }}", buttonText: "Log In", @@ -213,8 +192,6 @@ const UNAUTHENTICATED = { selected: {}, }, _code: "", - className: "", - onLoad: [], }, } diff --git a/packages/server/src/constants/screens.js b/packages/server/src/constants/screens.js index 5c5a9dfd26..a4e9c031ed 100644 --- a/packages/server/src/constants/screens.js +++ b/packages/server/src/constants/screens.js @@ -19,8 +19,6 @@ exports.HOME_SCREEN = { selected: {}, }, _code: "", - className: "", - onLoad: [], type: "div", _children: [ { @@ -35,7 +33,6 @@ exports.HOME_SCREEN = { selected: {}, }, _code: "", - className: "", text: "Welcome to your Budibase App 👋", type: "h2", _appId: "inst_cf8ace4_69efc0d72e6f443db2d4c902c14d9394", @@ -61,8 +58,6 @@ exports.HOME_SCREEN = { selected: {}, }, _code: "", - className: "", - onLoad: [], type: "div", _appId: "inst_app_2cc_ca3383f896034e9295345c05f7dfca0c", _instanceName: "Video Container", diff --git a/packages/standard-components/components.json b/packages/standard-components/components.json index 180652688f..d1376384d8 100644 --- a/packages/standard-components/components.json +++ b/packages/standard-components/components.json @@ -18,13 +18,7 @@ "description": "A basic header navigation component", "children": true, "props": { - "logoUrl": "string", - "title": "string", - "backgroundColor": "string", - "color": "string", - "borderWidth": "string", - "borderColor": "string", - "borderStyle": "string" + "logoUrl": "string" } }, "button": { @@ -32,7 +26,6 @@ "description": "an html