Best way to create multiple buttons which all have different values

Hello, Fuse forums, this will be my first post here :slight_smile:

I am currently developing an app to be used for control of a construction to be used for “The Gathering”.

This includes a control for an LED-strip, which has multiple functions (e.g. flash, strobe, solid light etc). For this reason, I need to have multiple buttons, 1 for each function, totaling 24.

Here is what I’m trying to replicate vs. what I’ve achieved:

LED-controller

As you can see, my problem is not creating the buttons, but rather how to optimize the creation process. As of now, when I scroll in the app to get the buttons into view, there is a noticeable delay (or lag, if you will) as the buttons are all created. This is not a problem when previewing on a computer, but a problem when previewing on my phone (S7 Edge), and only occurs the first time I scroll to that page.

I have tried multiple approaches, including creating each button individually, but my current code for creating the buttons is as follows (all approaches have resulted in lag):

Assets/JavaScript/buttons.js:

var colorPalette = require("../JavaScript/colorPalette");
colorPalette = colorPalette.colors; // A .js file containing information about all used colors

var lightButtons = Array(
	{name: "dimUp", color: colorPalette.white.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "dimDown", color: colorPalette.white.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "off", color: colorPalette.black.code, text: "OFF", textColor: colorPalette.white.code, fontSize: "28"},
	{name: "on", color: colorPalette.red.code, text: "ON", textColor: colorPalette.white.code, fontSize: "28"},

	{name: "red", color: colorPalette.red.code, text: "R", textColor: colorPalette.white.code, fontSize: "28"},
	{name: "green", color: colorPalette.green.code, text: "G", textColor: colorPalette.mdBlack.code, fontSize: "28"},
	{name: "blue", color: colorPalette.blue.code, text: "B", textColor: colorPalette.white.code, fontSize: "28"},
	{name: "white", color: colorPalette.white.code, text: "W", textColor: colorPalette.mdBlack.code, fontSize: "26"},

	{name: "lightRed", color: colorPalette.lightRed.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "lightGreen", color: colorPalette.lightGreen.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "lightBlue", color: colorPalette.lightBlue.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "flash", color: colorPalette.grey.code, text: "FLASH", textColor: colorPalette.mdBlack.code, fontSize: "18"},

	{name: "orange", color: colorPalette.orange.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "cyan", color: colorPalette.cyan.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "violet", color: colorPalette.violet.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "strobe", color: colorPalette.grey.code, text: "STROBE", textColor: colorPalette.mdBlack.code, fontSize: "18"},

	{name: "lightOrange", color: colorPalette.lightOrange.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "lightTurquoise", color: colorPalette.lightTurquoise.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "purple", color: colorPalette.purple.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "fade", color: colorPalette.grey.code, text: "FADE", textColor: colorPalette.mdBlack.code, fontSize: "18"},

	{name: "yellow", color: colorPalette.yellow.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "turquoise", color: colorPalette.turquoise.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "pink", color: colorPalette.pink.code, text: "", textColor: colorPalette.white.code, fontSize: "0"},
	{name: "smooth", color: colorPalette.grey.code, text: "SMOOTH", textColor: colorPalette.mdBlack.code, fontSize: "18"}
)

module.exports = lightButtons;

Pages/lightControlPage.js

var Observable = require("FuseJS/Observable");
var lightButtons = require("../Assets/JavaScript/buttons");

var lightButtonsObs = Observable();
lightButtonsObs.replaceAll(lightButtons)

module.exports = {
	lightButtonsObs: lightButtonsObs
}

Pages/lightControlPage.ux

<Page ux:Class="lightControlPage" ux:Name="lightControlPage">
	<JavaScript File="lightControlPage.js" />
	<Activated>
		<JavaScript>
			var helperFunctions = require("../Assets/JavaScript/helperFunctions");
			helperFunctions.changeActivePage("lightControlPage");
		</JavaScript>
	</Activated>
	<customButtonCircle ux:Class="colorButton" ux:Name="colorButton">
		<string ux:Property="ButtonName" />
		<float4 ux:Property="ButtonColor" />

		<LinearGradient AngleDegrees="120">
			<GradientStop Offset=".4" Color="{ReadProperty colorButton.ButtonColor}" />
			<GradientStop Offset="1" Color="{colorPalette.mdBlack.code}" />
		</LinearGradient>
	</customButtonCircle>

	<StackPanel>
		<Grid RowCount="6" ColumnCount="4">
			<Each Items="{lightButtonsObs}">
				<colorButton Height="60" Margin="0, 20, 0, 10" ButtonName="{name}" ButtonColor="{color}" Text="{text}" TextColor="{textColor}" FontSize="{fontSize}" />
			</Each>
		</Grid>
	</StackPanel>
</Page>

So, to get to my question; how would I make the creation process smoother and more elegant to avoid lag or delays?

TLDR; I need to create 24 buttons which all have different values/attributes, I can create them, but there is a noticeable lag/delay when scrolled into view. How do I fix that?

Hi Kodemikkel, and welcome!

The lag you’re describing is probably related to the transition between pages and simultaneous drawing of the UI.

A solution is to put a DeferPageSwitch property on your Navigator (if you’re using one), something like this:

<Navigator DeferPageSwitch="Preparing">
    ...
</Navigator>

There are ways to freeze only particular pages too. See DeferFreeze and IsFrozen for details.

If you’re using a PageControl, some of this may apply too, but you would have to check the docs for PageControl too.

If none of that helps, a complete reproduction is very welcome so we could do some debugging on our end.

I’m currently using a PageControl for navigation. DeferFreeze didn’t have any noticeable effect on the transition lag (code included to verify correct usage).

<!-- activePage is an Observable that contains information about the active page -->
<PageControl ux:Name="nav" Active="{activePage.navReference}" DeferFreeze="Preparing">
        <homePage />
	<heightControlPage />
	<lightControlPage />
	<pcControlPage />
</PageControl>

As mentioned earlier, it only lags the first time lightControlPage is scrolled into view, which might indicate that the lag is caused by the initialization of all the buttons/array?

Should the buttons maybe be initialized as the app is loaded? Although I might get a bit longer startup time, I feel that would be a good trade-off to avoid lag when using the app. However, I have no idea how to do that so it would have an effect, and without cluttering my code with unnecessary requires. Any ideas?

Shuffling through the docs, came upon this guy here: https://www.fusetools.com/docs/fuse/controls/page/freeze

So your code should then be something like this:

<PageControl ux:Name="nav" Active="{activePage.navReference}">
        <homePage />
	<heightControlPage />
	<lightControlPage  Freeze="WhileNavigating" />
	<pcControlPage />
</PageControl>

That should take care of it. Let us know how it goes!

It seems like it improved the transition. There is still something there that I can’t quite put my finger on (seems like the transition skips the first few frames), but it seems better than it was before; a bit hard to tell without some proper debugging. Nevertheless, I think I’ll stick with it unless I randomly stumble upon something.

One thing to note though; while previewing on my computer, the buttons do not appear until the transition is completed, whereas on my phone the buttons are visible when the transition starts. (Unless I navigate to the page using a button; in that case, the buttons appear after the transition has finished, same as on my computer)