Setting a button's Border radius dynamically; cloning images speed

If I get the object properties of a button, there are about 30 numbered properties. I want to set the “Border radius” property of a button use an Any Component block. Does anyone know how to do this? I’ve tried to set the property “Border radius” of object but that doesn’t seem to do anything.

1 Like

Can you get a Json from the object?

1 Like

I’m not sure how that would work. I think I need to identify the correct property name but I haven’t found one that works.

1 Like

I THINK those “properties” are actually the number of characters in the GUID thunkable uses to identify components. I tried going down that path few months back to no avail. But Thunkable is always changing

2 Likes

@drted Hmm, okay. I thought maybe they corresponded to each property in the panels in the Design tab. But I haven’t had any luck so far.

I’m returning to something I did when I first started using Thunkable: trying to create a grid of thumbnail images (buttons). Cloning is SLOW. Creating buttons seems faster but I lack access to most of the button properties. I’m considering just pre-populating the screen with buttons but that’s impractical and since I have a dynamic number of thumbnails that could easily range from 1 to 100, not ideal.

1 Like

Actually, I think my backup plan will be a grid of 9 (or 16) buttons with “next page” & “previous page” buttons to scroll between pages of thumbnails. That way I can keep it to one screen and only manually create a limited number of actual components.

1 Like

Hey @tatiang.

The Clone vs. Create topic is indeed a really interesting one and I have found myself spending hours trying to understand which is the best approach and it turns out that the answer is: “it depends”.

The most significant factor is whether you want to show the new elements (irrespective of whether that will be done by creating or cloning) on screen as they get generated. Simply put, showing them as they get generated is much slower than not showing them. The difference might not be that noticeable when generating a small number (i.e. 10) but when creating a large number (i.e. 50 or 100) then the difference is significant! Bottom line: Not showing is always faster than showing.

The other thing to consider is how complex is formatting as when you create elements you have faaaaar less control over their formatting. As you pointed earlier, you just can’t control things like i.e. a column’s padding or its contents justification. If you need to do that, there is no other way but to create your prototype in a hidden container (row or column) and then clone it in your app’s screen. And even if you want to create your elements and them format them, consider the additional blocks you will need for doing so and needless to say, more blocks take more time to be processed.

To better illustrate the above, I created a clone benchmark app (link) which considers a simple prototype which is a row with an image, a label and a button plus some formatting for each of them. Creating the same prototype with blocks will not match cloning visually due to the formatting limitations mentioned above.

Running it on my iPhone 7 for 25 repetitions I got:
Create with wait: 1.29 sec
Create without wait: 0.27 sec
Clone with wait: 1.12 sec
Clone without wait: 0.04 sec <-- Best

…and for 100 repetitions:
Create with wait: 12.66 sec
Create without wait: 2.55 sec
Clone with wait: 9.97 sec
Clone without wait: 0.37 sec <-- Best

Notice the huge difference in times between waiting and not waiting when we have 100 repetitions.

Closing, I would like to address the “So why show the elements as they get created?” question. This is something you may need to do knowing that completing all repetitions may take time the user is not willing to wait for. For example, in my news app I have a screen which returns 50 results. There is no way the user will wait for 6-7 seconds before he sees even the first result; the user will just not use the app. Instead, being able to see the first, second and third result almost instantly is something compering to having to wait multiple seconds for. So yes, there are real-life cases where you might need to show the elements as they get created.

I hope the above helps a bit.

Kind regards
Konstantinos

3 Likes

@Deluxe, very, very helpful. Thank you. I was thinking of making a benchmark project so I’ll look at yours instead. :slight_smile:

Yes, good point about showing the user what they want immediately regardless of how long it might take to create the components in the background. I think the issue for me is that I’m using separate screens. I may have to take a single-screen approach to my app which unfortunately, Thunkable doesn’t yet handle very well.

The new drag-and-drop interface should help with that as we can now layer components but even if it worked perfectly, there are many missing features that I rely on.

