Creating 180 Control Buttons, a little bit slow on Android

Godot Version

4.4.1

Question

The current design creates the result below


I have total of 5 grids with each of 36 buttons. By listening swipe(in gui_input) i am shifting all this grid nodes parallelly (position.x). Current scroll container did not meet my suits.
My editor layout design is like below

As you see above, i have a node for each grid (total 5) and placed next to each other. This way by listening swipe i am changing their positions with parallel tweens.

After scene is rendered, everything is fast but initialization is a little bit slow(around 0.8 - 1.3 second)

In initialization imo, i am not doing too much for every button as seen below. They are normal buttons with styleboxflat styles (not texture buttons)

grid_size_lbl.text = str(grid_size) + " x " + str(grid_size)
	for row:int in grid_container.columns:
		for column:int in grid_container.columns:
			var level_num:int = (row * 6) + (column + 1)
			var lvl_exists:bool = Constants.is_level_exists(grid_size, level_num)
			var btn_ratio_container:LevelChooserBtnRatiod = LEVEL_CHOOSE_BTN.instantiate()
			var btn:Button = btn_ratio_container.get_child(0)
			btn_ratio_container.modulate_color = Constants.get_selection_grid_btn_color(grid_size)
			if lvl_exists:
				btn.pressed.connect(button_clicked.bind(level_num))
				btn_ratio_container.level_num = str(level_num)
			else:
				var levels_unlocked:bool = GameManager.are_levels_unlocked(grid_size)
				btn.disabled = true
				btn_ratio_container.level_num = "?"
	 
			grid_container.add_child(btn_ratio_container)


func button_clicked(level_num:int) -> void:
	var get_current_selection_scn = get_tree().get_first_node_in_group("level_choose_grid")
	SceneManager.load_game_session(get_current_selection_scn, Constants.get_level_data(grid_size, level_num))

So my question is, is there any way better to design this “swipe to grid” situation? Can i use multi threading in initialization? Am i missing a node exactly for this situation?

You might want to profile a bit, either with the profiler or by sprinkling around Time.get_ticks_usec() and comparing.

My suspicion would be a lot of your time is going into either add_child() or instantiate().

One thing you might try is not adding the grid container to the tree until after all the child buttons have been added.

Thanks, .init functions call the method above in first post

var start:int = Time.get_ticks_usec()
	level_chooser_grid5.grid_size = 5
	level_chooser_grid5.init()
	
	level_chooser_grid6.grid_size = 6
	level_chooser_grid6.init()
	
	level_chooser_grid7.grid_size = 7
	level_chooser_grid7.init()
	
	level_chooser_grid8.grid_size = 8
	level_chooser_grid8.init()
	
	level_chooser_grid9.grid_size = 9
	level_chooser_grid9.init()
	print("diff: " + str((Time.get_ticks_usec() - start) * 0.001))

This returned 140 ms for android phone so clearly not the code. I will try other places. By the way i check the profiler and i saw the spike in script functions part but dont know how to interpret it.

Edit: I checked each method and they all seem fine. I think tons of controls and calculations for each grid may take up that time. Since they are control nodes and everything is ratiod can be the normal culprit maybe?

There’s a get_ticks_msec() as well if you want more granular results.

What I’ve found with things like this is that if you make a lot of changes to a node that’s live it can be expensive, and the expense seems to happen outside the scripts. That is, you queue up a lot of work for Godot, and it does it in an internal update where it’s hard to profile.

I think you might get better results if you create a new grid container without adding it to the scene, add the buttons to the grid container, and then add the fully-built container-with-buttons to the scene. I can’t be sure, but it might be worth a try.


Profiler result for spike

Thanks i will try that, seems fine suggestion, even 0.3 seconds cut will be enough for me.