Knockout: Depreacate Knockout.js for new projects

Created on 1 Aug 2017  Â·  25Comments  Â·  Source: knockout/knockout

It seems like it wouldn't be a good idea to use knockout for anything new. Would you be able to acknowledge this on your documentation and on your website?

Most helpful comment

More modern, and less mature. I'm going to assume you're referring to React since you're referring to a shadow DOM. Also, your "comparison" is quite apples-to-oranges. React supports server-side rendering compared to Knockout seems to have a very difficult API? Let me show you a comparison:

In react, you work in HTML fragments that get returned from component functions. Originally, this was incredibly inefficient and jerky to update the UI due to the HTML dom replacement of the generated HTML fragments. They had to invent an entire abstraction layer called a 'virtual dom' and perform a diff between the real DOM and the virtual one to make changes. They touted as a huge advancement but in actuality covered up a very inefficient way to do dynamic html. In comparison, Knockout introduces the notion of data-binding where specific dom elements are bound to observable data, such that that data change only effects specific parts of a dom. No diff required.

Here's another:

In react, it's standard practice to write code in JSX format which requires a transpiler to convert the JSX into a standard javascript form. In compassion, Knockout requires no transpilers or build step.

Also these snippets in data-bind just seem like they need to use eval to work, so the implementation is dubious

It took 10 seconds to search for "does knockout require eval to work" and I found these two pages immedately:
https://groups.google.com/forum/#!topic/knockoutjs/PQBcnOM3Fvk
https://stackoverflow.com/questions/4599857/are-eval-and-new-function-the-same-thing

@karolk , I appreciate you like react, and it looks like you have a long history of contributions to github projects (although mostly private repos), but starting an issue here saying that the developers and community should just pack it up looks really really bad. The development is active, even if the majority of work is bugfixes. Do you think React is going to have this sort of activity after 7 years and ~1600 commits? And @brianmhunt has an excellent project called TKO which modernizes much of the knockout implementation. And if that becomes a future release of knockout, it will _still_ be knockout because he has made great efforts to keep the API and capabilities in line with the current release. So check out that repo to keep your information up to date.

I suggest you check out the knockout tutorial http://learn.knockoutjs.com/#/?tutorial=intro. It's an excellent introduction. In fact, if you can find me the equivalent tutorial/live-demo in React, I'd love to see it. My experience with react developers I've spoken with is that they diss anything that isn't done the react way. I'd recommend that before criticizing and calling for a shutdown, you at least do some work in the framework so you know what you're talking about.

All 25 comments

What makes you think that @karolk ?

LOL, what?

There are more modern frameworks which support things such as shadowDOM, server-side rendering out of the box. In comparison Knockout seems to have a very difficult API. Also these snippets in data-bind just seem like they need to use eval to work, so the implementation is dubious. In my opinion knockout-style API and 2-way binding as a concept is a dead end. Also there is a ticket from 2015 about refreshing the website, but it seems that it never happened. Looking at the commit graph it seems it's just bug-fixing, no new features being implemented. Maybe there should be some effort on Knockout.js to React converter?

More modern, and less mature. I'm going to assume you're referring to React since you're referring to a shadow DOM. Also, your "comparison" is quite apples-to-oranges. React supports server-side rendering compared to Knockout seems to have a very difficult API? Let me show you a comparison:

In react, you work in HTML fragments that get returned from component functions. Originally, this was incredibly inefficient and jerky to update the UI due to the HTML dom replacement of the generated HTML fragments. They had to invent an entire abstraction layer called a 'virtual dom' and perform a diff between the real DOM and the virtual one to make changes. They touted as a huge advancement but in actuality covered up a very inefficient way to do dynamic html. In comparison, Knockout introduces the notion of data-binding where specific dom elements are bound to observable data, such that that data change only effects specific parts of a dom. No diff required.

Here's another:

In react, it's standard practice to write code in JSX format which requires a transpiler to convert the JSX into a standard javascript form. In compassion, Knockout requires no transpilers or build step.

Also these snippets in data-bind just seem like they need to use eval to work, so the implementation is dubious

It took 10 seconds to search for "does knockout require eval to work" and I found these two pages immedately:
https://groups.google.com/forum/#!topic/knockoutjs/PQBcnOM3Fvk
https://stackoverflow.com/questions/4599857/are-eval-and-new-function-the-same-thing

