Hacker News new | past | comments | ask | show | jobs | submit login
Making Web Components Work (mixpanel.com)
159 points by tdumitrescu on June 12, 2018 | hide | past | favorite | 111 comments



I've been using web components in production for a while now and it's great. Our front end "stack" consists of a single polyfill and Webpack. Use template literals for templating, so you don't even need handlebars/mustache anymore. Webpack lets you write SASS that is compiled directly to CSS and inserted in your shadow DOM with an ES6 import, so no more style sheets for anything but high level page layout. Everything is standards based web components written in vanilla ES6, transpiled for browser compatibility down to IE10.

One major issue we've had though, which wasn't touched in this article, is inter-component communication among siblings. Sure you can just do a global event bus, and that works, but I've yet to see an elegant solution for this yet.


>> Use template literals for templating, so you don't even need handlebars/mustache anymore.

You can do better than template literals. You can use TSX, which gives you compile-time verification for tags and attributes, in addition to JavaScript expressions.

See: https://github.com/wisercoder/uibuilder

With TSX (which is JSX written using TypeScript, you get things like syntax coloring and indentation for tags, because HTML and JavaScript are both first-class citizens in TSX.


I’ve only been using React for a few weeks but the comparisons on that page to React are FUD and the incompatibility with web components is just plain wrong and mixing them is covered here https://reactjs.org/docs/web-components.html


According to https://custom-elements-everywhere.com/ React has a way to go for full support.


From the page you linked: "Events emitted by a Web Component may not properly propagate through a React render tree."

React components are brittle, that's not FUD. For example, CSS classes used by React components can clash with other React components, or with the page that includes them. What's FUD about that?


That's misunderstandong of the technology. React has nothing to do with styles, it manipulates DOM. Handling styles is up to you, and it's extremely easy to use CSS modules.


>> React has nothing to do with styles

That's one of its limitations.

React is a component technology and doesn't solve the problem of clashing styles, element ids and so on. Web components is a component technology that does.


No, it's not a limitation, it's called separation of concerns, I don't want my component framework interfering with the job of Webpack or application runtime. I want to use my preferred (also easy, standard, ...) solution.

> clashing IDs

React solves that one, not through namespacing though. You never need to use IDs with React.

> clashing styles

React gives you power to solve this one by your preferred solution. You can use expressions in your JSX, and thus it's very easy to do one of the following:

- Generate optimal global CSS stylesheet with no code repetition, generate classnames on the fly (https://github.com/typestyle/typestyle)

- Import your CSS file as a module using Webpack - classnames are guaranteed to be unique; additionally, similar approach as TypeStyle (global optimal stylesheet) can be set up

- Use just "inline" styles (preferably not really inlined in your JSX) since React will keep it updated for you as well


Not doing anything about CSS isn't separation of concerns, it's just a leaky abstraction. Separation of concerns implies some work was done to achieve some level of decoupling that would otherwise be tighter.

In fact, the criticism that react components can have style clashes is precisely one of not having enough separation of concerns. The fact that there are numerous libraries to address that deficiency further indicates that react as a platform is severely affected by the underlying level of abstraction when it comes to styling.

It's fine to defend a technology you like but calling a weakness a strength does nobody any favors.


Styled-Components gives you efficiently “inlined” styles (creates unique CSS class used only by instances of your component) and doesn’t affect global CSS. It’s up to the developer to avoid polluting with global CSS and that’s honestly not very difficult.


>You never need to use IDs with React.

If you don't care about accessibility then yes.l, but try using properly annotated aria attributes without appropriately scoped ids(which you can do in react, but it's not free).


Hmm, right now I truly don't (that's the business requirement :-/). I'll investigate, thank you.


If I read parent's comment correctly, the notable thing was simplicity via few dependencies. I expect parent knows about J/TSX.


Panel can use any hyperscript based templating language. Virtual-jade, tsx, jsx, just h() calls.

It’s pretty flexible and thin.


Never heard of hyperscript before today, thanks for the pointer.


Vue discourages 2-way binding between components and instead suggests binding data down to children and requiring children to emit events up to their parents to request shared state mutation [0]. I'm not sure how elegant it is, but it seems logical to delegate the responsibility of state management to the components that originally provide the data.

[0]: https://vuejs.org/v2/guide/components-custom-events.html#syn...


The data-down, events-up architecture is fairly popular not just with Vue but React, Ember and other frameworks as well. The main criticism of it (at least in React-land) was that you ended up with a lot of noise from having to pass unrelated things up and down from intermediate components. This is what React context and higher-order components were meant to address when they were conceived.


