Semantic-Org / Semantic-UI

Semantic is a UI component framework based around useful principles from natural language.
http://www.semantic-ui.com
MIT License
51.1k stars 4.95k forks source link

Eliminate Dependency on jQuery #1175

Open martindale opened 9 years ago

martindale commented 9 years ago

The dependency on jQuery is largely unnecessary, and this library would be much smaller and even more performant if it were to find more specialized tools to implement the features that jQuery currently provides.

levithomason commented 8 years ago

Got it. How about a bullet list of what you're proposing and what we'd gain from the move? I'll mull it over and run it by the team. I'd much rather collaborate.

jlukic commented 8 years ago

We're running similar integrations for Ember and Meteor. Generally adding your project as an official integration would provide higher visibility for your work.

levithomason commented 8 years ago

Sounds good, let me think this through and talk with some folks on Monday. Appreciate you reaching out.

Ryuno-Ki commented 8 years ago

In some countries, Monday is Pentecost - a Christian holiday. I regret, you have to go to work then, @levithomason :-(

levithomason commented 8 years ago

It's crazy. I write apps and tools literally every day and night. It's a labor of love. Somehow, a large slice of my passion is called a job. Do what you love and you'll never have to do it ;)

We should try to keep this thread focused on jQuery, though. Appreciate your concern for me.

levithomason commented 8 years ago

@jlukic I've thought this through and ran some things by the team. It just makes sense, so let's do it. There are some things to work out to make a full transition.

I've started https://github.com/TechnologyAdvice/stardust/issues/243 as a place where we can work these things out. I'll move all future chat about the migration there. Would love your input.

sethlivingston commented 8 years ago

This is great news!

On Mon, May 16, 2016 at 5:35 PM, Levi Thomason notifications@github.com wrote:

@jlukic https://github.com/jlukic I've thought this through and ran some things by the team. It just makes sense, so let's do it. There are some things to work out to make a full transition.

I've started TechnologyAdvice/stardust#243 https://github.com/TechnologyAdvice/stardust/issues/243 as a place where we can work these things out. I'll move all future chat about the migration there. Would love your input.

— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/Semantic-Org/Semantic-UI/issues/1175#issuecomment-219568811

jlukic commented 8 years ago

I'm quite plelased about this, just need to make sure licensing remains MIT for all works published under Semantic-Org

levithomason commented 8 years ago

MIT it is.

drcmda commented 8 years ago

Sometimes i wish Jquery would just disappear. It keeps so many great projects from moving on. I wouldn't let a monolith inside a modular project if someone forced me, or sprinkle $(...) expressions over clean MV code.

if semanticUI would use lodash, which is modular, no problem at all, but jQuery is a no-go and completely uncalled for.

Just a neutral vanilla UI lib that can be used anywhere, in React, Vue, Angular and so on, without making them preferences or dependencies. Why is that so hard to get. )-:

controversial commented 8 years ago

@drcmda always I wish jQuery would disappear :P

levithomason commented 8 years ago

Just a neutral vanilla UI lib that can be used anywhere, React....

Keep in mind, no matter what your method of manipulating the DOM (jQuery, DOM API, Zepto, etc.) it is not compatible with React. React uses a Virtual DOM, a complete representation of the DOM in JS. It then renders one way from JS to the DOM. You never read from the DOM.

Because of this, it must keep the Virtual DOM and real DOM in sync. If you touch the DOM in any way, you can blow up your React app. It will yell at you and let you know as well.

So, while jQuery is bloated for many tasks, under the hood it is calling the same vanilla DOM APIs you would have to call yourself. Which are the same DOM APIs the rest of the world has to call. All of which are no nos in React land.

It has been decided that Stardust will become the official implementation of SUI for React. Check it out.

drcmda commented 8 years ago

@levithomason but that is kind of Reacts own shortcoming. Vue for instance can use the dom, without any disadvantage. It would be nice to have at least one quality UI components system that doesn't rely on old monoliths or coaxes you into a specific MV framework.

Stardust still looks great. All the best for it!

levithomason commented 8 years ago

I'd call it an advantage rather than a short coming given the ridiculous performance it brings. Though, I still agree with your points. Thanks for the wishes!

controversial commented 8 years ago

@levithomason Stardust just reached 1000 commits, in case you didn't notice :tada:

levithomason commented 8 years ago

Ha, I did not! 🎉 Awesome.

cortopy commented 8 years ago

jQuery has its uses but with React and Angular 2, there should be more options than assuming the web is like it was 5 years ago where jquery was taken for granted. There are projects where you just can't use jQuery.

