New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webassembly integration. Split the core into two parts. #8193

Open
o-alexandrov opened this Issue May 16, 2018 · 28 comments

Comments

Projects
None yet
@o-alexandrov
Copy link

o-alexandrov commented May 16, 2018

What problem does this feature solve?

Performance improvements.

What does the proposed API look like?

Split the core into two parts:

  • JS. Keep doing what you are already doing with the framework.
  • Webassembly. Experiment with the syntax sugar walt to have compiled JS core in .wasm
    • I read other closed issues on this topic and saw:

      This is like building a completely new framework (with similar syntax) - definitely not something the core team is interested in / have bandwidth for, but I wouldn't discourage anyone interested to try.

    • The syntax sugar, walt, potentially can make the split much-much easier, since it is still JS.

Things to consider:

  • Both JS and Webassembly can be called from each other, so it is time to start mixing parts.
  • Server-side rendering. This is the worst aspect in Vue.js. JSON client-side and server-side bundles is a ridiculous architecture to be honest.
    • If used with serverless-webpack to make a lambda function, there is no optimization possible on the dependencies, such as tree shaking as you are creating .json bundles that are then imported for the render function and webpack is unable to trace what parts of dependencies aren't needed. Therefore, SSR development stage is unfortunately in a very poor condition.
  • SSR is happening on the server-side. Node.js 8 can run .wasm, so that it could have been totally compiled.

Personally, we would start making progress in it ourselves, but there is no incentive for us to start working on it at the moment.
Therefore, it would be great, if there are interested parties in performance improvements in the community, who can dedicate time to it.

@posva posva added the discussion label May 16, 2018

@posva

This comment has been minimized.

Copy link
Member

posva commented May 16, 2018

Just to be clear, this is something we don't have the bandwidth to do yet either. I also think it is too early to have an open discussion on this

Also, sometimes people is really mistaken about the performance vs easy-to-use tradeoff which is very important to Vue as we want to make it easy for people to start using Vue. Web asm is not (yet) going to have such a big impact on performance as the bottleneck (DOM) will still be the same
Not sure why you mention SSR, web assembly is not going to change how the SSR works...

@o-alexandrov

This comment has been minimized.

Copy link

o-alexandrov commented May 16, 2018

@posva
1. SSR is the key here because of:

  • the browser support of .wasm, which is 73% according to caniuse, which could be ignored server-side, hence migrated completely to webassembly.
  • the whole idea of compiling to binary will drop the vue-server-renderer package and other aspects of how it is architected at the moment.
  1. Simplicity:
  • it is only syntax sugar that we are talking about, nothing major.
  • important, keep in mind that JS can be called from Webassembly and vice versa.
    • therefore, absolutely nothing will change for the majority of the users as they will continue to write absolutely the same code.

Webassembly should be triggered on and off based on the browser support on the client-side, where as the server-side should be completely rewritten and the current approach should be dropped.

@o-alexandrov

This comment has been minimized.

Copy link

o-alexandrov commented May 16, 2018

One of the performance examples:
image

I am a strong proponent of serverless architecture, and .wasm could bring extreme performance improvements as well as cost savings.

@posva

This comment has been minimized.

Copy link
Member

posva commented May 16, 2018

That's an expensive face detection algorithm... Its normal to see such an improvement. As I said, the main slow thing is Dom manipulations.
Anyway, feel free to add other points that may be useful

@o-alexandrov

This comment has been minimized.

Copy link

o-alexandrov commented May 16, 2018

I believe there are two things that you should consider:

  1. What makes Vue a better alternative to React and Angular?
  2. A natural webassembly integration might be the key that:
    • brings much more attention to Vue
    • leading to increased community that doesn't move back to react and angular

Imagine React implements it, what would make the community to continue using Vue as it is going to cost much more from the infrastructure perspective (file sizes are much bigger, operates much slower)? Forgetting apps (react-native), thinking only from the web perspective, it could have been a major blow.

There are already talks about React and WebAssembly, so I believe it is important for the community to prepare for the competition that will arise, there is no doubt to it. Hopefully, Vue integrates WebAssembly sooner than later.