@karolk , I appreciate you like react, and it looks like you have a long history of contributions to github projects (although mostly private repos), but starting an issue here saying that the developers and community should just pack it up looks really really bad. The development is active, even if the majority of work is bugfixes. Do you think React is going to have this sort of activity after 7 years and ~1600 commits? And @brianmhunt has an excellent project called TKO which modernizes much of the knockout implementation. And if that becomes a future release of knockout, it will _still_ be knockout because he has made great efforts to keep the API and capabilities in line with the current release. So check out that repo to keep your information up to date.

I suggest you check out the knockout tutorial http://learn.knockoutjs.com/#/?tutorial=intro. It's an excellent introduction. In fact, if you can find me the equivalent tutorial/live-demo in React, I'd love to see it. My experience with react developers I've spoken with is that they diss anything that isn't done the react way. I'd recommend that before criticizing and calling for a shutdown, you at least do some work in the framework so you know what you're talking about.

@chrisknoll thanks for your reply. I didn't mean to disrespect anyone but I separate tech from people so I think it's OK for me to criticise the code. I too wrote a micro templating system based on jQuery (it is a very bad piece of code) and thought I had some excellent ideas before other frameworks happened and ES6 string literals made my efforts less relevant.

Having spent a substantial amount of time in the front-end space I can see that project have a natural end of date and React will get there as well at some point, as did Prototype.js, jQueryUI and a bunch of other cool project. I am right now involved in rewriting a project from Knockout to React so my attention was drawn to Knockout.

I didn't expect anything else but to be told how wrong my assumptions are and how Knockout.js isn't dead yet and it's going great but in my opinion the API you invented didn't stand the test of time. I think from having used Angular.js that 2-way binding is just an easier way to shoot yourself in the foot and adding data-* snippets on html may be the compliant way to do it but it's definitely not as nice to work with as JSX.

What I think would be a way of spending time in a productive way would be a Knockout to Angular and Knockout to React guides and maybe some semi-automatic code converters.

What I think would be a way of spending time in a productive way would be a Knockout to Angular and Knockout to React guides and maybe some semi-automatic code converters.

Why not spend time creating a React to Knockout converter? That would be going in the right direction. :)

I think you should write a blog about your experience going from Knockout to React. That would be very informative to the overall community and if you do find something that is deficient (read: not merely different) maybe it would inspire some improvements. Competition is good! Convincing everyone to just convert to React is not in the spirit of competition. Besides, like I said, React and Knockout just approach the problem in very different ways (virtual dom vs. data binding), which is why a conversion tool is probably not possible. If you do decide to write something up, I'd definitely like to hear the specific justifications for the move; IE: there is something you just can't do in Knockout that only React can solve. That would be quite interesting! Also something to discuss on the knockout google groups since you might get more eyes on that.

Thanks for the input @karolk

In terms of more modern frameworks, it's noteworthy that tens of thousands of production websites continue to use Knockout, and have done so for aeons by Internet-time standards.

While there are certainly newer frameworks, investing in KO seems to have paid substantial dividends in terms of actually getting production websites up.

It appears straightforward to employ the ShadowDOM to compliment existing KO components and bindings. If you feel there is a benefit to that, consider opening an issue for that specifically on knockout/knockout or knockout/tko.

Rendering server-side is something that both KO and TKO can do, but it has never been a focus. It would require more guidelines or configuration than recoding, I suspect.

TKO uses a CSP-safe parser (i.e. not eval or Function, ...), based on knockout-secure-binding, for interpreting the data-bind and params strings. It has a pluggable binding system so alternatives can be employed.

I don't feel that Knockout has reached end-of-life yet, as it solves a problem in a way that feels quite natural to me. Tko in particular takes much of what Knockout did and breaks it into modular, reusable pieces that can be mixed and matched.

All that said, work has to be done on tko to make the next version more palatable to the masses.

I'm going to close this issue because there does not appear to be any specific items that Knockout itself could fix here, but I hope that does not derail the conversation or @karolk make you feel that the feedback is unwelcome or unwarranted.

@karolk You may find the comments on #2106 interesting.

FYI Azure and Visual Studio Team Services are built on Knockout :)

@codymullins you mean 2 of the worst sites I've ever had the miss fortune of going to!

FYI Azure and Visual Studio Team Services are built on Knockout :)

Visual Studio Team Service (Now AzureDevOps) has been using ReactJS since at least January 2017. The Azure Console was Knockout last time I Checked.

@juanjoseluisgarcia is correct. Microsoft Azure Portal is made with KO. Though even if I do not like all mentioned tools the portal made with KO (especially considering its complexity) looks and works much better than one made with React. In any case it is easy to make piece of shit with any tool.