I'm not sure if removing it entirely is feasible, but the guys at foundation make it clear in their docs which elements require jquery and which don't. Currently I mix & match from different sources. I'm finding it difficult to do with semantic-ui

levithomason commented 8 years ago

@cortopy Per https://github.com/Semantic-Org/Semantic-UI/issues/1175#issuecomment-219568811 above, Semantic UI now has an official React port, Stardust. This repo will soon migrate to the official Semantic-Org and be renamed to Semantic-UI-React. The docs will live at react.semantic-ui.com. You can find the current docs here.

We started out including jQuery. We've now rewritten everything except forms without jQuery, you can see our progress here.

Though we're racing toward v1 component APIs and removing jQuery, TechnologyAdvice is using Stardust in production. This means there is a team working on it every day. We're moving very fast.

I'd love for you to try it out, give your input, and collaborate with us.

cortopy commented 8 years ago

@levithomason Unfortunately I use Angular 2, not React. I've looked at the Integrations page in the docs, and this seems like a remote option now.

I'd be happy to help with angular2 components though!!

Enelar commented 8 years ago

I think that jQuery is OK. Since semantic itself weight more than 1MB (uncompressed), next 200KB is not making weather.

controversial commented 8 years ago

@Enelar I don't have anything against jQuery, just that it's 2016, and jQuery is becoming less and less useful. Many people don't want to use jQuery in their projects, and for a project like Semantic UI to have it as a hard dependency isn't something I'm a big fan of.

brickyang commented 8 years ago

@Enelar So you called 20% increases of size is "OK". Not to mention that you don't need to require all "more than 1MB" Semantic files into your project.

Enelar commented 8 years ago

@brickyang this is wrong. I get 265+184=449KB with

  'sticky',
  'segment',
  //'icon',
  'site',
  'container',
  'grid',
  'header',
  'label',
  'reset',
  'image',
  'button',
  'card',

I had to abadon modal and dimmer, i am using vanilla instead. Thanks god i disabled icons. Semantic bloating faster than 20% each half-year. Eliminating jQuery won't stop that process.

In compressed: 23.9+64.6+84.3=172.8KB, so i get your point too. Returning your coin: it don't require whole jQuery to run. Bake for your own.

Browsers soon will have most of jQuery underhood: http://caniuse.com/#search=querySelector http://caniuse.com/#feat=dom-manip-convenience http://caniuse.com/#feat=once-event-listener So i will cringe.

I am just having my own opinion.

jmcclell commented 8 years ago

@Enelar Bloating is really not the issue here, in my opinion. The issue is that a hard dependency on jQuery precludes easy compatibility with modern JS frameworks such as Angular, React or, say, Elm.

I don't know how one fixes this in a way that could make it more easily compatible, mind you, but that is my concern. When using one of these frameworks, one of the core tenants (especially of React which actually enforces it!) is that the underlying DOM and VirtaulDOM must be in sync. If we are using Semantic UI components (dropdowns, for instance) which rely on JS+jQuery to modify the DOM out-of-band with regard to React's rendering process, we hit a wall. The components, thankfully, do have hooks which can be used to work around this problem, as the docs demonstrate for the React case, but it is still less than ideal.

So, while I don't have much of an opinion with regard to bloating, and I, unfortunately, do not have any solutions to offer at this juncture, I think it's important that we focus on the more pressing issues that a dependency on jQuery creates. I don't believe bloat to be one of them.

sethlivingston commented 8 years ago

I second @jmcclel. If something isn't needed (and jQuery is not needed), and if that something also causes compatibility problems, then it needs to go.

cortopy commented 8 years ago

@jmcclell totally agree. It's what I said above too. Angular 2 is very similar to React. It has its own rendering process to transit from shadow to light DOM. Adding jQuery goes against all the foundations of the framework.

levithomason commented 8 years ago

React Compatibility

@jmcclell @sethlivingston Compatibility with React is unrelated to jQuery. Consider:

$('.ui.dropdown .menu').addClass('visible')

const menu = document.querySelector('.ui.dropdown .menu')
menu.classList.add('visible')

jQuery uses the same DOM APIs everyone else does. Using jQuery or vanilla DOM APIs makes no difference. At the end of the call stack, browser DOM APIs are manipulating the DOM. Using DOM APIs is not "the React way". Per React:

React provides powerful abstractions that free you from touching the DOM directly...

These abstractions are the Virtual DOM. React basically rewrote the DOM. You cannot solve the React integration issue by any other way except using React itself as the JS implementation. This is why we created Semantic-UI-React. It doesn't use the DOM, it uses React's abstractions, the "Virtual DOM".