@fnlctrl

This comment has been minimized.

Copy link
Member

fnlctrl commented May 16, 2018

Imagine React implements it

From What WebAssembly means for React - Lin Clark aka @linclark at @ReactEurope 2017
"But will it help with the performance with react applications in the browser? The truth is, the short-term immediate impact of this on performance isn't clear." which is the euphemism for "no."

As @posva said, the perf bottleneck is on DOM api, and not javascript itself, nor the virtual dom diffing algorithm. It's meaningless to speed something up that already takes like <10ms to 1ms, while still spending 100+ms on DOM APIs.

Besides, WebAssembly isn't magic and it has great limitations. You can't expect to compile some no-dom-access javascript to it. You can't use objects in wasm. I can barely imagine a JS library to live with that and implement their own objects on top of bytes.

file sizes are much bigger, operates much slower

On the contrary, wasm files are way much larger because it's compiled binary. Thinks of the size of C source code vs compiled executable. You can also check out this true wasm powered UI framework here: https://github.com/aspnet/blazor (which is compiled from C#), and see their demo: https://blazor-demo.github.io/
image

That's >1MB gzipped of all these files. Took 30+ seconds to load. For a bare-to-the-bone app that has a counter and can fetch a json. Truly amazing. Mind blown.

How fast is it? Transitioning from views (from Counter to Fetch Data) still took 36.6ms.
image

The power of wasm lies in boosting CPU-intensive applications, like the face recognition demo you've shared with us. But it does not help with core problem of all UI frameworks: the slowness of native DOM APIs.

@o-alexandrov

This comment has been minimized.

Copy link

o-alexandrov commented May 17, 2018

@fnlctrl

Your reference to a video

You are pointing to a video that is 1 year old, the presenter makes a lot of points that are in the process of changing, most importantly:

  1. No garbage collection => there is ongoing work
  2. No access to DOM API => it is in the list of of the high-level goals

And some of the other ongoing work in a video (27m50s)

Your points

On the contrary, wasm files are way much larger because it's compiled binary.

No, not true. Here is why:

  1. Comparison with an experimental project that is in Alpha stage only from March 22nd, 2018 is strange.
  2. You are stating that source code will weigh less than bytecode. It is false. Everyone on the web states, as well as your referenced presenter, that WebAssembly makes less network overhead, resulting in faster downloading the code, hence performance improvements.
  3. Please take a look here, there is no additional runtime passed over the net or anything like that because it is running absolutely the same as JS => in a VM.

Performance

The power of wasm lies in boosting CPU-intensive applications

Your referenced presenter believes that it runs from 10% to 800% faster. Please keep in mind that it was 1 year ago and WebAssembly is improving on another magnitude than JavaScript (i.e. much faster, since many things need improvements).

I am not an expert in this area, but it doesn't also make sense as games that are GPU-intensive that weren't playable on the web are playable with WebAssembly. There is also WebVR with WebAssembly

Again, nobody tells it is ready or make the switch now. However, if we start making progress now, we will be better off later on, when more optimizations are available, and might happen by the time the initial preparations are made.

It is a question of when, so starting now will help us to have a better understanding and project architecture when DOM access and garbage collection will be available.

@o-alexandrov

This comment has been minimized.

Copy link

o-alexandrov commented May 17, 2018

How could we help this change to happen faster?

I believe JS developers should take a closer look at:

@Becavalier

This comment has been minimized.

Copy link

Becavalier commented May 17, 2018

As @fnlctrl said, the real bottleneck of current JS framework is the cpu consumption on DOM related operations, but this can not be fixed with the current MVP WebAssembly standard.

On the other hand, there will be a lot of overhead when the executing pointer switching between JavaScript and WebAssembly context, and this is another problem you need to concern.

@OlzhasAlexandrov BTW, I think you need to learn more about how dose WebAssembly work, and what is its strength, what kind of frontend situations would be suitable for using current WebAssembly.

Here are some materials for your information:
https://webassembly.org/docs/future-features/
https://webassembly.org/docs/mvp/

Thanks.

@o-alexandrov