> One major issue we've had though, which wasn't touched in this article, is inter-component communication among siblings. Sure you can just do a global event bus, and that works, but I've yet to see an elegant solution for this yet.

Would Redux potentially be a good fit? It's a "global event bus" kind of thing, but with a pretty clear information flow model and an increasingly large user community. (Both of which are good things, IMHO.)


Event bus is how things often ended up getting done in Angular 1, and definitely not something I'd want to maintain (because you end up with comefrom-hell type of issues).

Redux feels like a step in the right direction conceptually with its centralized state bag, but I feel like it's a bit distracting (since it was primarily conceived to handle serializable actions for a very specific use case), and also doesn't have good patterns out of the box to organize side-effects (sagas kinda do, but people I've worked with are fairly divided on whether it works for them or not)

Recently I've been thinking that a lot of the complexity around React+Redux comes from wanting testable state, but as it turns out, Jest can mock imports making the entire context shenanigans somewhat pointless - just import a global state bag. I've had pretty decent success with just having a naive global state bag, would love to hear about similar approaches


I've been using MobX (https://github.com/mobxjs/mobx) in my day job for a year now in a very large client-side app, and hands-down prefer it to redux.

Initially I was wondering why we didn't have a centralised store, but once free from that mindset it allows you to keep observable data locally to where it's needed. Much nicer for encapsulation and separation of concerns.

Far less boilerplate too, as MobX does some very smart usage & dirty checking for you.

mobx-react also provides an @observer class annotation, which ends up working pretty magically - things re-render when they need to.

If anyone's interested, here are some tutorials from the author: https://egghead.io/courses/manage-complex-state-in-react-app...



Arguably siblings needing to communicate is "code smell". Is there a way to restructure so that this isn't needed?


Some unnecessary downvoting occuring, go easy.

In a discreet component architecture there is basically no reason for arbitrary siblings to know anything about each other - if there is common state to be shared it should be inhereted.

Granted, in JS land that sometimes involves jumping through weird IoC hoops or cached callbacks, which are akward to say the least, but in the abstract an instance of a component should be concerned with its own behaviour, and possibly that of it's descendents by way of that behavior.


> One major issue we've had though, which wasn't touched in this article, is inter-component communication among siblings.

The way we typically handle something like this is by connecting components through a common ancestor. The default naive behavior of Panel apps is for linked components to share a "centralized state bag" (as one of the other comments calls it re: Redux), and updates to that state automatically cascade to all the components. It's a blunt, easy and lightweight way to propagate changes arbitrarily throughout an app, but it does get unwieldy as the state object gets big so we've ended up with some mechanisms for partial state-sharing to address this issue.


For inter-component communication, sounds like redux would be a big help for you. Polymer has a mixin you could use: https://github.com/Polymer/pwa-helpers/blob/master/connect-m.... You're not using Stencil, but if others do, it has a redux connector or a simpler state tunnel system for passing state to child components (https://stenciljs.com/).


No, don't use Redux everywhere. Most applications don't need to manage client-side state. State lives on the server. If your application lets the user edit stuff without immediately sending the update to the server then you may have state, otherwise you don't and you don't need a state manager.


Perhaps if your app is just a series of request-response style CRUD forms, at which point why bother using a front-end framework in favor of server-side templates / forms. Toss in jQuery if you want some AJAX.

Tossing in Redux (or whatever Flux-like flavor of the day) is a low-effort, high-value add on top of React and obviates the possibility of some bat-shit data-passing situation that would make an OO inheritance junkie blush.

If you're the sensitive to boilerplate type, there are some simple libraries to solve that issue. Unless you're tossing together a three component TODO list demo, not using Redux will just bite you in the ass a year down the line in maintenance costs as your application grows.

This is really starting to remind me of the "Don't worry about the data model, just toss it in Mongo!" all over again.


Did you start developing apps, like yesterday? Patterns such as MVC have been around for decades and used in many different platforms such as web and mobile and did not need anything like Redux or Flux. Are there new problems that cropped up recently that needs Redux or Flux? It is youngster devs who haven't seen anything more than React that makes statements like "not using Redux will just bite you in the ass a year down the line".


No, but not respecting your data model will certainly bite you in the ass. Sweat now, or bleed later.

When I see folks saying, "Oh just deal with it in the components" I have to assume either A) they're working on an extremely small, self-contained piece (which is fine) or B) they're not bothering to think about their data from the get-go.


