Optimization. I think I'm doing something wrong

Hi all!
I’m making a game in SugarCube and have encountered warnings in chrome that the “click” handler is taking a certain amount of time and the further I get with development, the longer it takes. I understand that this is not very good and needs to be addressed at the initial stage, but I don’t know how.
I’m working on a gaming phone now. It is made with widgets in the right ui bar. It has app buttons, chat buttons, contact card buttons, etc. they are all done with arrays/objects and output in loops. And their handlers are in another widget, a widget for all handlers. They are all like this:

<<for _i to 0; _i<setup.phoneApps.length && _i!=15; _i++>>
    <<if setup.phoneApps[_i].isDownload>>
        <span id="gridItem">
            <button @data-id="setup.phoneApps[_i].nameApp" class="appButton open__app">[img[setup.phoneApps[_i].imgBtn]]</button>
        </span>
 <</if>>
<</for>>

<<done>>
<<script>>
openApp.forEach((open__app) => {
    open__app.addEventListener('click', () => {
      const contentAppItems = document.querySelectorAll('.content__app');
      contentAppItems.forEach((contentAppItem) => {
        if (contentAppItem.getAttribute('id') === open__app.getAttribute('data-id')) {
          contentAppItem.classList.add('activeNow');
          openOrder.push(contentAppItem); 
        }
      });
    });
  });
<</script>>
<</done>>

Everything is working. While I’m on the phone there are no problems at all and there are no warnings in the console, but as soon as I move to another passage or update the game time, in short, whenever there is an update of the game content, the warning [Violation] ‘click’ handler took 297ms appears in the console. And since the player will have to constantly move from location to location, the time will constantly change, and a new notification appears for each update, soon there will be thousands or more notifications. True, if you don’t open the console, you won’t see this, but still, it seems to me that this is not a very good practice. There is another line [Violation] ‘setTimeout’ handler took 499ms, but I checked it appears even in a new clean project, although the value there is somewhere around 65ms, and now 499ms, but also in contrast to an empty game and the content in it increased. At least this line doesn’t multiply with each content update, it’s always the same. Unlike [Violation] ‘click’ handler took 297ms, which is exactly the same as the screen refresh.
Help me solve the riddle, please. Please advise what to pay attention to or what needs to be changed.

There is also an additional nuance: when I move to another passage or change the time, my phone closes all open blocks and returns to its desktop. Maybe you know how to make sure that the state of open blocks is not reset? So I opened a chat with an NPC on the phone in the right ui bar, and in the main part of the game I went to “Home” passage from “Street” and that’s it, the chat was closed. If you can give me advice on this, I would be very grateful!

What are you trying to do with the handler/script?

And why using the HTML button rather than the <<button>> macro?

I don’t know. I learned that and did it and it worked (and works). Well, I did so further. How should it be? Please show me using my code snippets so that I can show the entire syntax using an example.

The documentation for the <<button>> macro can be found here.

I still don’t understand what the code in <<script>> is trying to achieve here (you haven’t said what you are trying to do with that code), so it’s a bit hard to say exactly what’s wrong with it…

This code snippet is just an example of how I created buttons and how I attach handlers to them. I read the documentation and of course I saw this macro, but I have little experience in coding and don’t always know how to apply it. so the option that worked for me is the one I stick to :))
This particular code on the phone opens applications, browser, messenger, etc. Plus it adds them to the array of open applications so that the “back” button works correctly. And it all works fine. In the same way, I display the chat buttons of all the heroes and all the hero cards (I wrote about all this in the question). The question is different, after a large number of applications, chats, handlers for all this and all these handlers are in <<done>>, which waits for the entire page to load before using the script, because if without <<done>>, then errors appear in the script type “null” so I have to use <<done>> for everything to work. and if <<done>>, then the handler waits, and the more places where you have to wait, then the overall wait becomes larger, which is what chrome writes to me about. I figured that as development continued, there wouldn’t be fewer such places and therefore the whole game as a whole would only work worse, so I decided to turn to experts. I tried to use a button macro, but it didn’t work for me, for example, this handler from the example would work when such a macro was clicked. That’s why I asked to be shown specifically using my example, and not in the documentation.

I think you have a misunderstanding. An event listener (what you are creating with addEventListener() doesn’t wait in that sense. It just responds when the click happens.

The warning suggests that you are triggering the click handler and it’s taking too long to run. That suggests that it is doing something recursive (or somehow looping through an incredibly long list).

However, there’s just not enough information in your post to diagnose this. We don’t know where openApp comes from, we don’t know how many .content__app elements there are, we don’t know what happens after you push them to openOrder and so on. You mention a setTimeout error, but there isn’t even a setTimeout() call in the code you have shown. As @manonamora says, I can’t even work out what the click handlers are doing. It looks like it adds an activeNow class to the selected app, but I don’t know why it needs to search .content_app elements. Is there maybe one element that gets clicked and another that should appear when that happens? If so, a simpler approach is probably:

openApp.forEach((open__app) => {
    open__app.addEventListener('click', () => {
      const matchingApp = document.getElementById(this.getAttribute('data-id'));
      matchingApp.classList.add('activeNow');
      openOrder.push(matchingApp); 
    });
  });

However, to answer your other question, if you want an element to persist between passages, you need to put it outside the story areas controlled by SugarCube, because those refresh every time you load a passage. Either add your phone elements directly to body, or check out the StoryInterface special passage.

Why then, when I comment on the messenger widget from the phone and the handler widget for all buttons, does this warning disappear and no longer appear when going through the passage?
It’s not a matter of the handler, it’s a matter of <<done>> because of it the handler waits for the page to load and therefore a warning appears about the click taking a long time to fire, and without it the handler has the value “null”. And my question is exactly this: “How to write a button that opens a block (adds a class to it, in which the display property changes from “none” to “flex”), so that the button immediately sees both itself and the block that it should open , and I wouldn’t have to use time delay be it <<timed 0s>> or <<done>> or something else?"

But you haven’t shown a click handler that would wait because of <<done>>. The code that you did show waits to set up the click handlers, it doesn’t wait when you click.

Again, sorry, but you haven’t shown us the part of the code that is causing the problem, so it’s hard to guess what might be going on.