This comment has been minimized.

Copy link

o-alexandrov commented May 17, 2018

@Becavalier
You are saying:

On the other hand, there will be a lot of overhead when the executing pointer switching between JavaScript and WebAssembly context, and this is another problem you need to concern.

It should be further analyzed, but the short answer is no, you are incorrect.
Again, it might be true for the exact moment, but logically, if it is not right now, it will be in the future.

Think about it, why would anyone write native node.js addons, if switching between native modules and JS would produce less optimized apps? You would be correct for a task that does almost nothing, but not for anything major.
Here is one of the benchmarks, but you can obviously find more.

Also, you are welcome to watch the talks above, so you could hear once again that mixing JS and WebAssembly isn't a bad thing.

One more point, WebAssembly gained support by Webpack since its 4th version and had gained first class support for more than a year already.

@Becavalier

This comment has been minimized.

Copy link

Becavalier commented May 17, 2018

@OlzhasAlexandrov
Yes, I agree with you that the WebAssembly will change the web, but it's not at current time, it will be in the future after the Post-MVP standard complete.

The overhead between JavaScript context and WebAssembly context would narrow down the application scenarios of current WebAssembly to just only "pure computing" applications, such as: "Graphic Processing" and "Compressing Library" related applications. These apps do not need to frequently switching between those two context environments, so that they can really save a lot cpu consumption and get a good running efficiency with the help of WebAssembly.

But for the frontend frameworks like "vuejs", without the implementation of GC, WebAssembly really can not help a lot. It doesn't need to have that much of math computing even using "virtual DOM" as the wrapper of real DOM, and the "diff" algorithm still have a good performance because of the good implementation of vuejs and the deep optimization of JavaScript engine.

last but not least, the CG and WG member are really trying their best to achieve the Post MVP standard of WebAssembly and also a better LLVM backend for WebAssembly, I think you can look forward to the day that WebAssembly will change the Web, but not now and here.

@webia1

This comment has been minimized.

Copy link

webia1 commented May 17, 2018

WebAssembly & Vue: I think, that’s great discussion, Vue would be the ultimate number one within the js-frameworks! And it is high time to think about it,..

@fnlctrl

This comment has been minimized.

Copy link
Member

fnlctrl commented May 17, 2018

Your referenced presenter believes that it runs from 10% to 800% faster. Please keep in mind that it was 1 year ago and WebAssembly is improving on another magnitude than JavaScript (i.e. much faster, since many things need improvements).

I don't see any of Chrome/FF/Edge's recent release notes stating anything about vast performance improvements of wasm. Specs have changed, but they're just specs and not actual implementations.

Also, the "performance" you're talking about here is off the point. WASM is fast, there's no doubt about that, but "10% to 800% faster" without proper context is meaningless. As many have pointed out, wasm doesn't speed up DOM APIs. Giving WASM dom access doesn't help that either, it just removes the context switch overhead, and DOM APIs are still going to be slow.

Comparison with an experimental project that is in Alpha stage only from March 22nd, 2018 is strange.

That is the only fully functional wasm UI framework, as of today. The latest release is March 22nd, 2018 shows exactly that is still under development and could have taken advantage of those "wasm improvements" you've talked about. Please enlighten me with another one that's better than blazor, as an real world example of wasm UI framework, and not "experimental".

Everyone on the web states, as well as your referenced presenter, that WebAssembly makes less network overhead, resulting in faster downloading the code, hence performance improvements.

So far, what you've referenced are all "talks" and "specs". Everything can look good on paper until someone actually tried to build things with it. If you would, please show us at lease one concrete example of wasm providing great performance boost and size reduction, for building a simple SPA (which requires calling DOM APIs).

Let me propose a better question:
Ever since that 1-year-old talk, if wasm is really so good for ui frameworks, has any of React/Angular announced a wasm rewrite plan for their core?

@GeertArien

This comment has been minimized.

Copy link

GeertArien commented May 18, 2018

Without getting mixed in this discussion, I just came across this thread by accident and don't have a clue if WASM makes any sense for this project, I just want to add my two cents. We're currently in the process of migrating a fairly large project from asmjs to WASM, so I'm actively following WASM performance in browsers. And what was said about there being no performance improvements in browsers is just straight up wrong.