Bothering to think about your data from the get-go doesn't mean you need actions and reducers. We don't have a new problem today that didn't exist 10 years ago. iOS apps don't need actions and reducers, so why do web apps need them? When you have a hierarchy of components information should flow down that hierarchy. If each component grabs and updates info directly from the store you are violating the encapsulation of hierarchical components.


Facebook developed flux since they had a lot of problems with MVC.


I've been using a similar approach for the last year, and I find that most problems are much easier to deal with because of less crud in the build flow. There is currently a W3C proposal for template instantiation that showcase some conveniences to deal with templates in components, could be good, could be bad. https://github.com/w3c/webcomponents/blob/gh-pages/proposals...

Most communication I solve by custom event dispatching or attribute callbacks, but there are the odd cases, especially regarding more advanced drag/drop, that still requires state at some level. Do you have any concrete example of inter-component communication to look at?


> Use template literals for templating, so you don't even need handlebars/mustache anymore.

Are you using some template tag function that handles escaping? Seems risky to rely on manual escaping everywhere.


I still find it bizarre that no one has stated the obvious yet:

Having a component tree (because the rendering model of a browser requires it) does not mean state management needs to be cramped into the same tree or use a tree in the first place!

A DOM tree itself doesn't do any kind of binding and it doesn't do inter-component communication. (it merely offers events) Why should web components? Keep them as dumb as DOM nodes please.

A lone H1 element doesn't register itself on some event bus, doesn't observe attribute changes and doesn't create odd 'actions' tied to some obscure state management system. And it shouldn't.


I only recently started looking at upgrading from angularjs to angular and web components were one of the things that made me question the emporer's clothes..

Zone js implements zones and by that they apparently mean exactly 1 zone.. making a supposed abstraction where you can't safely add 2 implementations of web components (or apps?) to 1 page without planning for that with 1 global setup for them..

My initial impression of shadow DOM is that I would get the same scope separation as iframes with a nicer method of passing data and describing the layout.. Then I assumed web components were this missing piece finally implemented.. now I'm wondering if I completely misjudged and everyone else really wanted a complicated footgun where seeming builtins are colliding with your namespace?


I was with you until the second paragraph, but DOM elements do sometimes have non-dumb semantics (e.g. <label for="foo">, or <a href="#foo">). There's also a very good reason we have templating languages to loop over table rows.


You don't have to do state management this way, sure, but this functional reactive style of state management has its own set of compelling benefits, like making it easier to reason about side effects and complicated state.


For me, the biggest plus of web components is the potential simplicity of unifying the document's object model with that of your application. Every JS framework, like React, Angular, Vue, etc. seems to have a parallel OM that either wraps or renders into the DOM (Angular seems to have about 5 of them).

The result is your can never just use the basic DOM APIs and devtools to inspect and interact with your application's components. Instead, you always have to get at them through some other API, and understand how the UI and state you see in the DOM is produced and updated by some mediating layer (virtual DOM, view hierarchy, etc.). It feels like trying to get at the truth by talking with two different people, who each only possess a subset of the facts.


These layers were created for efficiency, not for their own sake; there’s no “DOM transaction API”, so every DOM mutation causes a reflow. Thus, you mutate a virtual DOM, render the resulting changes to a new subdocument, and then replace an existing DOM node with that new subdocument.


Incorrect. This idea was a result of some early React users misunderstanding the purpose of the virtual DOM, and has unfortunately been thoughtlessly repeated ever since.

In reality, browser engineers are not that stupid. Mutating the DOM will queue a layout operation, but it will not actually occur until the current JS task has finished executing. Within a JS task, such as an event handler, an XHR completion, or a setTimeout, you can mutate the DOM as many times as you like, and it will only result in a single layout pass.

