This website demonstrates how a $5 ESP32 microcontroller can efficiently serve a fully functional, compressed, and optimized webpage with no external storage. It demonstrates techniques like minifying resources, using image sprites, and leveraging a reverse proxy for encryption, showcasing the ESP32's potential as a web server.
The page you're on now is being served by a tiny $5 ESP32, a remarkably efficient microcontroller that consumes only around 200 milliamps at 3.3 volts, which translates to about half a watt of power. Despite its low power consumption, the ESP32 is a surprisingly capable device, especially when used in projects where energy efficiency and compactness are key. In this case, it's being used to serve a full-fledged website directly from its flash memory, demonstrating how powerful and versatile these small, low-cost microcontrollers can be.
Notably, there is no SD card or external storage involved in this setup. Everything required to serve the webpage is stored directly in the ESP32's flash memory. This approach eliminates the need for additional components and keeps the overall system simple, compact, and cost-effective. To manage this limited storage space, I chose not to use a file system, which would have introduced overhead, but instead opted to compile all the necessary resources—HTML, JavaScript, and CSS—directly into the flash. This method also allows me to tightly control the size of the resources being used.
To ensure that the webpage fits within the constraints of the ESP32's flash, I take several steps to minimize the size of the resources. For example, I "minify" the HTML, stripping out unnecessary whitespace and comments, which significantly reduces the file size. Additionally, I include JavaScript and CSS inline within the HTML file, further reducing the need for multiple external files. To make it even more efficient, I pre-compress the HTML file using gzip compression before embedding it into the C++ class that will be written to flash. This careful optimization allows me to fit all the required resources into a very small space, demonstrating the power and flexibility of this tiny 32-bit microcontroller.
For handling images on the webpage, I use an approach where all images are packed into a single graphic file, and CSS is responsible for rendering just the portion of the graphic that needs to be displayed. This technique, often referred to as "sprites," is a way to optimize resource usage. Instead of storing individual image files or using up flash space with multiple separate image assets, the ESP32 only needs to deal with one large image. The CSS simply defines which section of the image should be displayed at any given time, significantly reducing memory requirements and improving performance. This makes it easier for the ESP32 to manage graphics while still providing a visually rich user experience. SVG images are rendered inline, further reducing resources.
The current architecture of the web server can handle around 5 to 10 concurrent connections comfortably. This is sufficient for many use cases, but there's room for improvement. I'm considering switching to an asynchronous server model to handle more simultaneous users—potentially scaling up to 100 or more concurrent connections. This would be an interesting challenge, but with the ESP32's processing power and the right optimizations, it's certainly achievable. The asynchronous server would allow the ESP32 to serve multiple requests in parallel without blocking, making the server more responsive and able to handle a larger number of connections at once.
While the ESP32 itself doesn't directly handle encryption, you may have noticed that the webpage is served over HTTPS. This is because I've set up the ESP32 in a reverse proxy configuration, where an Apache server handles the SSL/TLS encryption and takes care of the HTTP/2 and HTTP/3 protocols. This offloading allows the ESP32 to focus on serving the content, while Apache handles the more resource-intensive aspects of encryption and modern web protocols. Of course, it's possible to use the ESP32 as a web server without a reverse proxy, but this setup ensures a more secure and scalable solution, especially for production environments.
In conclusion, this project serves as a proof of concept to demonstrate the remarkable capabilities of the ESP32 as a web server. While this particular implementation is simple and compact, it showcases how a tiny, low-cost microcontroller can serve a fully functional, encrypted, and optimized website. The combination of efficient memory usage, compression, and a minimalistic architecture makes the ESP32 an ideal candidate for small-scale web server applications.
In the future, I plan to add more functionality to this website to further demonstrate the ESP32's real-world potential, such as adding dynamic content or integrating with IoT devices. If you're interested in exploring how the ESP32 can be used as a web server or have any questions about the project, feel free to reach out.
Return to jgilmore.com.