For example take this bug-ticket for Firefox60, this bug-fix increased the performance of our app twofold in FF! Yet it doesn't show up in the FF release notes. Word of advise, instead of checking browser release notes check the release notes of the javascript engines, as that's where the performance increases are implemented. And also check the ticket trackers, if they are publicly available.

Then there's also stuff like streaming compilation that was recently added to firefox and chrome, without much fanfare.

Also, and I don't know if this is relevant to this project, but react-native-dom was just announced at React-Europe, with layout powered by WASM.

@nnodot

This comment has been minimized.

Copy link

nnodot commented May 18, 2018

I find this topic very interesting as I am interested in both wasm and Vue.js!

First, a bit of context. I have actually used wasm for a real world use case: viewing very big JPEG 2000 images (several GB) in the browser and run some image processing on them. So, while I'm not an expert, I get my hands dirty and play a little bit with that very promising new technology. For the Vue.js part, I must confess I am a newbie (a month or two), but what makes me very happy with it is its simplicity and expressiveness (and the excellent doc, thanks to all the team :-) ).

Here are my observations and thoughts about wasm.

  • wasm can be very fast. I have seen up to 25 times faster than JavaScript on some image processing algorithm (convolution). I am talking about the same algorithm written in JavaScript and then rewritten in C then compiled with emscripten into wasm. But for your information, emscripten can also generate some optimized JavaScript which is "only" 2 times slower than wasm for the convolution algorithm and that surprisingly can be faster for some other algorithms. But, as always with performance, that depends a lot on the context. My conclusion is that wasm promise of speed is fullfilled, but JavaScript engines are also very optimised and perform very well. So there is no clear win.
  • wasm files can be very small. As already noted it is in fact one of the requirements of the MVP. But some wasm file created by emscripten can be very big (as in the Blazor example) in part because emscripten can bring some code for standard library.
  • One of the core advantage of wasm, is as a compilation target. With emscripten you can bring legacy C/C++ code base into the browser. This is what is done for Google Earth, for AutoCad, for some game, etc. But often it is for lower parts of the code (like physics engine), not the actual display code.
  • I agree that, for now, there can be some overhead on calling wasm from JS or JS from wasm, and so on manipulating DOM from wasm.
  • The first identified use cases that can clearly benefit from wasm are not the UI ones.

So, with my experience, for now I guess that wasm is not a very good candidate for performance improvement for Vue.js. But as note by @OlzhasAlexandrov, everything is moving. It is a new technology and things can improve in the future. If one want to go this path, I guess the best it to first identify some bottlenecks of Vue.js by measuring things and check if wasm can be a good candidate to improve performance by doing some experiments.

But for me, as I said, the killer feature of Vue.js is its simplicity. So I prefer a slightly slower solution but very easy to use, than a very fast one that is more complex. And if wasm is used, it means there will be an other development technology (walt or something else), which comes with maintenance cost for the dev team. So there will be some compromises to do between all that.

@Dwood15

This comment has been minimized.

Copy link

Dwood15 commented May 18, 2018

Vue.js already has typescript support, I wonder how much it would take to work assembly script into vue as an option?

This may be somewhat offtopic to the issue, but as someone who really likes to use Vue, I would certainly enjoy taking the paradigm/framework into the context of a 3d game's ui... While that would take ton of effort... it would be interesting to be able to use the vue paradigm to compose and interact with WebGL-ui's via something like an html canvas or offscreen-canvas

On-Topic:
I don't think WebAssembly is a good first-class target for Vue.js, unfortunately, because there is significant belief that browsers will never implement first-class dom api access for WebAssembly.... And if it does get implemented, we won't be seeing it for some time.

@Dwood15

This comment has been minimized.

Copy link

Dwood15 commented May 21, 2018

I've spent some more time thinking about this topic, and want to add some extra thoughts before I lose them.