(The exception is if you try to read back some measurement from the DOM, such as an element's bounding box, after mutating it. In this case, the browser does have to block while it performs layout, but that is not something can be solved with virtual DOM).

So, what is the purpose of the virtual DOM? It was invented to allow React to provide the illusion of full re-rendering. React's authors wanted to a provide an experience similar to that found on the server, where an entire HTML page is re-rendered from scratch for every load. In that way, there is never any possibility of part of the HTML becoming stale, as it all gets recreated from scratch each time.

However, the browser DOM is not designed to be blown away and recreated from scratch all the time. Nodes are expensive objects, spanning the JS and C++ worlds. Recreating the whole DOM tree each time any part of it needed updating would be too slow. So, instead, they created the virtual DOM as an intermediate data structure. React renders the virtual DOM. The virtual DOM is diffed against its previous state, and then the changes are applied to the actual DOM tree. In that way, every component's render() method can be executed, but only those parts of the DOM that have actually changed will be updated.

It's a nifty optimisation, but it's not about avoiding reflow, it's just another method of dirty checking, similar to that done in other frameworks like Angular or Ember. It's just that React chooses to diff the data structure produced by render(), rather than diffing the model data that is later used for rendering.


Please read this blog post titled "How to win in Web Framework Benchmarks" https://medium.com/@localvoid/how-to-win-in-web-framework-be...

It goes into some details how different approaches in different frameworks work, and why. Moreover, it shows how you basically need to re-implement Virtual DOM and other tricks in vanilla JS code to approach the same speed.

Yes, browser engineers are not that stupid. But they don't batch operations as efficiently as a proper Virtual DOM implementation would (including efficiently handling event listeners, looking for clues like `keys` on repeating DOM elements etc. etc.).


That article doesn't quite support what you're claiming. The Vanilla JS implementation uses optimised DOM mutation techniques that are inspired by how the Virtual DOM libraries do things, but it doesn't re-implement a Virtual DOM. Yet it's faster than any of the Virtual DOM implementations its benchmarked against.

So the takeaway is that DOM mutation can be slower or faster depending on the techniques you use. Using a Virtual DOM library can help you improve performance, because these techniques are often baked in, but they don't intrinsically result from using a Virtual DOM: You could write a V-DOM library that didn't use them, and was slow, and you could write, for example, a static template library that did, and was fast.

In theory, a compiled, static template approach should be faster than V-DOM (or anything other than a set of totally bespoke and optimised vanilla JS functions for each app operation). Because while a compiled template does not have the turing-complete flexibility of something like JSX, it has the advantage of knowing in advance exactly which parts of the DOM can change and how, which eliminates the need to build and diff the Virtual DOM tree.


> In theory, a compiled, static template approach should be faster than V-DOM

Maybe faster in basic microbenchmarks. As soon as you start optimizing UI library for complex applications, there are many other optimization goals you should focus on, like the size of the generated code per component type, the amount of different code paths(increase probability that executed code is JITed), etc.

Virtual DOM solves many issues, it is not just diffing, it is also a lightweight component model, possibility to add lightweight synthetic events, single code path for creating/updating/destroying DOM nodes, the simplest algo that handles complex tree transformations, etc.


> Moreover, it shows how you basically need to re-implement Virtual DOM and other tricks in vanilla JS code to approach the same speed.

Surplus [1] is the fastest in most benchmarks, and it doesn't use a virtual DOM.

[1] https://github.com/adamhaile/surplus


Couple of small changes to the surplus benchmark implementation[1], and it is not the fastest anymore[2] even when benchmark is super biased towards fine-grained direct DOM manipulation libraries like surplus (ratio of data binding per DOM elements ~0.5, number of DOM elements 8000-80000)

1. https://github.com/localvoid/js-framework-benchmark/commit/1...

2. http://rawgit.com/localvoid/js-framework-benchmark/sandbox/w...


I'm not sure what table you're looking at, but at those links Surplus is still the fastest only behind vanilla JS.


https://i.imgur.com/MG3eGTM.png

Inferno here is also slightly patched[1], instead of using stateless components, it is using stateful components to demonstrate how fast it can go down when you start using high-level abstractions in a library that focuses only on low-level primitives.

And if you really want to understand the fundamental flaw in libraries with fine-grained direct data bindings, try to reimplement this[2] 70 lines of React code with such library.

1. https://github.com/localvoid/js-framework-benchmark/commit/2...

2. https://github.com/localvoid/uibench-react/blob/master/js/fc...


Ah, I forgot to check Ivi. Still, Surplus, Ivi and vanilla JS are the top 3. Clearly the virtual DOM is difficult to optimize. Surplus is itself also largely unoptimized because it largely didn't need to be at the time. I had a discussion with the author on incremental reduce optimizations in the S.js issues section.

Anyway, I have nothing else to say on the matter. Clearly anything with only 10% overhead over vanilla JS is definitely fast enough, and Inferno is there now if you want something React-like.

As an aside, do you have any experience with Ivi? I'm looking to learn something else and wondering if I should dig into Web Components or something like Ivi. Web component performance was terrible last I checked.


> Clearly anything with only 10% overhead over vanilla JS is definitely fast enough

And now is the main question :) If virtual dom is competitive in benchmark that is super biased towards direct data bindings libraries, what is the point of using direct data binding solutions when they won't be able to handle even basic use cases that involve client-server communications when server sends data snapshot. There won't be any information about data changes, and you'll end up with reimplementing tree diffing algo, so that you can apply it to the data.


