I did not intend to propose base64, I just wanted to point out the approach.
More is to say: Reading strings form
require("Storage").... has the advantage of being mapped until pulled and is perfect for streaming; see transferring files using special setup for Transferring large amounts of data on https://www.espruino.com/Internet. With that the application can control how big the memory chunk is to be. At best, it could be that no RAM - or just for control - is used because some DMA was in discussion, and that could move data directly from flash to http transmit buffer. I do not know the internals, but streaming is for sure the way to go.
Next thing is, @Julian1, do you really need to serve everything from Espruino? UI infrastructure stuff can be pulled from anywhere and when you are on the www, only essentials have to be delivered from Espruino device and all the other stuff comes from a regular server, even from Google or so... For an example take a look at poast about Shiny Web UIs - you can check out the whole conversation and conversation related to this.
A different approach is to just ship the data to a mid tier Web and App server stack using mqtt. A flavor of that can be boot the app from that Web and App server and the connect only for the data directly (triangle) using pull / push-pull / long-polling...