Angular2

Adding jQuery goes against all the foundations of the framework.

Then, like React, this is must also be true of using vanilla JS, since jQuery just calls vanilla JS under the hood. If Angular2's render process is not compatible with jQuery or vanilla JS, then it seems work is needed in Semantic-UI-Angular2. Though, I did a lot of jQuery integration in Angular 1 and it is claimed that "using jQuery from Angular2 is a breeze compared to ng1."

If jQuery were removed, what is the proposed replacement JS that would solve Angular2 issues?

Is Removing jQuery Worth It?

I agree it is better to not depend on jQuery. But, I haven't see a valid pragmatic argument that justifies the cost of rewriting the entirety of SUI jQuery to vanilla JS. It would take a team several months and introduce new bugs and browser compatibility issues. Compatibility issues would have to be solved with the same browser APIs and logic that jQuery is solving them with. This effort would remove jQuery only to then rewrite all the parts of jQuery that SUI is using (which is most of it). This doesn't seem like time well spent.

Even if completed, if your framework of choice does not play well with DOM manipulation, then this effort offers no gain to you.

Proposal

Specialization

I believe the more beneficial approach is to keep core SUI just as it is, a great framework for traditional HTML/CSS/JS applications. Allow frameworks and libraries to use any of the HTML, CSS, or JS that their paradigm allows. Semantic-UI-Ember for example is a thin wrapper on top of SUI, whereas Semantic-UI-React has no jQuery nor SUI JS at all.

Less talk, more do

Action is the best way to affect change. Lead the charge, if your endeavor has merit, others will help. Props to @avalanche1 for trying to coordinate action in https://github.com/Semantic-Org/Semantic-UI/issues/3981 to remove jQuery. So far, it appears people do not truly want to remove jQuery and are only willing to cavil about doing so.

Smaller, Focused, Bite-sized Efforts

We need to narrow this down. Proposing a massive task like "remove jQuery" as a blanket solution to size optimizations, React/Angular2 integration, and mobile performance is not a valid approach. It is too broad to accomplish anything.

If the issue is package size, there should be an issue focused on this alone. It should include a detailed analysis of SUI package size and incremental steps to improving that.

If the issue is speed, there should be an issue focused on this alone. It should include perf analysis and a hot list of areas to fix.

If the issue is mobile performance, there should be an issue focused on this alone. It should include mobile perf analyses and a prioritized hot list of areas to improve.

Finally, if the issue is integration with a particular framework or library, first check the existing integration repos in Semantic-Org. If there one missing, open an issue focused on this integration alone.


If the community really cares about these issues, I believe this is a more effective approach to take. Otherwise, it looks more like removing jQuery for the sake of removing jQuery and grasping for justifications.

jmcclell commented 8 years ago

@levithomason I actually generally agree with you here. As I said in my post, I do not know of how one could fix the issue of compatibility/inter-op with modern JS frameworks. The existing hooks are certainly a step in that direction.

I think it's a larger issue, and not one that Semantic alone faces. It's not the dependency on jquery, it's the requirement to manipulate the DOM for some of the UI functionality. Is there a way of doing that which would be more compatible and flexible than the current way? I don't know the answer to that question.

Removing jquery, in and of itself, as you point out, is not really solving anything.

Enelar commented 8 years ago

@jmcclell on any jQuery site try to store some selector in variable, and then replace body content. And then try to find child/parent etc, on removed element. You will notice that they do not have html parent, but they are still present. Because they are in DocumentFragment. (Google Chrome 54). Documentation update is pending: https://github.com/jquery/learn.jquery.com/pull/725

So jQuery perfectly works with DocumentFragment aka "VirtualDom"

jmcclell commented 8 years ago

@enelar I think perhaps you've misunderstood the issue. The problem lies in the reverse. If my purely functional JS framework's VirtualDom representation expects the real DOM to look one way, but jQuery has modified it behind its back, I've now got a VirtualDom that is no longer in sync with the real thing.

How much trouble this actually can or does cause, in practice, is debatable, but it's a problem that exists.

Even in the direction you refer to, if I re-render the real DOM via my VirtualDom-based renderer and it overwrites the real DOM, even if jQuery's variable still has a stored copy of the previously rendered DOM fragment in memory, it's not very useful if, say, that fragment is where I've placed my hook for something such as a dropdown action.

Currently, in order to use Semantic UI with Elm, I am using a small hack where I continually listen for DOM change events in jQuery and re-apply .dropdown(), .checkbox(), etc. methods to the appropriate selectors when they are added/removed so that Semantic continues to function.

