Why is my WiFi WebServer so slow?

Hello there!

I’m running a WiFi WebServer on my WeMos - D1 R2. Code is almost identical to the example, just changed a few minor things that can’t have any effect on speed.

I made a React Native app that requests the /on or /off url depending on which buttons is pressed.

What happens? Well…

Sometimes (rarely), the server responds within a second. Mostly, it takes from 5 - 10 seconds for the server to respond and sometimes, the server won’t even respond to the request.

What going on here? How can I fix this so that the server will respond within a second to the request?

Code:

#include <ESP8266WiFi.h>

const char* ssid = "your-ssid";
const char* password = "your-password";

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);

  // prepare LED
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected!");
  
  // Start the server
  server.begin();
  Serial.println("Server started!");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
  // Wait until the client sends some data
  Serial.println("New client!");
  while(!client.available()){
    delay(1);
  }
  
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
  
  // Match the request
  int val;
  if (req.indexOf("/off") != -1)
    val = 0;
  else if (req.indexOf("/on") != -1)
    val = 1;
  else {
    Serial.println("Invalid request...");
    client.stop();
    return;
  }

  // Set LED according to the request
  digitalWrite(LED_BUILTIN, val);
  
  client.flush();

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nLED is now ";
  s += (val)?"high":"low";
  s += "</html>\n";

  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");

  // The client will actually be disconnected 
  // when the function returns and 'client' object is detroyed
}

Have you tried a network sniffer to see at what protocol step the delay occurs?

Good idea, I'll try that. WireShark would be perfect for this, right?

I never used it so I'll paste the results here for people to analyze since I don't know what to look for.

Yes, Wireshark would be a good tool. I would look at the message timestamps to see what messages are taking a long time getting a response or messages that are repeated many times because they weren't acknowledged.

Why does your response contain and but no head or body tags?

What are the client.flush(); supposed to do?

If you use a web browser to talk to your server, do you see the same delays?

( I would dump all those Strings you use. Also client.readStringUntil() has a built in timeout)

You can also embed something like:

Serial.print ("id=XXX. millis() = ") ;
Serial.println( millis() ) ;

throughout your web server code to see what is taking the time.

The structure of response has nothing to do with performance.

I fixed it. The problem was that the connection between the client and server didn't close properly since the connection was being kept alive in the example (using the API in my app). At the end of the loop, I added a client.stop() that forces the connection to close and now it works perfectly.