ckeditor / ckeditor5-design

☠ Early discussions about CKEditor 5's architecture. Closed now. Go to https://github.com/ckeditor/ckeditor5 ☠
58 stars 12 forks source link

ECMAScript 6 #63

Closed pjasiun closed 8 years ago

pjasiun commented 9 years ago

tl;dr should we use ECMAScript 6 iterators and generators in the CKEditor 5?

ECMAScript 6 brings us a lot of features we could use in the CKEditor 5, and this ticket could be called: "Should we use ECMAScript 6?", but I believe it is too generic and it's better to focus on features we need at the beginning. I focus on Generators, because they can influence on the new editor architecture, make it much simpler but also may be the most difficult to change. For those who did not met generators before here is nice tutorial.

Generator could be very useful when it comes to all transformations, and transformations is what we have everywhere: between linear data, document tree, dirty DOM and input data. But also may be useful for creating tools like DOM walker.

What are pros of using generators:

So what are cons:

This is risky. The question is should we take that risk?

oleq commented 9 years ago

This is risky. The question is should we take that risk?

Yes. It's risky if we release CKE5 before browser vendors implement ES6. On the other hand, ES6 is the future of JS and sooner or later it will be a very common thing and CKE code base will be ready for that. At the moment, Firefox and Edge are virtually ES6–ready and I think it's unlikely that Blink/Webkit developers would fall behind. It's an approved standard so the pressure of the community will increase and people will expect devs to implement new stuff, at least in Node.

Another thing is that it's not only about generators/iterables. Classes, template strings, destructuring, "arrow functions", sets, maps. There's a lot of stuff we could use in CKE that would make the code shorter and simpler. Perhaps even faster. Considering the roadmap of CKE5 we should not hesitate and take the risk because the benefits are totally worth it.

EDIT: Keep in mind that development will be rough at the beginning since Babel produces tons of (slow?) code, takes time to compile and requires browser polyfill to enable some crucial features.

Reinmar commented 9 years ago

I'm absolutely for using ES6. I was hesitating half a year ago, but I think that things are stable enough right now. And first of all – the spec is approved.

But, I would choose very carefully features that we want to use. Mostly for performance and code size reasons.

Classes are a good example of a feature we should adopt. They are a syntactic sugar, so they should be performant from the first day and their ES5 version is pretty compact too. I mean – we would need to write the same code.

We already use promises from ES6, because we want to anyway and they can be polyfilled.

Destructuring – why not. They are easy to transpile to ES5. Arrow functions – the same (although I find them unreadable when used too extensively).

Let, const – ofc.

But iterators... I'm not 100% sure. Check the example from https://babeljs.io/docs/learn-es2015/#iterators-for-of in http://babeljs.io/repl/. A tone of code and it's hard to understand what's its performance. Plus, it requires loading the Babel's polyfill. Additionally, their performance may be very poor initially, so if one would like to generate a ES6 package of CKEditor (what must be supported by the builder) it perhaps may be small, but slow as hell.

So I would make clear rules what can be used and what should not. Stuff to reject:

oleq commented 9 years ago

A tone of code

In ES6? Hardly. Transpiled to ES5 – perhaps.

and it's hard to understand what's its performance.

[citation needed]

Plus, it requires loading the Babel's polyfill.

That's the real problem, I suppose. We could avoid those features at the very beginning and, once commonly implemented, simply adopt them.

Additionally, their performance may be very poor initially

[citation needed]

Anyway, let's force @fredck to chime in.

pjasiun commented 9 years ago

https://babeljs.io/docs/learn-es2015/#iterators-for-of is actually a bad example, because this's a code you will never write if you could use generators. It would looks more like:

function* fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}

It's simple and I believe the performance would not be a problem.

pjasiun commented 9 years ago

But I agree that transpired code will look like an nightmare. And the size of that code is not the biggest problem here. If ES6 features will be part of the CKE5 API we can not use Babel then. Then they need to be supported natively.