Enelar commented 8 years ago

@jmcclell sounds like bad designed framework. Let me explain. With jquery it is ok to create elements:

var my_var = $('<div></div>');

And you just created real thing. It yet not attached to DOM but its real.

$(document).append(my_var);

my_var.detach();

Your expectation that jQuery working with DOM-attached elements only, is wrong. As long as i remember, wrong since jQuery 1.1. So i disagree with your point.

I could give my_var into your_function(my_var), and you should never assume that it attached to "real" DOM. It just matter of encapsulation. BTW it is huge offtopic, knock at my email pls.

jmcclell commented 8 years ago

@Enelar It is off-topic, agreed. I've no need to continue the conversation, however. It just appears that we are mis-communicating with regard to terminology more than anything, eg: VirtualDom.

levithomason commented 8 years ago

@jmcclell The issues you are facing with Elm are identical to what we faced with React. Both use a similar virtual DOM implementation. We also tried to use SUI jQuery lifecycle methods to sync the two, but in the end, it just isn't practical (especially for the dropdown). IMO, the best path forward at this point in web history is to create Semantic-UI-Elm repo. Unfortunately, React and Elm use different virtual DOM implementations so we couldn't reuse Semantic-UI-React code.

I do agree it would be awesome to somehow abstract SUI hooks to support any choice of render stack. Something akin to moving SUI core to a DOM-Hook-Only based architecture with adapters for React Virtual DOM, Elm virtual-dom, and jQuery. I'd be super interested in pioneering some research with you if there is enough community interest in this. Basically, a generic JS component specification.

levithomason commented 8 years ago

Apologies for continuing an off topic discussion. However, @Enelar's comments while bold are completely incorrect. I'm afraid they're severely misleading to others.

Real vs Virtual DOM (TL;DR below)

The distinction between the real DOM and Virtual DOM has nothing to do with what was said. They are entirely separate APIs and data types.

The Node is the base interface for most DOM types. The Element inherits from Node and represents an object of a Document. The HTMLElement inherits from Element. Finally, the HTMLDivElement inherits from HTMLElement.

Therefore, a <div> is the real DOM because of it's type. Regardless of what created it, what memory references it has, or whether or not it is attached to another node. It is a document object of type HTMLDivElement, an instance of Node.

The DocumentFragment also inherits from Node, which by definition makes it exactly the real DOM. Stating "DocumentFragment aka 'VirtualDom'" is equivalent to saying "String('1, 2, 3') aka an 'Array'", just because it is a comma separated list. It couldn't be more "not an array".

jQuery operates only on the real DOM

jQuery is just a wrapper around browser APIs. Both create real HTMLDivElement objects, instances of Node:

var jqDiv = $('<div></div>')[0]
var docDiv = document.createElement('div')

console.log({}.toString.call(jqDiv))
console.log({}.toString.call(docDiv))
//=> [object HTMLDivElement]
//=> [object HTMLDivElement]

console.log(jqDiv instanceof Node)
console.log(docDiv instanceof Node)
//=>  true
//=>  true

Then what is the Virtual DOM?