After considering my personal experiences using Vue, I have a hard time believing the bottleneck for Vue is in the JS DOM api. Are there benchmarks showcasing this? My personal experience is that you're not using Vue for the performance, you're using it because it makes designing ui an elegant experience.

Runtime type-checking of props, the ridiculous callstack depth of exceptions, it's still all on the same thread, and more, seem to be leaning against it.

I wonder if the wasm -> js interop layer would be such a slowdown. honestly, I'm with the Vue core team - not really sold on wasm being a performance boon to Vue.

@OlzhasAlexandrov - if you want to help Vue make a jump to Wasm, we need benchmarks. Just because wasm speeds up some expensive image processing doesn't mean Vue's bottlenecks are the same.

@ the core team: You really can't underestimate the power of built-in run-time type-safety that wasm could give Vue. Manually checking with typeof and instanceof really isn't ideal.

Potential for other performance boosts on the other hand, might possibly include using Vuex in a wasm environment, via web workers. While it's theoretically possible, I don't know if anyone has tried.

@o-alexandrov

This comment has been minimized.

Copy link

o-alexandrov commented May 21, 2018

If the core team has a task with the exact tech requirements, I'll be glad to assist in the beginning.

I suggest that we start by replacing the bundle renderer for production.
Please let me know any benefits of JSON parsing of the bundle that is created by vue-server-renderer besides ease of debugging (which we should ignore in production) over normal, usual, and straightforward rendering:

import { createApp } from '/path/to/built-server-bundle.js'

☝️ please observe the reasons why it's a bad approach in the initial comments of this issue.
SSR optimization should bring the most value.

@o-alexandrov

This comment has been minimized.

Copy link

o-alexandrov commented May 21, 2018

In short, look how bad vue-server-renderer (link to source) is for serverless:

  • First, cold start, triggers huge JSON parsing with a lot of typeof checks.
  • We cannot tree-shake dependencies with serverless-webpack, since the function doesn't have access to the dependencies itself, only to the .json bundles and the .html file.

I am sorry for all devs who are using it, including myself.
Imagine how great it would be, if we compile it to wasm.

@OEvgeny

This comment has been minimized.

Copy link
Contributor

OEvgeny commented May 23, 2018

So, another 2 cents.

In short, look how bad vue-server-renderer (link to source) is for serverless:

Just to me this statement does not answer the question: "Why WebAssembly should be used to address mentioned issues?". In fact issue description also doesn't. Just because there are only assumptions about WebAssembly capabilities/strong-sides (less bytes, more performant) and examples unrelated to usecases meet in Vue.

I believe there are better ways for fixing mentioned issues without utilizing WebAssebly.

As for WebAssembly integration, lets take a look at Glimmer as an example (which is nearly close to Vue in its goals). They built a compiler to compile handlebars templates into binaries for Glimmer VM. This aims to increase both network and DOM updates performance. The compiler and VM are (still?) written in TypeScript. As far as I know there are only plans for WebAssembly version. Please note that templating-engine is only the part of whole thing. So you already have a clue how much effort is needed to achieve such goal. I mean it is not possible to just replace one compiler with another to get WebAssembly binaries in place of JavaScript sources. It's a lot of work (for nearly no viable reason imho).

If anyone sees possible path for Vue to implement such integration, I guess it's very welcome to discuss though.

@o-alexandrov

This comment has been minimized.

Copy link

o-alexandrov commented May 23, 2018

@OEvgeny
There have been so many already highlighted:

  • benefits of migrating to WebAssembly
  • cons of current approach for SSR

so not to continue repeating the same things over again, I will build on what has been previously said:

I suggest not to try to rewrite or use AssemblyScript (why better than walt) for the whole Vue ecosystem at once.
Rewriting a small package for a SSR function, vue-server-renderer, is a primitive task to start with.

It is a common approach to divide a big project into a bunch of small pieces.
Experimenting on a small package from the Vue.js ecosystem is a good starting point.

@kripken

This comment has been minimized.

Copy link

kripken commented May 23, 2018

As for WebAssembly integration, lets take a look at Glimmer as an example[..] As far as I know there are only plans for WebAssembly version.