> what is the point of using direct data binding solutions when they won't be able to handle even basic use cases that involve client-server communications when server sends data snapshot.

I'm not sure what you mean. Surplus is built on S.js, in which all data is lifted into reactive expressions. S.js already handles that for you but at the data model level, where it arguably should be, not at the UI model level.


> S.js already handles that for you but at the data model level

It only works as long as it is able to track changes, many client-server applications doesn't send you list of changes that you should apply to your data, they just send you data snapshots. With virtual dom library I'll just update my data and rerender everything that depends on this data, with direct data bindings good luck figuring out solution to such simple problem.


> With virtual dom library I'll just update my data and rerender everything that depends on this data

So you have to visit every data node, and then also visit every changed UI node. Where if you have deltas, you only visit changed data nodes and then changed UI nodes.

Re: data snapshots, it's easy to design your own service to use a delta protocol. But even when you can't, you can separate the code used to construct your reactive objects from the code that initializes them. This is just basic function abstraction, and it doesn't really add any work. From the example on S.js site:

    const                                // 
        a = S.data(1),                   //     a() |   1     3     3     5
        b = S.data(2),                   //     b() |   2     2     4     6
        c = S(() => a() + b()),          //     c() |   3     5     7    11
        d = S(() => c() * a()); // t0    //     d() |   3    15    21    55
    a(3);                       // t1    //         +------------------------>
    b(4);                       // t2    //            t0    t1    t2    t3
    S.freeze(() => {                     //    
        a(5);                            //    
        b(6);                            //    
    });                         // t3    //
Now becomes (quick and dirty to convey the idea):

    const
        a = S.data(1),
        b = S.data(2),
        c = S(() => a() + b()),
        d = S(() => c() * a());
        update(3, 4);
        S.freeze(() => update(5,6));

        function update(aval, bval) {
            a(aval);
            b(bval);
        }
S.js will detect whether the value you're providing is actually different, and will only propagate what has changed. Roughly the same number of lines of code, just more reusable.


Sorry that I can't clearly explain this problem to you, and you obviously don't understand about what I am talking. Maybe you can try to think about ordered lists and complex data transformations, not just basic values.

Or maybe I can just ask you one more time to reimplement this[1] 70 lines of React code with Surplus, but you are probably will just ignore it :)

1. https://github.com/localvoid/uibench-react/blob/master/js/fc...


I've never worked with React, so that code is just noise to me right now.

In any case, there's no inherent difference between basic values and ordered lists and data transforms. The latter two are just recursive application of operations on basic values.


I am finally figured out how to do it with Surplus :) Its documentation is super confusing, first it talks that there are no lifecycle hooks, but then I see lifecycle hooks[1], then it talks that there are no diffing, and then I see inefficient diffing algo[2].

It won't be so hard to solve use cases that I am talking about. Just create an index(HashMap), implement simple diffing algo that updates hashmap index and doesn't care about item positions, then from the ordered list generate a new list with values from the hashmap index, and then apply this inefficient diff algo that uses object identity to track objects[2].

1. https://github.com/ismail-codar/surplus-material/blob/3dce38...

2. https://github.com/adamhaile/S-array/blob/1046fca3032691d4ef...


When you don't have any information how ordered lists were transformed(data snapshots), there is a huge difference between basic values when you can assign the latest value, and ordered list where you need to figure out how to rearrange items in observable array, so that it will be able to track changes and rearrange DOM nodes.


It seems odd to characterize a declarative approach to rendering as an optimization.

The draw for me is that I don't need to manage the state of a bunch of DOM objects anymore. I wouldn't even mind if React were slower- the performance isn't really the point.

I don't and will never want web components for this reason.


You can use vdom in web components. This article, that you didn't read, talks about using one.


Virtual DOM isn't what makes things declarative. You can solve the same problem by diffing the model instead of the render output- the important part is that you have a comprehensive way to tell what parts of the view need to change.


> It's a nifty optimisation, but it's not about avoiding reflow, it's just another method of dirty checking, similar to that done in other frameworks like Angular or Ember.

There's also a lot of "implicit state" not captured in such a virtual DOM, like the user's current selection, the scroll position, form values, and so on. If these are blown away, it creates a really poor experience. The virtual DOM isn't just an optimization, it is actually a correctness fix.


