1- When compiling Blink for a Mega, the upload is 20 KB. For the ESP32, the Blink upload (uncompressed) is 240 KB. And the compile and uploading are proportionally that much slower too.
Now I understand that the firmware gets re-flashed everytime you upload. If Blink and the libraries are 8 KB, and thus the firmware for the Mega is 12 KB, then the firmware for the ESP32 is approximately 230 KB. This does not sound right. So what is all this bloatware in an ESP32 upload and how can it be eliminated?
The upload for OTA webserver is 800 KB! Doesn’t leave much room for the code.
2- Is there a way to make the ESP32 call a function right before it reboots or uploads, to do some housecleaning or EEPROM saving?
3- What is Examples -> ArduinoOTA -> BasicOTA ?
When you use OTA, it creates a partition with a fixed size of 8kB to handle over-the-air updates. You still have space for code.
I think this article explains well how partitions work: https://blog.espressif.com/how-to-use-custom-partition-tables-on-esp32-69c0f3fa89c8
The basic OTA example uploads code over the air via Arduino IDE, without the need for a web server.
My guess is the ESP32 base includes all of the libraries required for all of the peripherals on board (ie. WiFi, Bluetooth etc) whereas the mega has no such peripherals.
You could try recompiling the base ESP32 removing all of the code it uses for those items OR try adding all of those libraries to the mega blink code and see how large it is.