There is a PR for porting an initial small part of Glimmer to Rust/wasm: glimmerjs/glimmer-vm#752 My understanding is that part is mostly done, but it is waiting for a dependency (wasm2asm in binaryen, which will allow it to run in browsers like IE11 that lack wasm support). The dependency should be ready soon, so it's possible we'll see wasm adoption in Glimmer at that point.

@OEvgeny

This comment has been minimized.

Copy link
Contributor

OEvgeny commented May 24, 2018

There is a PR for porting an initial small part of Glimmer to Rust/wasm

Great news! Very happy for Glimmer team. As PR title says "Initial stab at porting asm/stack.ts to Rust", I think there are a lot related to Rust/wasm changes as PR is quite big. Maybe things will go smoother with AssemblyScript/walt. Anyway any example on AssemblyScript /walt integration with existing js production-ready project/library is really appreciated.

Rewriting a small package for a SSR function, vue-server-renderer, is a primitive task to start with.

I'm not sure it is so, maybe if you're smart enough.

@mihail-shishkov

This comment has been minimized.

Copy link

mihail-shishkov commented May 27, 2018

Blazor's story is entirely different. Blazor runs on top of Mono (.net runtime) that is compiled to WASM. It actually executes real .NET assemblies/dlls in interpreter mode. It interprets MSIL and the guys building it have stated many times that this will be addressed. Mono team (Miguel de Icaza, creator of Xamarin and Mono) are working on ahead of time compilation that will make possible compiling blazor apps straight down to WASM. Currently the entire .NET "VM" is downloaded with the app itself + some standard libraries that have plenty of meaningless code in them like File IO (which does not make sense in the browser). That's why it is >1MB in size. When things get optimized enough I am pretty sure that the same app written in angular and blazor will be smaller in blazor and will run faster in blazor (given that angular has not switched to wasm). You may want to take a look at this one https://github.com/koute/stdweb which is a way to manipulate the DOM with Rust. No interpreting or VM over VM here just plain WASM.

@fnlctrl

This comment has been minimized.

Copy link
Member

fnlctrl commented May 27, 2018

@mihail-shishkov Would you please build a stdweb demo (namely, the todomvc example) and put it here? The repo doesn't include a pre-built one and I can't seem to get the demo to compile on my windows machine. I guess it's also too much of a hassle for people who just want to see a demo to install the complete rust toolchain.

@fnlctrl

This comment has been minimized.

Copy link
Member

fnlctrl commented May 29, 2018

So I installed a ubuntu vm and rust toolchain, and finally built the stdweb todomvc demo:
image

For now, that's 30KB js + 430KB wasm, for a todomvc demo. (and 6KB gzipped js + 131KB gzipped wasm = 137KB gzipped)

And compared to vue's todomvc demo, 2KB gzipped js + 22KB gzipped runtime, that's 522% bigger in size.

Perhaps it wasn't a complete waste of 2 hours to setup a rust env and compile that demo, since at least I confirmed my assumption by actually trying it out. I'll just leave the built demo here. See it for yourself.

Yes of course, it's still "experimental". I guess we'll have to wait to see that "size advantage" in the future, perhaps Soon™.

As for performance, there's no difference at all since the todomvc demo is too simple. Below are the timeline for adding a todo item.
Vue:
image

stdweb:
image

I guess we'll have to wait for a more complex demo to find out. For now, I'll just keep assuming wasm won't bring much performance improvement to traditional applications that heavily uses DOM APIs to draw the UI.

@liangzeng

This comment has been minimized.

Copy link

liangzeng commented Jun 9, 2018

In most cases, extreme performance is not a requirement, and a skilled programming language and ecology are important.

Fragmentation of technology should be avoided, so we can use https://github.com/AssemblyScript/assemblyscript for performance-related attempts.

@EqualMa

This comment has been minimized.

Copy link

EqualMa commented Jan 7, 2019

I agree with you. Server side may improve much performance if computing modules are wasm. (In fact browser side is not so important when talking about performance. ) Thankfully vue 3 will be in typescript and will be splitted to many small modules so it may be easy to extract computing modules and compile to wasm with AssemblyScript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment