It was surprisingly easy finishing up my RetroArch port to the web, thanks to Emscripten and all the hard work in that. And making it easier for programs to get on the web is a good thing. However, during my journey, I ran into more than a couple issues and learned more than a couple discouraging facts that make me think twice about the great future of full-blown programs on the web.
A lot of the tech is still very very young
Doing things the “not-Web” way is bad, but it works better
One thing I learned very quickly: blocking the event loop is bad. Very very very VERY bad. It’s so bad. Never do it. No reason to ever do it. But it’s the only way to do some things.
You are at the mercy of the event loop
The event loop is 100% unpredictable. It also must be hit to do anything involving input/output. Video needs it to display, input needs it to capture events, and audio needs it to play. I tried to implement an audio callback method to avoid blocking on audio, but the callback fired at intervals that were in no way predictable, from one time up to five times every 20 milliseconds. That and trying to put calls to “requestAnimationFrames” is spotty at best. Hoping to get a stable 60FPS off of it is an exercise in futility. Most of these issues are not issues for something like a video or a normal game: Audio can be queued and you can play individual samples instead of streaming. For emulators, there is no alternative, and the tools the web platform has right now do not help. They have to be worked around to get a program that performs well.
What can be done?
The first thing that can be done is to make the browsers behave similarly. Right now Firefox doesn’t have the constantly updating currentTime for Web Audio, and the precision on performance timers on Chrome is really odd. These can be fixed (or a consensus agreed upon).
For more performance-heavy things, there needs to be a way to either get around the event loop or control it better. The yield keyword in ES6 is a nice first step, but there needs to be a way to guarantee (or at least make a better attempt) a callback or timer to happen when it should. Even better would be a way to start a thread separate from the main loop. Can Web Workers be used for this? Not sure, but probably not with any audio/video output which makes it a no-go for us. Maybe some new tech can allow this in browsers. A pipe dream perhaps, but hey, it’ll probably be better than NaCl in the long run.