(In asm.js, memory was provided by an ArrayBuffer of fixed size, so there memory could truly not grow at runtime.)
If anyone does choose to do this I hope they spend significant amount of effort making their caching and code splitting optimal.
Many devs already make me download their SPA to display static text and images.
You could still use JS while Python support catches up.
There have been several libraries that provide the concept of a promise, but with modern python these are built into the stdlib with native async/await support, though many interfaces are still sync-only (though you can work around that with things like gevent that monkey-patch those interfaces to work with an event loop under the hood).
I agree that python would be a poor fit for the kind of uses that JS in the browser usually serve, but it's really a matter of ecosystem, not core language design.
What they can do is to provide GC to unbloat a lot of those runtimes I guess.
the hard part at the time was obviously all the hooks between the dom and the javascript runtime as well as concurrency story. python 2 was not built to be driven by callbacks, which is how the whole browser/javascript ecosystem works.