Reinmar commented 9 years ago

In ES6? Hardly. Transpiled to ES5 – perhaps.

And we need to care about ES5. I didn't mean ES6 of course.

and it's hard to understand what's its performance.

[citation needed]

You've got it above ;) Did you compared that generated ES5 code with some code that was written as ES5 in a first place (of course it would be a different approach - and that's the point).

That's the real problem, I suppose. We could avoid those features at the very beginning and, once commonly implemented, simply adopt them.

Yes, definitely. The whole point is that now we should only unlock us, because in 2-4 years from now there will be no problem at all.

Additionally, their performance may be very poor initially

[citation needed]

Again – me. In the race to implement as much of ES6 as possible browser vendors must take shortcuts and can't spend months optimising the code so e.g. it's properly JITed. Of course, there may be cases where some ES6 feature will be faster than some ES5 approach, but in general you have no idea about that and many will be slower.

Reinmar commented 9 years ago

PS. Remember about the approach that we chose regarding Promises. We can adopt some new stuff from the standard library if we find it super super useful. We just need to expose it through our API so its polyfillable in weird environments where e.g. Babel's polyfill cannot be loaded. But we'll need to make sure that CKE will work without loading the whole ES6's std lib polyfill which must be pretty big (a number I found was 50kb, but no details so I don't even know if it was minified or not).

Reinmar commented 9 years ago

BTW. Remember about one more thing - debugging. Even with source maps ES6 code will be harder to debug than code working natively. Therefore code that doesn't transpile to something understandable may be a pain in the ( )*( ).

pjasiun commented 9 years ago

That is true. But note that we are talking about the feature which is already supported in Chrome and Firefox. I believe Edge will support it very soon. At this stage we will not debug mobile, but on the other hand we will do it soon, since CKEditor 5 will focus more on mobile.

oleq commented 9 years ago

BTW. Remember about one more thing - debugging. Even with source maps ES6 code will be harder to debug than code working natively.

Just a little bit. I just looked around and noticed that debugger statement (debugger as a whole) works fine with source maps in Chrome. Quite a surprise.

Reinmar commented 9 years ago

Talking about performance. By coincidence I found this yesterday:

http://www.incaseofstairs.com/2015/06/es6-feature-performance/?utm_source=javascriptweekly&utm_medium=email

And talking about debugging:

https://twitter.com/OliverJAsh/status/618393924521099264

Reinmar commented 9 years ago

Summary from my F2F discussion with Fred. Fred shares this opinion:

Personally I intend to start using most of these features where they make sense but will avoid designing core APIs around these features (perhaps with the exception of Promises) until the native implementations have matured a bit.

It makes a lot of sense. We cannot force other developers to use ES6 just yet, because that will be super inconvenient for many (as it would simply force them to use 6to5 transpilers), so we cannot build our API around ES6. We can however use it internally, like inside our modules or functions. And of course we can freely use ES6 in our build tools and other code which will not be released.

So the remaining question is whether to use ES6 in a project like CKEditor taking into account how we'll be able to use it and that we're building an open source project – a framework to be used by other developers.

There will definitely be annoyances (like debugging and need to setup the environment), we must be careful when picking ES6's features and applying them to not affect too much the performance, code size or an ability to debug the code. We must figure out how to build a CKEditor packages, because Babel adds private helpers to the source and since it should be possible to build CKEditor core independently from plugins, how to share those helpers so they do not repeat in every module/package. Etc. This obviously requires additional work.

So what are the profits? Since ES6 will definitely cause some troubles, are the benefits worth the pain? I think they do. The subset that we'll be able to use does not open any new possibilities, but it makes a code more robust and standardised. This will be profitable for us and for other developers too. Secondly, it will affect the project's reception and attract more developers interested in cutting edge stuff. There's no real link between "the project uses ES6" and "the project is well coded", but (unfortunately) many developers have the attitude that if something doesn't use cutting edge technologies, it's outdated. Finally, with time the situation will improve, more browsers will support ES6, so perhaps even with CKE 5.0.0 we'll already be in a situation when Babel is only needed to test CKE on some legacy (mobile?) browsers and that in some use cases developers will be able to ship ES6 version of CKEditor.

TL;DR: I'm still for using ES6 (if we're able to solve the problems related to the building process), but being careful and picky.

fredck commented 9 years ago

Let's give ES6 a try!

At the very fist stage, we may not adopt transpilers and code purely targeting Chrome.

Later on we can have a Bender plugin that automagically transpiles the code when serving application files, avoiding having to fire this manually or through watchers.

Fingers crossed and lets make it successful. Not bad to think about coding the software of the future using the language of the future ;)

pjasiun commented 9 years ago

I did a research how Babel works with CKEditor 5 (at the current stage) and:

ckeditor5> grunt babel
Running "babel:dev" (babel) task
Warning: node_modules/ckeditor5-core/tests/es6.js: Line 28: Direct super call is illegal in non-constructor, use super."operations"() instead Use --force to continue.

Aborted due to warnings.
let [ a, , b ] = [ 1, 2, 3 ];

=>

var _ref = [1, 2, 3];
var a = _ref[0];
var b = _ref[2];

Changes in https://github.com/cksource/ckeditor5/tree/babel and https://github.com/cksource/ckeditor5-core/tree/babel

fredck commented 9 years ago

Ok.. the first trouble points are already known:

I would add two other points that need check:

oleq commented 9 years ago

Documentation (jsduck)

This could be a game–changer. Sadly, it's been like nearly 2 years since the stable release and it doesn't look like anything is going on there.

I would add two other points that need check:

Some extra from me:

fredck commented 9 years ago

This could be a game–changer. Sadly, it's been like nearly 2 years since the stable release and it doesn't look like anything is going on there.

I mean, if not jsduck, what then, with support for ES6?

pjasiun commented 9 years ago

Compilation (building process), packaging: We expect "alphas" and "betas" before browsers implement ES6, don't we? If we use Babel for that, we must know the limitations and possible obstacles.

All plugins need to be build with the same version of Babel (if we decided to use Babel). This is a type of limitations and issues we could meet.

pjasiun commented 9 years ago

This could be a game–changer. Sadly, it's been like nearly 2 years since the stable release and it doesn't look like anything is going on there. I mean, if not jsduck, what then, with support for ES6?

We could move this discussion here: https://github.com/ckeditor/ckeditor5-design/issues/25

amitev commented 9 years ago

modules (because we already decided to use AMDs),

Please make sure you're not strictly tight to requirejs. We are now loading CKEditor with systemjs and it works quite well.

P.S. Compatibility with JSPM will be great too.

fredck commented 9 years ago

Please make sure you're not strictly tight to requirejs. We are now loading CKEditor with systemjs and it works quite well.

P.S. Compatibility with JSPM will be great too.

It will be distributed with no RequireJS dependency in a standard, pure AMD fashion, which should be compatible with systemjs, JSPM and others.

amitev commented 9 years ago

By JSPM compatibility I mean to be able to include it in the JSPM registry - https://github.com/jspm/registry/blob/master/registry.json and for JSPM to be able to download the editor and its plugins from a github tag.

fredck commented 9 years ago

At first, it will be registered on npm, so it should work for JSPM as well. But ofc, including it in the JSPM registry as well seems reasonable. As I said, we should have the compatibility requirements for it to happen so in the future. Let's get back to this once CKEditor 5 will get its first shape.

vokiel commented 9 years ago

Comparison table of performance of ES6 features relative to the ES5 baseline operations per second. http://kpdecker.github.io/six-speed/

Reinmar commented 8 years ago

I extended https://github.com/ckeditor/ckeditor5-design/wiki/Coding with a section about ES6. I'm closing this issue (at least for now).