1 Like

@Deluxe I was surprised at how fast your cloning was. Four hundredths of a second for 25 rows containing three components each. In my experience, cloning just a few rows of three components can take up to ten seconds. So I had to ask myself: what could be causing the delay? And it’s pretty clear now that assigning a photo to a button is the thing that is slowing everything down for me. I’ve been cloning and setting images without thinking to separate the two processes.

So that’s next. It seems odd that an image that exists on the phone/in the project would take any significant amount of time to “assign” to a component. I can see if it’s web-based and pulled from somewhere, but local…???

The other problem is that I believe it’s reporting the time duration before the clones are created. So I think your times might be quite a bit off, at least that’s what I’m seeing in my initial testing. It reports 0.05 seconds but then spends about 5 seconds drawing the remaining cloned components.

Even when I put the loop counter in the Clone block’s “Do” section, it still fires before the clone is drawn on the screen:

1 Like

I agree that the “without wait” times are a bit off so I timed them manually and it would be safe to say that you only need to add about 1.2 seconds to their on-screen result at least on my low-end Huawei P smart Z. Now that I think of it, we may want to break the analysis in two parts: a. How fast the device calculates the clones/creations and b. How fast it displays them. The first has to do with its CPU while the second with its GPU. Of course, there are other factors that play their role such as other apps running in the background, the type of the device’s memory (i.e. UFS or eMMC etc.) but the test app gives the high-level, pragmatic picture.

The key take-away is the huge difference between the with and without wait. On the other hand, cloning vs. creating primarily has to do with how complex your prototype is, as described above.

Again, as mentioned, huuuuuge topic! :slight_smile:

Konstantinos

1 Like

I just noticed something interesting about your test app’s code (barely visible at the end of your video). Why do you use the “repeat > until” loop? If you want to show the clones as they get created, insert the wait block in or right under the clone block. I don’t see why you need the “repeat > until” loop.

Just curious…

1 Like

The purpose of the repeat until block was to force the program to wait until all 25 iterations of the clone loop completed. But it didn’t do that. I think the clone block gets queued and the change var by 1 block still fires each cycle of the loop (it shouldn’t). Or rather, the clone is “created” but not drawn.

So the timing is inaccurate. Again, the program completes in a fraction of a second but the drawing of the clones takes 5-7 seconds. I’ll try your suggestion for using a wait block to see each clone as it’s created.

1 Like

Rather than a fixed wait, try something like this. That way in only waits as long a necessary.

2 Likes

Here’s what I tried based on your suggestion. It’s surprisingly fast!

1 Like

And I was able to verify, now that I’ve separated it out, that setting each cloned button’s image for 25 buttons takes about 5 seconds. So now I need to work on reducing that delay. Perhaps with smaller cloudinary image sizes.

I’m experimenting with populating the cloned buttons with resized images:

Ideally, I’d POST a smaller version in Cloudinary but I haven’t figured that out yet. This method, though, reduces the display time from 5-7 seconds down to about 2 seconds. Unfortunately, it doesn’t seem to much matter what I set the new width to… 200 pixels or 5 pixels… it still takes about 2 seconds to display.

FYI, other image optimization options including q_auto can be found at Image Optimization | Cloudinary.

1 Like

I use this on most images I bring into the app from cloudinary. It works wonders!

I think in the background setting up integromat to schedule a chrome job would be ideal and something I hang done yet. Like for every new image uploaded there could be an automation that resize the image so that you don’t have to resize on the fly. That should also increase the speed of the image loading fractionally

Ideally, I’d POST a smaller version in Cloudinary but I haven’t figured that out yet.

Upvote this: (Thunkable X) Picture resize before uploading to MediaDB · Issue #224 · thunkable/thunkable-issues · GitHub

Curious… isn’t this the same as Waiting 0 seconds?

Deluxe, yes, it is the same as a zero second wait. I was comparing it to the fixed waiting period mentioned above.

1 Like