Very slow graphical menu

I have a simple graphical menu set up with esphome on a Firebeetle ESP32E. I am using a Waveshare 2.4in LCD screen.

It’s connected to a rotary encoder which controls the menu

It is all working perfectly, but when the list is long (say above 20 items) moving the menu between items is quite slow.

It’s quicker with a shorter list, but still pretty slow.

Any ideas on why this might be? I have tried adding two “move up” commands one after the other in the script and there’s a little delay between even those so I don’t think it’s just the rotary encoder that’s being slow to respond - it seems it’s the graphical menu that’s taking time to move between elements.

Here’s the main code - I haven’t included the graphical menu as it’s quite long

  esphome:
    name: tapeplayer

  esp32:
    board: firebeetle32
    framework:
      type: arduino

  # Enable logging
  logger:
    logs:
      component: ERROR

  # Enable Home Assistant API
  api:
    password: 

  ota:
    - platform: esphome
      password:

  

  wifi:
    ssid: ""
    password: ""

    # Enable fallback hotspot (captive portal) in case wifi connection fails
    ap:
      ssid: "

    manual_ip:
      # Set this to the IP of the ESP
      static_ip: 
      # Set this to the IP adress of the router. Often ends with .1
      gateway: 
      # The subnet of the network. 255.255.255.0 works for most home networks.
      subnet: 255.255.255.0

  captive_portal:

  sensor:
    - platform: rotary_encoder
      name: "Rotary Encoder"
      pin_a:
        number: GPIO16  # Connect CLK to D1
        mode:
          input: true
          pullup: true
      pin_b:
        number: GPIO17  # Connect DT to D2
        mode:
          input: true
          pullup: true
      resolution: 1
      filters:
        debounce: 10ms
      on_clockwise:
        - logger.log: "Moved up"  # Log message on button press
        - display_menu.up: my_graphical_display_menu
      on_anticlockwise:
        - display_menu.down: my_graphical_display_menu
        - logger.log: "Moved down"  # Log message on button press

  # Example minimal configuration entrydisplay:

  spi:
    clk_pin: GPIO18  # Clock pin (often labeled as SCK)
    mosi_pin: GPIO23  # Master Out Slave In (often labeled as MOSI or SDA)
    miso_pin: GPIO19  # Master In Slave Out (often labeled as MISO, optional for this display) 

  # Configure the display 
  display:
    - platform: ili9xxx
      model: ili9341
      id: my_display
      cs_pin: GPIO14
      dc_pin: GPIO25
      reset_pin: GPIO26
      invert_colors: false
      rotation: 90
      pages:
      - id: graph_page
        lambda: |-
          it.print(0, 0, id(my_font), "My menu is not currently active");
          it.print(0, 20, id(my_font), id(my_global_string).c_str());


  font:
    - file: "gfonts://Open+Sans"
      id: my_font
      size: 10
      



  binary_sensor:
    - platform: gpio
      name: "Rotary Encoder Button"
      pin:
        number: GPIO4  # Replace with the pin connected to the button 
        mode:
          input: true
          pullup: true  # Use an internal pull-up resistor
        inverted: true  # Ensure it works correctly with active-low buttons
      filters:
        - delayed_on: 30ms
        - delayed_off: 30ms
      on_press:
        - logger.log: "Rotary Encoder Button Pressed!"  # Log message on button press
        - if:
            condition:
              display_menu.is_active: my_graphical_display_menu
            then:
              - display_menu.enter: my_graphical_display_menu
            else:
              - display_menu.show: my_graphical_display_menu


  mqtt:
    broker: "
   
  # Include the graphical display menu from a separate file
  graphical_display_menu: !include graphical_display_menu.yaml