From embarrassing 30s to consistent 90s on Lighthouse - this is the story of performance optimization gone wrong, then right. What started as a typical modern web stack became a journey of unlearning, where an accidental JavaScript-free deploy revealed that sometimes less is more.
I don’t even want to think about how much time and electricity is getting wasted each day because of all these massively bloated websites and webapps. Modern computers are insanely fast, yet webapps sometimes take more than 10 seconds to start up on a good day.
Personally I like my WebApps in C89
/* app.c */#include<stdlib.h>#include<stdio.h>#include<string.h>#include<unistd.h>#include<netinet/in.h>#include<sys/socket.h>#ifdef __linux__#include<linux/net.h>/* For SO_REUSEPORT */#endif#define LISTEN_PORT 9000#define REQUEST_TYPE_UNKNOWN 0#define REQUEST_TYPE_GET 1staticconstchar *html_main = (
"<!DOCTYPE html>""<html>""<header>""<title>My first Web App</title>""</header>""<body>""<h1>Hello World</h1>""</body>""</html>"
);
staticsize_t html_main_length;
staticvoidhttp_reply(int cl_sock_fd,
constuint16_t status,
constchar *status_msg,
constchar *mimetype,
constsize_t content_length){
char buffer[0x400];
int length;
length = sprintf(
buffer,
"HTTP/1.1 %u %s\r\n""Content-Type: %s\r\n""Content-Length: %lu\r\n""\r\n",
status,
status_msg,
mimetype,
content_length
);
write(cl_sock_fd, buffer, length);
}
intmain(void){
int32_t sv_sock_fd, cl_sock_fd;
structsockaddr_in sv_addr, cl_addr;
socklen_t cl_addr_size;
uint32_t option;
char *input_buffer;
size_t input_length, input_buffer_length;
uint8_t request_type;
memset(&sv_addr, 0, sizeof(sv_addr));
sv_addr.sin_family = AF_INET;
sv_addr.sin_addr.s_addr = INADDR_ANY;
sv_addr.sin_port = htons(LISTEN_PORT);
sv_sock_fd = socket(sv_addr.sin_family, SOCK_STREAM, 0);
if (sv_sock_fd == -1)
{
perror("Unable to create server socket");
return EXIT_FAILURE;
}
/* Tell it to re-use the address and port... */
option = 1;
if (setsockopt(sv_sock_fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)))
{
close(sv_sock_fd);
perror("Unable to setsockopt on socket");
return EXIT_FAILURE;
}
if (setsockopt(sv_sock_fd, SOL_SOCKET, SO_REUSEPORT, &option, sizeof(option)))
{
close(sv_sock_fd);
perror("Unable to setsockopt on socket");
return EXIT_FAILURE;
}
if (bind(sv_sock_fd, (struct sockaddr *)&sv_addr, sizeof(sv_addr)))
{
close(sv_sock_fd);
perror("Unable to bind socket to address");
return EXIT_FAILURE;
}
if (listen(sv_sock_fd, 0))
{
close(sv_sock_fd);
perror("Unable to listen on socket");
return EXIT_FAILURE;
}
input_buffer_length = 0x400;
input_buffer = malloc(input_buffer_length);
if (!input_buffer)
{
close(sv_sock_fd);
perror("input_buffer == NULL");
return EXIT_FAILURE;
}
html_main_length = strlen(html_main);
cl_addr_size = sizeof(cl_addr);
printf("Waiting for new connections on port %u ...\n", LISTEN_PORT);
while (1)
{
cl_sock_fd = accept(sv_sock_fd, (struct sockaddr *)&cl_addr, &cl_addr_size);
if (cl_sock_fd == -1)
{
perror("Error when accept()ing");
break;
}
request_type = REQUEST_TYPE_UNKNOWN;
input_length = 0;
/* Read from the client */while (read(cl_sock_fd, input_buffer + input_length, 1) > 0)
{
if (input_length >= input_buffer_length)
{
input_buffer_length += 0x400;
input_buffer = realloc(input_buffer, input_buffer_length);
if (!input_buffer)
{
close(sv_sock_fd);
close(cl_sock_fd);
perror("Failed to realloc() input_buffer");
return EXIT_FAILURE;
}
}
if (input_buffer[input_length] == ' ')
{
if (request_type == REQUEST_TYPE_GET)
{
printf("GET request: %.*s\n", (int)input_length, input_buffer);
if (strncmp(input_buffer, "/", input_length) == 0)
{
http_reply(cl_sock_fd, 200, "OK", "text/html; charset=UTF-8", html_main_length);
write(cl_sock_fd, html_main, html_main_length);
break;
}
http_reply(cl_sock_fd, 404, "Not Found", "", 0);
break;
}
if (strncmp(input_buffer, "GET", input_length) == 0)
{
request_type = REQUEST_TYPE_GET;
input_length = 0;
continue;
}
break;
}
++input_length;
}
close(cl_sock_fd);
}
free(input_buffer);
close(sv_sock_fd);
return EXIT_SUCCESS;
}
To compile on a UNIX-like system: $ cc -o app app.c -std=c89 -Wall -Wextra
I don’t even want to think about how much time and electricity is getting wasted each day because of all these massively bloated websites and webapps. Modern computers are insanely fast, yet webapps sometimes take more than 10 seconds to start up on a good day.
Personally I like my WebApps in C89
/* app.c */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <sys/socket.h> #ifdef __linux__ #include <linux/net.h> /* For SO_REUSEPORT */ #endif #define LISTEN_PORT 9000 #define REQUEST_TYPE_UNKNOWN 0 #define REQUEST_TYPE_GET 1 static const char *html_main = ( "<!DOCTYPE html>" "<html>" "<header>" "<title>My first Web App</title>" "</header>" "<body>" "<h1>Hello World</h1>" "</body>" "</html>" ); static size_t html_main_length; static void http_reply(int cl_sock_fd, const uint16_t status, const char *status_msg, const char *mimetype, const size_t content_length) { char buffer[0x400]; int length; length = sprintf( buffer, "HTTP/1.1 %u %s\r\n" "Content-Type: %s\r\n" "Content-Length: %lu\r\n" "\r\n", status, status_msg, mimetype, content_length ); write(cl_sock_fd, buffer, length); } int main(void) { int32_t sv_sock_fd, cl_sock_fd; struct sockaddr_in sv_addr, cl_addr; socklen_t cl_addr_size; uint32_t option; char *input_buffer; size_t input_length, input_buffer_length; uint8_t request_type; memset(&sv_addr, 0, sizeof(sv_addr)); sv_addr.sin_family = AF_INET; sv_addr.sin_addr.s_addr = INADDR_ANY; sv_addr.sin_port = htons(LISTEN_PORT); sv_sock_fd = socket(sv_addr.sin_family, SOCK_STREAM, 0); if (sv_sock_fd == -1) { perror("Unable to create server socket"); return EXIT_FAILURE; } /* Tell it to re-use the address and port... */ option = 1; if (setsockopt(sv_sock_fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option))) { close(sv_sock_fd); perror("Unable to setsockopt on socket"); return EXIT_FAILURE; } if (setsockopt(sv_sock_fd, SOL_SOCKET, SO_REUSEPORT, &option, sizeof(option))) { close(sv_sock_fd); perror("Unable to setsockopt on socket"); return EXIT_FAILURE; } if (bind(sv_sock_fd, (struct sockaddr *)&sv_addr, sizeof(sv_addr))) { close(sv_sock_fd); perror("Unable to bind socket to address"); return EXIT_FAILURE; } if (listen(sv_sock_fd, 0)) { close(sv_sock_fd); perror("Unable to listen on socket"); return EXIT_FAILURE; } input_buffer_length = 0x400; input_buffer = malloc(input_buffer_length); if (!input_buffer) { close(sv_sock_fd); perror("input_buffer == NULL"); return EXIT_FAILURE; } html_main_length = strlen(html_main); cl_addr_size = sizeof(cl_addr); printf("Waiting for new connections on port %u ...\n", LISTEN_PORT); while (1) { cl_sock_fd = accept(sv_sock_fd, (struct sockaddr *)&cl_addr, &cl_addr_size); if (cl_sock_fd == -1) { perror("Error when accept()ing"); break; } request_type = REQUEST_TYPE_UNKNOWN; input_length = 0; /* Read from the client */ while (read(cl_sock_fd, input_buffer + input_length, 1) > 0) { if (input_length >= input_buffer_length) { input_buffer_length += 0x400; input_buffer = realloc(input_buffer, input_buffer_length); if (!input_buffer) { close(sv_sock_fd); close(cl_sock_fd); perror("Failed to realloc() input_buffer"); return EXIT_FAILURE; } } if (input_buffer[input_length] == ' ') { if (request_type == REQUEST_TYPE_GET) { printf("GET request: %.*s\n", (int)input_length, input_buffer); if (strncmp(input_buffer, "/", input_length) == 0) { http_reply(cl_sock_fd, 200, "OK", "text/html; charset=UTF-8", html_main_length); write(cl_sock_fd, html_main, html_main_length); break; } http_reply(cl_sock_fd, 404, "Not Found", "", 0); break; } if (strncmp(input_buffer, "GET", input_length) == 0) { request_type = REQUEST_TYPE_GET; input_length = 0; continue; } break; } ++input_length; } close(cl_sock_fd); } free(input_buffer); close(sv_sock_fd); return EXIT_SUCCESS; }
To compile on a UNIX-like system:
$ cc -o app app.c -std=c89 -Wall -Wextra