In loose terms, the real Document Object Model is an API and set of types for working with Document objects (for us, the browser's document). Loosely, the Virtual DOM is an API and set of types for creating plain objects that only describe what a real document looks like. You are creating virtual document elements that represent real document elements. You never actually create an element that inherits from Node nor does it live in a real document. Virtual DOM elements are just plain JavaScript objects.

This is true of both the React (Virtual) DOM and the virtual-dom project which powers Elm.

Notice, the API for creating elements is not the same nor are the returned elements the same type as browser document elements. They're just objects.

var reactDiv = React.createElement('div')
console.log({}.toString.call(reactDiv))
//=> [object Object]

console.log(reactDiv instanceof Node)
//=> false

TL;DR / Conclusion

The real DOM is made up of instances of Nodes and includes the browser document and it's elements. jQuery is an abstraction on top of this API. The Virtual DOM is made up of plain objects that describe what a real document should look like. They are two completely separate APIs with completely separate types and objects.

Neither jQuery nor the browser have an API for creating virtual DOM elements. Virtual DOM solutions do not provide APIs for directly creating or manipulating real DOM elements.

For clarity, none of this has anything to do with the native Shadow DOM utilized by Angular2.

levithomason commented 8 years ago

.....aaaaaaaand, I think we should close this issue and open little tiny focused issues where we can get stuff done 👯

controversial commented 8 years ago

Right. Creating nodes that aren't in the main DOM isn't a special jQuery feature, it's present in vanilla JS with document.createElement. This capability is not what is meant by virtual DOM, @Enelar

sethlivingston commented 8 years ago

Agree with @levithomason haha, but will add: Maybe SUI's primary contribution is a specification for how UI components should be constructed and styled and implementations are left up to different projects. Question is, what form would that specification take?

levithomason commented 8 years ago

I'm not completely sure of the spec or abstraction, but I think of how SUI has brought consistency and beauty to component markup via a semantic language. It would be interesting to explore something similar for the behavior of components.

Naive first ideas come in the form of defining lifecycle hooks and events for components and their component parts. If this abstraction could somehow be implemented, perhaps adapters could be made from it. Each adapter might wire SUI spec'd component life cycle hooks and events into a React component, an Elm component, or jQuery selectors/methods.

Seems the abstraction would be responsible for associating html classes to components and component parts. This way, the abstracted interface could inform an adapter that when the menu receives click then the new classes are menu active and the component is in the "menu-open" state.

This is obviously contrived and incomplete, but I hope it gets the rough idea across. Generically associate components/component parts, with their events, classes and a given set of states. Then, allow the implementing framework/library to ingest the spec and create the components.

jmcclell commented 8 years ago

@levithomason This is exactly what I was half-baking in my brain. I don't have a grasp on what it would actually look like, but intuitively I feel like we can do better - that such an abstraction could be created.

levithomason commented 8 years ago

Cool, I'm seeing it now. If you wanted to start a repo testing this idea out, I'd be willing to try and help grow this fragile idea to see where it goes.

Ryuno-Ki commented 8 years ago

Sounds interesting. It would be interesting to mention this issue on that repo/put a link to it in here.

hendricha commented 7 years ago

Random question: How would (Could?) stardust function with https://github.com/Matt-Esch/virtual-dom or would it require React?

levithomason commented 7 years ago

Stardust is a set of React components that render to valid Semantic UI markup. React has its own Virtual DOM implementation. So, Semantic-UI-React (Stardust) uses React's Virtual DOM. There is no way (or reason) as far as I am aware to switch the Virtual DOM implementation to the one by Matt-Esch.

It is worth noting, virtual-dom claims to have been inspired by React:

Original motivation

virtual-dom is heavily inspired by the inner workings of React by facebook. This project originated as a gist of ideas, which we have linked to provide some background context.

So, they are similar in approach and spirit. Though, I don't think you'd want to try to replace one with the other.

ansarizafar commented 7 years ago

VueJS is simple and next jquery. Semantic ui written with Vuejs +1

dreampod commented 7 years ago

We have done all the components as described without using jQuery. In it's current state it is designed to work on react-rails but when it's out of beta and we can release the npm / gem package and it could become open source. The roadmap for us is not very clear yet, but I appreciate the Semantic-UI react project even more as we have had to solve a lot of the same problems :)

levithomason commented 7 years ago

@dreampod would love to collaborate on any possible React component problems you've run into and solutions you've implemented. We now have nearly 100% component support. We continue to grow in stars and collaborators at a regular rate as well.

ivantcholakov commented 7 years ago

I think that a jQuery-based repository should exist in the future anyway. Have a look at Aurelia framework, it seems to offer progressive code transition without conflicts with jQuery.

levithomason commented 7 years ago

Agree, see https://github.com/Semantic-Org/Semantic-UI/issues/1175#issuecomment-229401450. Though, this is not feasible with React specifically. http://react.semantic-ui.com/introduction#jquery-free.

Jack is working toward some really great long term standards for the web, specifically, a UI component spec. I'm hoping it takes root and is adopted. If so, it will lend itself exactly to something akin to https://github.com/Semantic-Org/Semantic-UI/issues/1175#issuecomment-244635034.

Speaking of ^ @sethlivingston, in a recent email chain with Jack he indicated he is working on precisely this. Pretty exciting.

franciscolourenco commented 7 years ago

By implementing using react you are replacing one dependency with another.

On 2 Dec 2016, at 23:49, Levi Thomason notifications@github.com wrote:

Agree, see #1175 (comment). Though, this is not feasible with React specifically. http://react.semantic-ui.com/introduction#jquery-free.

Jack is working toward some really great long term standards for the web, specifically, a UI component spec. I'm hoping it takes root and is adopted. If so, it will lend itself exactly to something akin to #1175 (comment).

Speaking of ^ @sethlivingston, in a recent email chain with Jack he indicated he is working on precisely this. Pretty exciting.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

italomaia commented 7 years ago

What about making semantic-ui jquery-slim compatible first, then, work your way down ... ?