Thanks to the browser war, the JS engine of the mainstream browser has introduced various optimization technologies, and the news that the performance of certain browser has been greatly improved from time to time also makes the front end students more confident. So has the JS language itself reached a level close to native?

Train of thought

We know that JavaScript today is essentially a scripting language, even with the introduction of higher-level compilation techniques like the JIT. Not to mention languages like C/C++ that can compile to native machine code, the runtime of JavaScript is not superior in principle even when compared to Java that uses bytecode. So the question arises, how to quantify the JS speed and native language gap?

There are many benchmarks for Todo MVC in the front-end framework space, and the way they compare can be simply interpreted as comparing the performance of different frameworks that implement the same functionality. Of course, this is feasible and easy to quantify, but different coding implementation and construction techniques may significantly change the running score data (such as whether to enable the React optimization plug-in), and the Todo MVC scenario is basically limited to adding, checking, modifying and deleting data, which is not a complex application in real scenarios.

Noting that many programming languages can compile to JavaScript today, we chose another approach: comparing the performance of the native and JavaScript versions of real-world applications. Also, with Web Assembly as a standard, the opportunity to compare the performance of native code, WASM, and JS looks even more interesting.

How do you choose the application to test? We need computationally intensive scenarios to squeeze out on-the-go performance, and the most common examples of this are games and multimedia processing. We chose FFmpeg, one of the oldest names in video coding, and built it into WASM and JavaScript to test the speed at which different versions of it could encode video to get a performance comparison of native, WASM, and JS.

Process and Results

We want to compare how fast the three FFmpeg builds encode video using the default configuration:

  • native
  • The JavaScript version
  • WASM version

The input file for the test is the Demo video attached to FFmpeg (videoConverter. JS library) of THE JS version, and the test platform is the 2015 beggar MacBook Pro.

native

Homebrew installed version:

time ffmpeg -i bigbuckbunny.webm output.mp4
Copy the code

Transcoding takes about 6s.

The JavaScript version

Videoconverter.js comes with an out-of-box static Demo page where you can transcode video. Select Video to.mp4 to output. Transcoding takes about 140s.

WASM version

The WASM version of FFmpeg does not have a stable release from the community. Here’s how this column is built: after installing Emscripten, compile FFmpeg from source to WASM and use the ffmPEg.wasm for transcoding.

After compiling a C application into WASM, we can choose to use it in Web Workers. Simply pass the original command line argument in a different format:

ffmpeg({
  arguments: [
    '-i'.'/input/demo.mp4'.'out.mp4'
  ],
  files
}, function (results) {
  self.postMessage(results[0].data)
})
Copy the code

The time required is about 24 seconds.

conclusion

Significant performance differences were observed:

In this computation-intensive scenario, JavaScript performance is about 1/20 of native performance, while WASM performance can be about 1/4 of native performance (again, this is just a conclusion for this scenario, not general-purpose).

But this data is for reference only, because there are many implicit pits throughout the link. To name a few:

  • The indexes of video coding test are greatly influenced by algorithms and parameters. The default configuration based on FFmpeg may not guarantee consistent code paths.
  • When FFmpeg was compiled into WASM, a lot of clipping was done, such as disabling inline platform-specific aggregation encoding, disabling multithreading, and so on. This has an impact on the performance of the final build publication.
  • WASM is often not a multifold performance improvement over native JS. In some cases (such as image processing) where the entire application is not compiled into WASM but instead calls WASM modules with JS, it is expensive to copy data frequently between WASM and JS, and WASM may even perform worse than JS.

Despite these distractions, we’re pretty sure that the performance gap between JavaScript and native can still be orders of magnitude. However, in the current common background, active page, Hybrid and other scenarios, we rarely need to use JavaScript to handle computation-intensive tasks, so it is not easy to become the bottleneck of the entire application.

Hopefully this simple test will give you some insight into how slow JS really is. However, the good news is that from another perspective, mobile JS is no longer as slow as PC JS. If you are interested, please refer to this article.

Finally, relevant resources involved in the paper are listed:

  • FFmpeg documentation
  • videoconverter.js
  • WASM version of the warehouse
  • WASM version sample