> there’s no “DOM transaction API”, so every DOM mutation causes a reflow

Perhaps there should be. Has there been any discussion on standardizing such a thing?


I just started using Web Components, and in my opinion, their future is definitely very bright. Now that HTML imports have been squashed, they're basically just standard JavaScript objects imported as modules, as they should be. Before, you created a class/object that had a property like foo.el which was the element it was associated with, but the link was tenuous, and required a bunch of code to keep things in sync, and various component styles could easily clash. Extending native elements and the Shadow DOM is a great way to contain everything. Wiring them up to something like Redux or MobX is trivial.

The only real missing piece is the concept of props over attributes. If I want to pass an array of ids to a sub-component declaratively, there's not really an easy way to do it. Hopefully there will be some consensus about this soon. The best thing is that this is all part of modern browsers without libraries, or even precompilation. Not every web app needs massive libraries, so having web components as a built-in, light-weight component system is fantastic.


> The only real missing piece is the concept of props over attributes

Plenty of HTML templating languages allow for setting properties declaratively. Polymer, lit-html, Vue, Angular, all do.

For instance, in lit-extended (an extension of core lit-html), properties are set by default, attributes have a '$' suffix, and event handlers have an 'on-' prefix:

    html`
      <my-element
        aProp=${foo}
        an-attribute$="${}"
        on-click=${clickHandler}>
      </my-element>
    `;


You're right, but because it's not part of the standard, there's various implementations. This is what I meant about consensus.


The standard side of things is just that DOM Elements have a JS interface with properties. That there are many ways to set properties on JS objects, with template systems being just one of many.

I'm not sure that HTML itself will get a standard way to set properties, even with the Template Instantiation proposal. Encoding the intent to set a property is hard given that all valid attribute names are already valid attribute names, and could have current semantics. Adding new support for currently invalid attribute names sounds like a very difficult thing to do.

This can stay at the level of opinionated libraries. You learn how to use that library and it's method for setting properties, and you don't have to worry about other components choices for templating.


Well, it seems like a basic problem that everyone runs into pretty quickly when they start putting components together. Think of an Android RecyclerView created as a web component which lets you scroll through a large dataset. The parent component needs to be able to pass a reference to an array of content. This can be done programmatically easily enough, but not in a declarative way.

(BTW, lit-html is really well done. I look forward to seeing its progress - LitElement could really be the underpinning to a standards-based competitor to React, which is a very welcome thing in my opinion.)


> If I want to pass an array of ids to a sub-component declaratively, there's not really an easy way to do it.

This seems like a framework layer feature and not something that should be baked into the standard. I don't think web components are supposed to act like a framework and optimize a particular workflow or programming style.

I think the way snabbdom implements props just assigns Javascript properties to the DOM object.


Personally, I'd love to see HTML add a standard way to refer to the value of JavaScript objects in memory. This is already done (badly in my opinion) with the blob:// url you can pass to media elements. Declaratively defining an element with a live JS variable for attributes would be very useful in lots of ways, and not specific to any programming style.


>> If I want to pass an array of ids to a sub-component declaratively, there's not really an easy way to do it.

Yes, there is. See https://github.com/wisercoder/uibuilder


Err, no. What part of that mass of crazy non-JavaScript did you think was "easy"? Wow. I didn't even know TSX was a thing. To each his own, but yet another dependency written in indecipherable pseudo-script (regardless of its popularity) is not my idea of easy.


If you're going to flog your pet project repeatedly, you should at least provide a substantive response around it. This comment provides no value. It's just an ad.


Web Components were interesting but too complicated and never gained traction at Autodesk (my former employer) where we just ended up going with React, which is actually a pretty good solution to the crappy ecosystem that browser based programming has become.


I read Polymer is switching to JS modules with 3.0, sounds like a right step for Web Components :)


We already did :)


Just started using Vue.js and the components approach makes a lot of sense. Web Components is a not-quite-ready pure JS approach? Vue, polymer, react native... I feel confused every time I read "Web Components" because it means something different depending on context.


Web Components means the standards of <template>, Custom Elements, and Shadow DOM. There's an overview here: https://developer.mozilla.org/en-US/docs/Web/Web_Components

Polymer has always been a set of helpers for making Web Components. There are others like SkateJS and Stencil.

Vue is not normally Web Components, but they have an option in CLI 3 to compile to Web Components.

