Http.begin function is making my ui slow and laggy

what im currently doing is that im designing a ui for a project, and in this ui i want to dispaly the weather of my city, my problem is that when i uploaded the code without the weather segment the ui works perfectly, but when i added the weather segment the ui started lagging horribly. what i did next was a kind of process of elimination to determine what was causing the ui lag. i started to delete lines of code and uploading until i found the culprit. the http.begin function is causing this lag, when runing the code without it the screen is buttery smooth. I know that this isnt specifically an LVGL or squareline studio problem but i didnt know where else to ask, any help would much appreciated.
my code:

#include <lvgl.h>
#include <TFT_eSPI.h>
#include <ui.h>
#include <FT6236.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
FT6236 ts =FT6236();

/*Don't forget to set Sketchbook location in File/Preferencesto the path of your UI project (the parent foder of this INO file)*/
const char* ssid = "TP-Link_9584";
const char* password = "mahmoud1997";
String URL = "http://api.openweathermap.org/data/2.5/weather?";
String ApiKey = "19d727ef1f40988a879d3ed7073cea7f";
String lat = "32.85058250391577";
String lon = "13.186447750686403";
/*Change to your screen resolution*/
static const uint16_t screenWidth  = 320;
static const uint16_t screenHeight = 240;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * screenHeight / 10 ];

TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */

#if LV_USE_LOG != 0
/* Serial debugging */
void my_print(const char * buf)
{
    Serial.printf(buf);
    Serial.flush();
}
#endif

/* Display flushing */
void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p )
{
    uint32_t w = ( area->x2 - area->x1 + 1 );
    uint32_t h = ( area->y2 - area->y1 + 1 );

    tft.startWrite();
    tft.setAddrWindow( area->x1, area->y1, w, h );
    tft.pushColors( ( uint16_t * )&color_p->full, w * h, true );
    tft.endWrite();

    lv_disp_flush_ready( disp );
}

/*Read the touchpad*/
void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
{
   if(ts.touched()){
    data->state = LV_INDEV_STATE_PR;
    TS_Point p = ts.getPoint();
    data ->point.x = p.y;
     data->point.y = tft.width() - p.x;
     Serial.printf("x-%d,y-%d\n", data->point.x, data->point.y);
   }else{
     data->state = LV_INDEV_STATE_REL;
   }
   }


void setup()
{
    Serial.begin( 115200 ); /* prepare for possible serial debug */
tft.begin();          /* TFT init */
    tft.setRotation( 3 ); 


    if(!ts.begin(40)){
      Serial.println("unable to start");
    }
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

   Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

    if(!ts.begin(40)){
      Serial.println("unable to start");
    }
lv_init();
lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * screenHeight / 10 );

    String LVGL_Arduino = "Hello Arduino! ";
    LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();

    Serial.println( LVGL_Arduino );
    Serial.println( "I am LVGL_Arduino" );

    

#if LV_USE_LOG != 0
    lv_log_register_print_cb( my_print ); /* register print function for debugging */
#endif

    

    
    /*Initialize the display*/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init( &disp_drv );
    /*Change the following line to your display resolution*/
    disp_drv.hor_res = screenWidth;
    disp_drv.ver_res = screenHeight;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register( &disp_drv );

    /*Initialize the (dummy) input device driver*/
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init( &indev_drv );
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = my_touchpad_read;
    lv_indev_drv_register( &indev_drv );


    ui_init();

    Serial.println( "Setup done" );
}

void loop()
{

 if (WiFi.status() == WL_CONNECTED) {

    HTTPClient http;

    //Set HTTP Request Final URL with Location and API key information
    http.begin(URL + "lat=" + lat + "&lon=" + lon + "&units=metric&appid=" + ApiKey);

    // start connection and send HTTP Request
    int httpCode = http.GET();

    // httpCode will be negative on error
    if (httpCode > 0) {

      //Read Data as a JSON string
      String JSON_Data = http.getString();
      

      //Retrieve some information about the weather from the JSON format
      DynamicJsonDocument doc(2048);
      deserializeJson(doc, JSON_Data);
      JsonObject obj = doc.as<JsonObject>();

      //Display the Current Weather Info
      const char* description = obj["weather"][0]["description"].as<const char*>();
      const float temp = obj["main"]["temp"].as<float>();
      const float humidity = obj["main"]["humidity"].as<float>();
      Serial.printf("\n%f",temp);
      int TEMP=(int)temp;
      int HUMIDITY=(int)humidity;
      char per='%';
      lv_label_set_text_fmt(ui_TEMPLABEL, "%d", TEMP);
      lv_label_set_text_fmt(ui_HUMIDITYLABEL, "%d%c", HUMIDITY,per);
      
}

http.end();

    lv_timer_handler(); /* let the GUI do its work */
    delay(5);

}


    lv_timer_handler(); /* let the GUI do its work */
    delay(5);
}

UI without http.begin:


UI with http.begin

You already found the problem, the function that you’re using blocks (for about 0.5…1s) the main loop which is responsible for the refreshment of the GUI inputs and outputs (by calling lv_timer_handler periodically in cca 5…20ms intervals). Http.begin is much slower than the required timeframe for adequate LVGL screen update so you should avoid it using in the main loop as is. What you can do is using theards in your program and calling the slow http.begin and similar functions in a different thread than LVGL’s thread, updating the necessary information in variables and display them in the thread of the LVGL displayer code.

Alternatively, if you don’t want to or can’t use threads, you’ll need to find a non-blocking or ‘polling’ alternative of the http.begin function that can be called in the main loop beside LVGL updates, but returns immediately (or in time of max. 5…10 milliseconds) if the result has not yet arrived. But even getting the results with http.GET and http.getString can be blocking, so the same should be done with polling/non-blocking versions of those. To follow where you’re in the process you can use state variables, essentially doing all the requests in a state-machine.

iam a complete noob when it comes to advanced programming, i do not know what threads are or have any knowledge of state variables.
maybe if you have an example of a non-blocking alternative to http.begin???
thank you for taking the time to explain.

i tried using the weather function outside of the main loop and created another loop and plugged in the code for the weather in there, the ui started to behave normally but i couldn’t get the weather info to be viewed on the screen . i don’t know what im doing wrong.

The HttpClient library you’re using seems to have simple functions that would take more time than your GUI refresh-time, so it seems the only option is running it in different thread. You said you created another loop for the Http handling. I guess you’ve put it in a place where it never runs (you can check it by serial debugging).
If in your Arduino project you don’t have threads you can possibly utilize the fact if the ‘loop()’ is handled by a hardware interrupt: I can imagine a working scenario where you have a ‘while’ loop (with some delay() if needed) in the ‘main()’ function that is handling the Http stuff, while you have the GUI in the ‘loop()’ that is probably a timed interrupt. I guess it doesn’t matter if the GUI update (lv_timer_handler) periodically interrupts the Http functions which are not synchronous and timed less strictly. So summarizing: Try having Http stuff into a while() function of main(), GUI update stuff into loop() as normally…