Write in front
"No silver Bullet" is a classic paper on software engineering published by Fred Brooks in 1987. The main argument of this paper is that there is no one technology or method that can increase the productivity of software engineering by 10 times times within 10 years. In the field of Web development, because JavaScript has a lot of problems that are inherently impossible to solve, is there a silver bullet that solves JavaScript ills?
Talk about JavaScript development history
As a language designed for only 10 days, Brendan Eich must have imagined that JavaScript would evolve from a simple "script" to a WEB development master, and penetrate into desktop or mobile client development and even server-side development. The reason JavaScript is so hot, even with the famous Atwood law, is that "any application that can be implemented using JavaScript will eventually be implemented in JavaScript", mainly because of two points:
The WEB application can replace the traditional client application more and more;
The JavaScript engine's computational speed has improved dramatically.
From a dialectical point of view, the above two views are actually mutual influence, mutual promotion of the relationship. The gradual increase in the speed of the JavaScript engine has led to a part of a simple client application that can be replaced by Web applications, so that both users and developers want more complex client applications to be implemented in the web, which further increases the speed of JavaScript engine operations.
The Google V8 engine is a phenomenon-level project that improves the performance of JavaScript engines. V8 was released in 2007, with the introduction of JIT (just-in-time) technology, the V8 engine can compile JavaScript code before it runs into a machine language, so the speed of operation will be greatly improved. The objective problem is that the performance requirements of developers are almost endless, and the performance of JIT-based design ideas has been gradually excavated to the limit, and gradually exposed some difficult problems to solve. The first is the performance bottleneck known as "re-optimization". The prerequisite for compiling to machine code is that the compiler must clearly know the type of the variable, but JavaScript is a weakly typed language, as shown in the following code:
function sum (A, b) { return a + b;} SUM ("1", "2");
V8 Engine When running this code, when the first call to the SUM function, because the type of the pass is two numbers, so the sum of the function is set to a numeric type and compiled into a machine code, but then the SUM function passed the string type, which causes the compiler to speak only the sum of the newly compiled The function is disassembled and then re-compiled into a machine code of type string of the parameter type. This situation greatly reduces the performance of JavaScript.
The second is that some of the compiler's optimization strategies may be "self-defeating", leading to a negative impact on performance in specific situations. A typical example is the TypeScript compiler's performance optimizations when compiling code:
https://github.com/Microsoft/TypeScript/pull/10270 This optimization can be seen by adding a delete operation to an object, forcing the object's "hidden class" mechanism to be closed, and switching an object to dictionary mode. To achieve the performance improvement role.
Again, JavaScript has a garbage collection mechanism, although the V8 compiler has done a lot of optimization of the algorithm of garbage collection mechanism, but in the application of large memory consumption, the instantaneous garbage collection still has a lag phenomenon, which leads to the possibility of a complex application of the occasional lag phenomenon. These problems reflect the flexibility of the language mechanism itself, which restricts the performance optimization of the JavaScript engine, and if you want to solve this problem completely, you must abandon the JavaScript language itself. With a strong type of programming language to achieve the most extreme performance, under the guidance of this technology, WebAssembly technology emerged.
When it comes to WebAssembly, it is inevitable to mention the asm.js that has a profound impact on it, a new technology that Mozilla introduced in 2013, a subset of JavaScript that discarded a lot of the syntax that would cause performance problems and was designed to be Compile builds instead of manually writing Asm.js code. The sum function above is shown in Asm.js as:
function sum (A, b) { a = a | 0; b = B | 0; return (A + b) | 0;}
In the code above, the standard JavaScript engine parses it and produces the correct results, while Asm.js declares the type of the variable based on some special identifiers that do not result in a computed error at run time (for example, a = a | 0 means that the variable A is an integer, and in this way, the code can achieve high performance on the JavaScript engine that supports asm.js, and it will continue to execute in the correct logic on unsupported devices rather than running. Despite this, asm.js still has some problems, mainly based on the JavaScript syntax of text Format parsing is not fast enough, and the size of the code is large, in order to solve these problems, the asm.js for binary WebAssembly came into being.
What is webassembly?
WebAssembly is a cross-platform binary format that is close to the machine language. In March 2017, the four major browser makers, Google Chrome, Apple Safari, Microsoft Edge and Mozilla FireFox, both announced that the original version of WebAssembly was supported in the latest version of the browser, which means The WebAssembly technology has actually landed and can be tried in a specific production environment. WebAssembly can now be generated through the Emscripten SDK, which is the WebAssembly compiler principle:
Shows how to generate WebAssembly content by writing C/C + + code.
- First, the C + + source code is compiled into LLVM bytecode through LLVM. This is a cross-language underlying virtual machine bytecode, in theory all strongly typed programming languages can generate this bytecode. It can be learned that in the future, all strongly typed programming languages (such as java/c#, etc.) can develop WebAssembly programs.
- This abstract bytecode is then generated in asm.js format by the backend compiler in Emscripten. This is a special JavaScript code that some JavaScript engines will run faster than usual JavaScript code, and since Asm.js is still JavaScript, even if the JavaScript engine does not support the special Also run this logic in the usual way. This means that the source code written in C + +, even if the user device does not support WebAssembly, can be rolled back to JavaScript to run and get consistent results.
- Again Asm.js will be born into WebAssembly. wasm file through another compiler, because WebAssembly is a binary format, its code volume is much smaller than JavaScript, and because it is already a machine-oriented format, It also eliminates the need to JIT-compile the source code before it runs.
As can be seen from the above, WebAssembly can theoretically be generated by any strongly typed language, without forcing the user to rely on the local running environment, the code size is small, the resolution is fast, almost the future of the Web development of a "silver bullet." Unfortunately, at this stage, WebAssembly still has a lot of problems to be solved.
- The first is its own stability, in the case of Chrome, Chrome 57 supports the MVP version of WebAssembly, but on Chrome 58, a large number of WebAssembly programs directly cause the process to crash, although subsequent chrome 59 has been repaired Most of the problems, but still have to maintain the stability of the current version of the attitude.
- Next is the debugging, WebAssembly is designed for an open, can be debugged program, but at present, whether it is Chrome or FireFox, debugging there is still a lot of room for improvement. Because it is difficult to debug at the current stage, writing business logic code with WebAssembly is still inconvenient for research and development.
There is also interoperability with the WEB. At present WebAssembly similar to Webworker, can only carry on the simple numerical computation work, cannot operate the DOM node directly in the C + + layer. While the future roadmap mentions that this feature will be added later, at this stage WebAssembly is better suited for more purely intensive data computing rather than writing business logic directly.
To sum up, at this stage, WebAssembly is not suitable for writing specific business logic directly, but is better suited to writing libraries with high performance requirements in applications, communicating with JavaScript-written business logic, and manipulating DOM nodes on the JavaScript side. As an example of the new Egret Engine 5.0 rendering library developed by the author, The Egret engine provides JavaScript APIs to the outside, and the JavaScript logic code compiled by the developer is aggregated into a set of command queues sent to the WebAssembly layer, and then WebAssembly Responsible for all of the calculations, eventually generating a set of data streams based on the WEBGL format, and finally JavaScript simply parses the set of data streams and directly invokes the DOM's WebGL interface to pass the data.
In the course of practice, we summarize several advantages and disadvantages of WebAssembly which are not easy to pay attention to:
-
Code is very small, we will be about 300k (compressed) JavaScript logic instead of WebAssembly rewrite, the volume only about 90k. While the use of WebAssembly requires the introduction of a 50k-100k JavaScript class library as an infrastructure, the overall advantage of resource sizing is significant.
-
Because the code format is binary, it is not possible to see the source directly in the browser, although in theory can still be reverse engineering to some extent the original business logic, but because developers can compile with the use of-O3 and other aggressive optimization strategies, So the final anti-compilation business logic is also difficult to read. While theoretically everything in the client's content is unsafe, code security has improved significantly compared to the direct exposure of all code to the user.
-
When running extreme tests such as benchmark, the game engine uses WebAssembly to be no more geometric than JavaScript. The author's inference is that because the JIT mechanism of the JavaScript engine will optimize the compilation of the functions that are run frequently, in the test environment of benchmark, whether it is the JavaScript version or the WebAssembly version, the code is executed in a large number of iterations. It runs highly optimized machine code, although the WebAssembly version still has some performance advantages over the JavaScript version, but it's not obvious.
-
When running business logic code, because most of the business logic code runs only once, so the JavaScript engine will only make this part of the Code simple compilation optimization rather than limit optimization, so run this part of the code WebAssembly compared to The JavaScript version is a great boost, but because of the above, it is not recommended that developers use WebAssembly when writing business logic, so there is a dilemma here. Ideally, in addition to the underlying library, some of the key logic involved in performance issues can be written using WebAssembly.
In summary, so far because WebAssembly is not very perfect, so its main role is as a useful complement of JavaScript ecology, and JavaScript coexistence rather than replace. But through its roadmap, we can tell that WebAssembly's design ideas are excellent, and all the existing problems can be solved in the long run. In addition to WebAssembly is very rare by the big four browser manufacturers jointly announced that will be strongly supported and implemented features, its browser compatibility issues can be resolved, and then step back, even if the old browser does not support, because WebAssembly support fallback to JavaScript, can also be guaranteed to operate normally.
At this stage, the WebAssembly is suitable for a large number of dense computations and does not require frequent data communication with JavaScript and DOM. such as game rendering engine, physics engine, image audio and video processing editing, encryption algorithm and so on.
The author believes that WebAssembly, like the original HTML5 standards, after the announcement is not a lot of people at first, think there will be browser compatibility issues, the implementation of major browser vendors, performance issues, user needs and user experience issues, but in recent years HTML5 has finally been widely used , even some people think he can replace Nativeapp in many scenarios, rather than just the small goal of "replacing Flash" that year. With the leap-forward development of the underlying technology and the unanimous support of browser vendors, WebAssembly will surely have a bright future, and may really be a "silver bullet" for Web development.
Transferred from: Http://www.infoq.com/cn/news/2017/07/WebAssembly-solve-JavaScript
Webassembly is a silver bullet that solves JavaScript's ills?