React and React native have basically nothing to do with Web Components, though React can use Web Components because Web Components are just HTML elements.


> Web Components are just HTML elements.

Yup. And you can't use Polymer elements in React because React passes data as attributes whereas Polymer expects properties.

And then there's the issue of event handlers etc. etc. etc.

"Web Components" are now a largely non-intersecting collection of mutually incompatible frameworks and libs: https://custom-elements-everywhere.com

Good luck using Polymer's <custom-element binding="{{a.b}}"> anywhere


> And you can't use Polymer elements in React because React passes data as attributes whereas Polymer expects properties

This is mostly React's existing opinion that elements don't even need properties set, and is not the fault of Polymer or Web Components. Most Polymer elements are fine with simple types like strings or numbers being set as properties or attributes.

> "Web Components" are now a largely non-intersecting collection of mutually incompatible frameworks and libs: https://custom-elements-everywhere.com

That is a site that says how well _frameworks_ work with Custom Elements, ie do they make closed-world assumptions about HTML that interfere with using Custom Elements. It says nothing much about what a Web Component is, so I'm not sure how Web Components could be "non-intersecting".

> Good luck using Polymer's <custom-element binding="{{a.b}}"> anywhere

I know you troll every Web Components and Polymer discussion you can now, but this is just a non-sequitur. Polymer's template syntax is only used to implement elements with Polymer. `<custom-element binding="{{a.b}}">` would only ever occur in a Polymer template and is not intended to be used "everywhere", so no luck is needed, thank you.


> I know you troll every Web Components and Polymer discussion you can now

This is not trolling. This is called hard truths that Web Component proponents are completely blind to.

Riddle me this: why is it that there are almost no resources, blog posts, projects, or comments that talk about and use vanilla Web Components? 99.9% of posts and videos about WebComponents always immediately use Polymer, or Stencil, or... or... or...

The answer is easy: Web Components are crap, pure and simple. They are unusable in their present form. You need to throw in a data binding library, a templating library, a virtual DOM, a callback handling library, a..., a... etc. Better still, throw in a full framework like Polymer or Angular.

Even the project we're commenting on, titled "Making Web Components Work" needs the following to make them work: "does so by providing an easy-to-use state management and rendering layer built on Virtual DOM (the basis of the core rendering technology of React). Through use of the Snabbdom Virtual DOM library and first-class support for multiple templating formats".

How the hell is that "Web Components", "standards" and "work"?

When you call out all these inconsistencies, half-truths and outright lies about Web Components, you're called a troll, go figure.

---

As an aside. I remember saying that templating in Web Components is also crap because you have to use horrible DOM APIs or `innerHTML` to do anything useful. Obviously I was called a troll etc. However, when Apple proposed Mustache-like template instantiation [1] the same very people who called me a troll pissed themselves with joy and wonder. You know Web Components APIs and specs are crap. You chose to bury your head in the sand, turn a blind eye and preach how "WebComponents are the future". Well, it took browsers 11 years to get to two-thirds of jQuery's capabilities. It will take another 50 to maybe get one-third of capabilities of Web Component frameworks or React, or Angular, or Vue (hell, of even Snabbdom).

[1] https://github.com/w3c/webcomponents/blob/gh-pages/proposals...


I think the next major leap forward in HTML app development will happen when Web Components are portable across client framework types so it's not necessary to rewrite every visual element when switching from Angular6 to Vue or even something compiled to WASM in a few years.


This is exactly what Web Components already do. Web Components are just HTML elements, and generally usable in any framework or with no framework.


Oh -- awesome! I've been focused on back-end and mobile the past few years. I guess it's time to dive into Web Components!




I'll need to update that with recent developments like: no one uses vanilla WebComponents, as they are unusable. Everybody uses any number of layers on top of them: Polymer, Angular, Stencil, whatever.


I've been trying to understand why I would use WebComponents over vue/react. Like, if you're going to use a layer on top of WebComponents, why not use something like Vue anyway. Their single file components allow you to compose your templates together <my-widget>Some slot content</my-widget> etc..

I'm struggling to see the use of Web Components. And how easily it's going to be to compose WebComponents in with your custom frameworks' components, I wonder how easy that is going to be (e.g. passing props down to a web component).

It seems that you'll still be better off just picking a framework for the next wee while anyway.

Still, I'll look forward to your updated article ;)


Off topic.

Not to be harse. But for a company as big as Mixpanel, the blog UI is terrible. No branding at all and seems unprofessional.

