To deviate a bit from the main thread, it is incredible how they managed to make Android NDK that bad.
On my case, when using it I sometimes even get the feeling "this used to be better with Symbian", clunky as it was.
And the time they take to create any improvements to it, it looks like NDK is a 20% project from Android team, that we should be thankfull it even exists to start with.
- Working with the NaCl toolchain was pretty painful compared to Emscripten. While Emscripten always tried hard to integrate as easily as possible into existing build infrastructures, NaCl was more like the Android NDK (the NIH seemed to have been pretty strong in the NaCl team).
- Likewise the integration between the Javascript side and the NaCl side: much better solved in Emscripten (especially with the ability to embed Javascript snippets into C/C++ source code, IFIR NaCl used message passing instead of being able to call directly into the JS side)
- NaCl used its own set of "system APIs" which was both good and bad, good because those APIs usually didn't have the limitations of browser APIs, bad because it was quite painful and slow to talk to browser APIs for areas that were not covered by the "builtin APIs" (and that was everything except 3D rendering, audio and networking).
- WASM still hasn't caught up with PNaCl with the "it simply works" multithreading, I'm not sure how Spectre/Meltdown would have affected NaCl though.
- The actual 'wire format differences' were always overrated, apart from a few edge cases the performance differences between asm.js, WASM, NaCl and PNaCl were quite small (the difference between NaCl and PNaCl was that NaCl was a "safe subset" of native CPU instruction sets (so you'd need different NaCl modules for running on x86 vs ARM), while PNaCl was a portable LLVM-IR derived byte code format - also once NaCl switched to PNaCl, the startup time was actually a lot slower than WASM).
All in all, my lasting impression of PNaCl is "at least it wasn't as bad as the Android NDK" ;)