Also maybe you will be surprised that we do not use TypeScript and ES6 at all. We use C# and Bridge.Net to compile all directly to ES5. Also I wrote basic version of KnockoutJS bindings for Bridge.Net.
So Knockout does only what it really worth for our project: components and MVVM.

For next project most likely we will use TKO. At least I consider refactoring of existing code and move all to TKO in the first half of 2019.

I just want to ask @brianmhunt about performance of TKO.
I know KO has some issues in tests and I personally got a troubles with thousands of elements in foreach.
Did anybody test TKO vs Vue for example?

KO result can be found here:
https://stefankrause.net/js-frameworks-benchmark8/table.html

Hi @hardhub — It looks like TKO with JSX is substantially faster than KO in many areas, sometimes by orders of magnitude; I'd be interested in seeing it eventually incorporated into the table.

For huge lists, you can use my knockout-fast-foreach plugin, which has much better performance than the standard foreach, particularly for large lists.

Yes, there is something up with the large table modification benchmarks that I hope can be addressed (was hoping for 3.5, but 4.0 would work, if 4.0 comes out soon (wink wink)). There was a PR to the benchmark (which was accepted) that attempted to address this, but didn't address the issue. Would be good if some of our implementation experts could get the faster implementation into core. Maybe the benchmark can have an option for the fast foreach plugin enabled on it, maybe that would show the diff in large lists, but also show potential impact on the other use case?

something up with the large table modification benchmarks

I investigated a bit the source code of benchmark.
They unwrap observable array modify elements inside array and put it back to observable array.
Maybe splice functions will work better on observable array itself.
But not sure if KO performs some optimization and avoid deletion of already displayed items which also are part of in new array.
If not - then maybe good way to go.

    self.swapRows = function () {
        startMeasure("swapRows");
        var tmp = self.data();
        if (tmp.length > 998) {
            var a = tmp[1];
            tmp[1] = tmp[998];
            tmp[998] = a;
            self.data(tmp);
        }
        stopMeasure();
    };

https://github.com/krausest/js-framework-benchmark/blob/master/frameworks/keyed/knockout/src/Main.js

I believe that was the change in the PR, in the origional bench, it pushed it (which is also slow).

I'm not sure how fast-foreach works, but, in my mind, when recieving a new array int he foreach binding, doing a more sophisticated diff between current elemetns and new elements and only swaping out the doms that were impacte woudl proably be the best. But, I'm not an expert on this.

All of KO and TKO and fast-foreach should use a least-change swap (see the observableArray.changeTracking.js. Using slice ought to be faster since the diff is effectively pre-computed.

In terms of fast-foreach and tko, they also doing async-updates with requestAnimationFrame.

TKO-jsx also does a diff-DOM-compare when an observable array of JSX nodes is updated i.e. even without binding foreach - the following will do a least-diff update:

<div>{observableArray}</div>

Where observableArray is an array of (possibly heterogeneous) "JSX", text, Promise, or observable values.

It sounds so good, makes me sad it is not out yet :( no pressure....

I still use knockout all the time, I pick it over other frameworks time and time again for one big reason.

I can throw it in any project and it doesn't conflict with anything.

We're launching a single page app on Thursday that integrates as a page in an existing web application. It's built entirely in knockout on bootstrap 3.2. It compiles to a single JS file that's 120 kb in size, that includes all it's styles, images, html, and js code. I built it this way because it's platform agnostic. It doesn't really care which of our web apps it's in as long as it's on our domain. Also it was a requirement to have it launched to different sites in our network (the intranet, and our public site). The intranet version runs anonymously with no user login and is read only (no likes, favorites, custom lists, etc etc etc) It's backed by a REST API and a Google Search API. Basically this app is a search center for all of our CMS content. We wrote a google api to index all of our CMS content and categorize it based on meta data coming back from a rest api on the cms. Then our single page app is the UI for searching all of that content. It's pretty slick and 100% SPA, even maintains deep links through hash fragments and can be bookmarked. We've got some cool stuff in there, including mobile views, a podcast player with wave form view, youtube player api integration, and swipe support. It's even got multiple view modes for grid vs row display. We even have a google search cursor in play so it's returning a set of a results at a time as you scroll instead of bringing back everything. It's built a lot like some modern SPA's, instead of seeing blank content and having content appear out of nowhere, we show placeholder graphics (div's with cool css to fake abstract dummy data) where data is about to be.

Load time on the page is insignificant. It's near instant and is by far the fastest thing on our website. That's partially because it doesn't have server side rendering at all, it's backed entirely by rest apis.

The CMS world is leaning hard towards headless CMS's... So before long server side rendering might become obselete entirely.

We're actually leaning away from server side MVC layers entirely. All of our new pages are backed by rest apis, and that's awesome. Because we don't need to interact much with back end devs. The backend developers can focus on Data and Rest APIS and not touch a single line of JS or HTML and leave all of that to the Front End engineering team, works out much better.

Let's face it, having back end developers have to do html, css, and js is how you end up with crappy html css and js in the first place. And having front end engineers work on backends is how you end up with crappy data layers and back end rendering layers. So it's best to separate the two completely and hire people that specialize in one or the other and keep them on what they specialize in. As opposed to having "every hat" developers that can do lot's of things ok or well, but not anything great.

You can do a lot of modern development with knockout if you know how to use gulp-4 or webpack really well and setup a build for it. The issue there is there is no easy cli tool to do it for you.

I use gulp-4 and all of the following plugins:

const { watch, series, parallel, src, dest } = require('gulp'), htmlToJs = require('gulp-html-to-js'), livereload = require('gulp-livereload'), cordova = require("cordova-lib").cordova, sass = require('gulp-sass'), rename = require('gulp-rename'), concat = require('gulp-concat'), uglify = require('gulp-uglify'), css2js = require('gulp-css2js'), include = require('gulp-include'), del = require('del'), path = require('path');

So the just of it is htmlToJs runs through my html folder and compiles all of that to html.js in a staging folder. Sass compiles all my Css and runs it through css2js to the staging folder... And then a normal script task in gulp 4 uses gulp-include to process app.js. App.js then includes html.js and styles.js into the app and outputs to app.js in the dst folder.

That's just one example of a build to do it.

In fact, atm I'm working on an apache cordova project using Live-Reload, gulp 4 and all built in knockout that will run in the browser, android, and ios.

server-side rendering out of the box

With node.js? thanks - not needed

Knockout seems to have a very difficult API

WHAT?

2-way binding as a concept is a dead end

Are you MVVM "killer"? Or probably MVC/MVP as well?

Knockout has some valuable disadvantages but nothing of that is mentioned by you.

Also there is a ticket from 2015 about refreshing the website, but it seems that it never happened.

Read about TKO.

effort on Knockout.js to React converter?

React? Piece of shit... No, thanks!

Jeez, don't hold back @hardhub, tell us how you really feel. ;)

My biggest complaint about knockout really, is having no way to do conditional components like you can with templates.

I.e. I want to do this:

<my-component-here data-bind="if: showThisThing()" />

But you can't....

But you can do this:

<div data-bind="template: 'myTemplateIdHere', if: showThisThing()"></div>

And my second is that I can't use IF Bindings to exclude the element it's on, it excludes it's children, so I end up having to use ko comments for IF's when I need the element I'm using conditional logic on to be the immediate child of the above element (common in bootstrap row/col scenarios).

I would love if you could do more with components in data-binds with conditional logic like that because components can all share the same instance of a viewModel, which is really handy sometimes.

Other than that I think it's darn near perfect.

And my second is that I can't use IF Bindings to exclude the element it's on, it excludes it's children

You could do so with a custom binding that uses node preprocessing. An example of this is my Repeat binding. See https://github.com/mbest/knockout-repeat/blob/master/knockout-repeat.js#L30

How about a virtual element?


On Wed, May 22, 2019 at 4:29 PM Ryan Mann notifications@github.com wrote:

My biggest complain about knockout really, is having no way to do
conditional components like you can with templates.

I.e. I want to do this:

But you can't....

But you can do this:

`

And my second is that I can't use if to exclude the element it's on, it
excludes it's children, so I end up having to use ko comments for IF's when
I need the element I'm using conditional logic on to be the immediate child
of the above element (common in bootstrap row/col scenarios).

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/knockout/knockout/issues/2277?email_source=notifications&email_token=ALETWB3YT4Q5NJ4GEXHS2B3PWVKFXA5CNFSM4DVHWBQ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODV7HQ5I#issuecomment-494827637,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALETWB7JZX7W6FVQHYL6Y3TPWVKFXANCNFSM4DVHWBQQ
.

@mbest Nice, yeah I was trying to do something similar with a binding I called "eif" (element if) that works just like if, but on the current node. It replaces itself with a comment. To make it easier I was trying to replace it with a knockout comment like this:

This is a good example to go by, thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mcarpenterjr picture mcarpenterjr  Â·  3Comments

fastfasterfastest picture fastfasterfastest  Â·  4Comments

ricardobrandao picture ricardobrandao  Â·  8Comments

Apollo3zehn picture Apollo3zehn  Â·  3Comments

priyank-eschool picture priyank-eschool  Â·  7Comments