Even more ironic is they say this as the first line in the post: "Clean, attractive user interfaces and effective user experience have always been pillars of Mixpanel’s products."

They should look at companies like GitHub, Facebook, Twitter, and the likes for an example.


You are looking at the engineering blog, which--judging by the rest of the mixpanel.com site, probably isn't borrowing much from the marketing/ux side of the company.

Check the Mixpanel blog (https://mixpanel.com/blog/) and you'll find it the brand consistency more similar to the other tech companies you mentioned.

I'm actually okay with engineers spending less time on shiny css and more time on the content of their posts.


One thing their example doesn't handle is browser location history on clicking elements in their UI.

Maybe it was due to how simple the example was, but having to click back many times based on how many times a user used the interface is just bad design.


Sorry about that, the example was developed as a standalone SPA with history for the routing. But since we decided to embed it into the blog post itself, the pushState routing doesn't make a lot of sense in that context.


Ah I figured it'd be something like that.

I'm looking forward to a future where we use web components.


They remind me too much of WPF (.net ux tech) which I never cared for. Once I moved to web dev with React I found that much simpler. Web Components seems like a step backwards to me.


The lib "does so by providing an easy-to-use state management and rendering layer built on Virtual DOM (the basis of the core rendering technology of React). Through use of the Snabbdom Virtual DOM library and first-class support for multiple templating formats".

How is this "making web components work" any different from making DOM work via snabbdom or React?


A few months ago Mixpanel notified me that they had been accidentally transmitting and storing passwords for some customers due to a UI issue. I wonder if the re-architecting had something to do with that or if it was the resolution.


Web Components are awesome. They will be the future. That said, I feel React has good future just because of React Native. It’s amazing that you can develop highly performant applications and target multiple platforms


Didn't Facebook stop using React Native in their own app (or part of it) because it's performance was poor? Or the file size was gigantic, there was something wrong...


I'm surprised that the Mixpanel engineering blog is hosted on Wordpress with the default theme. The default theme doesn't align with their designed brand, and it makes me suspicious of whether they have taken steps to secure the installation. For this low-effort of a blog, I would have expected them to use Medium.


while web components are interesting, how can you do native apps on top of it when needed? e.g. vue-native, react-native etc, or at least support by something like Electron etc.

or is it strictly a web-browser-only thing?


It's a browser spec, so yeah browser-only. Electron is browser-based (Chrome), so web-components can be used there.

Check out https://github.com/Polymer/pwa-starter-kit/wiki for concrete examples using LitElement (https://github.com/Polymer/lit-element)


i use stenciljs web component compiler. it is not a framework... it is great as it lets you do things without having to worry about browser support.


web components are never happening


Maybe not, but please don't post unsubstantive comments to Hacker News.

Edit: looks like you've been doing this a lot, and it's really not what the site is for. Would you mind reading https://news.ycombinator.com/newsguidelines.html and using HN as intended? The idea is: if you have a substantive point to make, make it thoughtfully; if you don't, please don't comment until you do.


That seems like a rather bold statement without much reasoning behind it. What in particular makes you think that web components are "never happening"?


Easy: web components have not implemented a single part of the original promise [1].

It's not Web Components that are happening, it's the dozens of frameworks required to make them work that are happening.

Even mixpanel's library "does so by providing an easy-to-use state management and rendering layer built on Virtual DOM (the basis of the core rendering technology of React). Through use of the Snabbdom Virtual DOM library and first-class support for multiple templating formats" [2]

Web Components are a very low-level extremely limited crummy DOM-based API that no one in their right mind wants to use. They are not happening.

---

[1] https://fronteers.nl/congres/2011/sessions/web-components-an...

[2] https://github.com/mixpanel/panel


This looks less than promising: https://caniuse.com/#feat=custom-elements


That's the deprecated v0 spec, fyi.



Out of the 4 major browsers, 2 major browser vendors have support for the base stuff, 1 has it behind a flag being tested ready to be turned on, and 1 doesn't have any support yet...

That's pretty far from "not happening"


It's unflagged in firefox nightlies. Edge needs to get with the picture but really they are the only one out at this point. The polyfils, while not ideal, work great and shouldn't be needed much longer. The mobile story here is actually quite strong, since all major mobile platforms have full support for it.


That's like saying "electric cars are never happening". Both already are happening.


That's ridiculous. One counter point: Ionic is going to ship web components to many thousands of app store and web apps shortly. A lot of people won't even know they are there, since they look and feel like any other framework component (if they are using Angular, for example). It's happening whether you realize it or not.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: