Except this barrier has never existed. Every HTML input is interactive: text fields, checkboxes, radio buttons. They not only remember their value, but your cursor position within them and the segment of text you've highlighted. The browser knows how far each scrollable element is scrolled, which element is in focus as you tab through the page. Forms have validation state, and can be interacted with to send an HTTP request. These days you can even do autocomplete with nothing but HTML: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/da...
The magic of HTML has never been about static layout, but about having a declarative language for building out an interface (not just a static view, but an interface). This idea that it should be nothing but a dumb view-layer is a new one, popularized by the very frameworks you're railing against. Data binding is a way to stay in that declarative space, while dramatically expanding what use-cases can be covered within it. JavaScript (in the browser) was, and always should have remained, a trapdoor for working around HTML's shortcomings. It's a Turing-complete language for doing things that can't be done any other way. Anything that can be neatly siphoned off from that more complex imperative world, should be. For the sake of complexity, for the sake of accessibility, for the sake of performance, and for the sake of compatibility.
With 150 years of evolution (at current W3C standards pace) you might get an HTML spec that is capable of expressing the behavior that users expect from present-day applications. Until then we have React et al.
I strongly disagree.
Form/<input> fields are one of the areas that a native app can slaughter HTML, even if using a WebView within an app. For example, just showing the correct keyboard layout is a nightmare, and heaven help you if you need to do something slightly custom. Another example: browsers do funky shit with scrolling and zooming on input focus. Try using the best HTML code-editor from a tablet: the editing experience sucks.
Another example is swiping, where browsers like Safari Mobile (and the old Edge) decide to navigate back/forward if the user happens to swipe from the edge by mistake - killing page state. Overriding pinch-zoom for say a photo app is doable, but sometimes ends up with invalid UI states (especially if you mix in viewport sizing changes due to orientation/ua-zoom/virtual keyboard show/tab bar show).
Disclaimer: I have spent many man-months working only on making user friendly custom <input>s in HTML, and the experience blows chunks. I have developed a custom Web UI that required too many compromises in UX.
It’s literally just an attribute on the input element?
No it really shouldn't. Just look at JS. It's a complete mess. And HTML would get there in a short time if they were to adopt "anything that can be neatly siphoned". The problem is that data binding is actually quite complex. I have seen data binding done 10 different ways in different languages and they all had their flaws. It will be very difficult indeed to come up with such a standard that is actually being used universally.
If it is not, what sense does it make to add it to the standard? But for it to be used a lot, it would actually need to solve most problems in most businesses for the forseeable future.
Given the fact that the Web apparently still hasn't figured out quite how UI development is supposed to work (judging by the 1 new language feature, 10 new frameworks, 100 new libraries developed each day), it will be a very poor idea to start baking half baked stuff into a standard.
Separation of languages is a silly way to separate things. You're building components: logic, structure and style are coupled. SwiftUI adopts the React model, and it succeeds because of it. One can build an app in React/SwiftUI in about 1/2 the time spent "separating concerns", and build systems still extract things out to be clean and performant, there's no sacrifice being made there. CSS is a shitshow and a total mess especially on large teams.
React has nothing to do with how performant an app is and if anything speeds them up compared to anything previously, you may be confusing the power and ease with which it enables development as getting some drunk on building larger apps, but that's only because of how effective it is. Twitter is a good example, great performance. It's way more about the team than the tool, though certainly it will get easier over time to have the defaults be better at optimization for smaller teams who are ambitious.
Most of the super bloated websites I see are basically news sites and other less-techy sites that are stuffed with ad tracking and have no tree shaking. The majority of React apps build with Webpack which supports tree shaking and lazy loading out of the box, plus React makes it possible to pre-render your entire app and deliver it as HTML that hydrates.
I think WebComponents have left a horrible taste in the mouth because they came well after React and others existed, didn’t take any inspiration or provide any abstractions that would help, did basically everything worse and seemingly without any discussion with real world devs, and then were hyped and pushed on everyone for years while they basically lacked all necessary features. Now, years later they have evolved and added libraries on top to smooth over all the weirdness, and if you squint they look similar, but the web would have been a better place if they had just provided some VDOM abstractions, style containment in a simple way, and so on rather than master-planned a High Modernist dystopia and then slowly painted over it until it resembled something like the organic cities that already existed.
1) Classes for writing components. Yuck. React's function component feels much more elegant.
2) @property decorator. Double yuck! I want a reactive way of updating my component's state without having to declare this piece of state as a property accessible by the outside world.
3) this.requestUpdate(). Triple yuck compared to something like React's setState or useState hook.
4) In order to create children components, I need to create more customElement-decorated classes? Yuck again!
Good React is fine for large applications, but not for websites. Even in applications a few lines of Javascript and a rendering backend can replace entire JS frameworks. Try disabling Javascript for a day and you can see how many pages just become a white screen because whatever is replacing the browser's renderer isn't loading.
> Twitter is a good example, great performance.
I agree that it's a great example, but it performs horribly for me. I use their website on my phone and videos rarely play back properly, content jumps around while navigating, empty screens and loading bars are everywhere. Sometime I just have to reload because the Twitter website decided it doesn't want to load images anymore. Nitter links, on the other hand, load instantly, including image and video content, because of its minimalist approach.
Server side rendering is a welcome improvement because it means the developer doesn't offload the website's calculations to their visitors. I'm fine with whatever framework people pick on the server, as long as my browser doesn't get its rendering engine replaced by the fancy framework for the week.
Look at the new default "razor pages" web project for .NET core. While it it is a little bit fancier, it basically brings back the same mental model that PHP has been using for decades. That is, cram all of the logic into a single file, and use a "service locator" pattern (I know it's actually DI under the hood) to "inject" extra functionality. In this way it is easy to trace where all of the pieces are coming from. Why abstract your `UserRegistrationView` to accept any `UserRegistrationModel` from a `UserRegistrationController` in a "decoupled" manner when the reality is that only one of any of that actually needs to exist ever? Might as well have the orchestration right next to the use-case!
The above applies to (what I believe to be) a significant majority of use-cases. At least the interesting ones.
It’s ironic that this is done in the name of “Separation of concerns“ -
You know what separates concerns: having everything that affects this component - in one place. That’s true separation of concerns.
I’ve worked in multiple frameworks in multiple languages and nothing does it better than modern react (especially with webhooks).
For my own experience with things that were specifically MVC or MVVM:
In C#: Asp.net MVC, WPF (with/without Prism)
In Typescript: Knockout, Angular 2.0+ (I guess it wasn’t mvc really - I disliked it for other reasons)
React (with hooks) on the other hand is the embodiment of a pure Functional Programming UI.
I can literally write a component with a single import and a single function.
For every reason functional patterns beats OOP patterns, react beats mvc - and achieves true separation of concerns (feature aligned concerns).
Not really — unless React is the only library you use.. MVC is still the best pattern. If you are an iOS developer you may already be familiar with MVC in Cocoa. Most UI frameworks, including ASP.NET Core, JSP and JSF (Java based frameworks), Ruby on Rails, and Django (Python) are all based on MVC. That's no accident. These disparate platforms — mobile and Web — all converged on MVC because it is the best architectural pattern for developing user interfaces.
Even within the frontend world and not in React you have all sorts of new state systems and structures that are in my opinion far more intuitive, less code, less cross cutting concerns, easier to change and grow more naturally. The gist of it is either a global state store with cursors and namespaces (I like this less than most) or a global state system with state split out (see Recoil) or an entirely tree based reactive state system (see mobx-state-tree or mobx-store) or even just nesting reducers or any simple nesting state container (pure react, zustand). I’ve recently put together gqless[0] with a state system similar to recoil but simpler (sort of like use-atom). It’s wonderful.
Your data is a tree/graph, you app is a tree, your file system is a tree, everything matches. You just slot in state with corresponding actions and at the level of the view hierarchy where it first becomes relevant (router at top, view controllers are spread in the middle layers however needed, and leafs get their own state as needed). And all data level things stay up in the graph, which I guess you could argue is an M sitting above it all, the VC are blurred together with more C at the top of the tree and pure V at the leafs. Even styling is all encapsulated where it’s used. Each piece is a lego block that can be moved around. And yes, it works, and works well, even without all the handlebars of Rails.
Wouldn’t dream of going back. It’s perhaps not a mature enough ecosystem for most to navigate their way to getting a good DX on a stack like that. Many pieces have rough edges if you don’t know what to avoid, it’s not like these huge mature frameworks that keep you away from scary stuff but also box you into a rigid structure. But of course it means you can do all sorts of things unimaginable in MVC land.
In any case, my critique is not levied against MVC the pattern, rather, how it is manifest. One can logically follow MVC without the physical separation of concerns (files). It's a continuum: You start by defining your state, view, and orchestration all in the same place. Should any one piece of the above suddenly need to be reused elsewhere, you then abstract as necessary.
I was pushing back against the idea that "inlining" CSS/JS with HTML is poor practice. What React achieves, because it demands you inline JS (and CSS if you want) with the HTML, is a simple, declarative development paradigm. It's like reading a function. No procedural ad-hoc `let el = document.querySelector('#id')` garbage getting in the way. The behavior is with the component, not around the component. In many ways, this is how OOP was supposed to work.
The nitpicks you have on Twitter are on specific behaviors (video and jumping and slow fetch) that have nothing to do with React. The site itself is lightweight and runs fast.
This statement alone invalidates your arguments, because evidently you never once tried opening Twitter on an underpowered machine, be that desktop or a phone.
Downloading 500kb of js and processing this is just a nogo. The best advice to anyone interested in page speed, dont use this crap.
Takes 4kb to full page render (1 file - static only - JavaScript disabled).
That’s smaller than most any html+css especially if using some css library.
Of course once that is loaded and if JavaScript is enabled, then it will start to load interactive stuff and prefetch (which is around 100kb - but I have a lot of interactive stuff - including a zork style adventure Easter egg in the site header).
https://developers.google.com/web/updates/2019/02/rendering-...
This is comparable to hacker news home page (which is purely static), but my first contentful paint was slightly faster (probably because my site is slightly smaller).
Both sites were about 4 times faster (TTI) than google home page and typescript home page.
Here is a post that explains some of the content that is interesting: https://ricklove.me/cool-stuff
Let me know how it does on a slow connection.
Overall, it was a very refreshing experience.
I did notice that for some components I need to show a loading indicator while they are loading async (for a slow connection).
Thanks for letting me know!
I guess I’ll know if someone finds the Bitcoin.
Update: I added a few more nerd lore passwords - thanks for the idea!
Just check the stats here: https://perf-track.web.app/react
Type “dir” in the header (or other activities in the “cool-stuff” post).
Moreover, I can build anything I want very quickly - with great engineering - and still get performance comparable to a static site.
React + react-dom is under 40kb minified gzipped. The other 460kb are your responsibility.
If browsers provided data binding and reactivity out of the box, frameworks and applications would be much faster and lighter.
Whenever a feature gets added to standard HTML, web frameworks and "polyfills" keep implementing their own versions because the standards don't fit them and they don't want to rewrite (or keep their own implementation as a mere fallback).
Even if a data binding framework would be standardized today, it would take years for browsers to catch up and gain critical mass. There'd only be more polyfills and Javascript to help support people running IE11 or whatever.
I'm glad many JS features have been implemented natively in HTML5, but this specific case feels overkill to me. HTML templates have been introduced and then ignored by frameworks already and I doubt any framework would switch over to a new data binding API if it became a standard today.
Maybe in some experimental project, but I've never seen this in any video site.
> input elements such as calendar controls are rewritten
Yes, because the native browser widgets are totally insufficient and can't be styled.
> animations are done in JS instead of smooth CSS transitions
JS animation can be super fast (see GSAP) and it seems you're talking about jQuery.animate() which I agree was terrible. But these days most people use CSS animations.
> drag and drop support is manually rewritten in JS
Again, because the browser does not have a proper drag and drop API to do it. I know because I've had to implement drag and drop many times. From vanilla, to jQuery, to React... for mouse and touch UIs.
Here's another huge thing lacking in the browser world: touch gestures.
I don't want them to be styled, thank you very much.
> JS animation can be super fast (see GSAP) and it seems you're talking about jQuery.animate() which I agree was terrible. But these days most people use CSS animations.
GSAP is giving me stuttery animation when I scroll through their website on my phone, presumably because it's constantly updating the DOM to keep control of the animation. It's not as bad as the state of JS animation was 10 years ago, but I can think of very few use cases where such a library would actually be necessary instead of using pre-calculated CSS transitions and such.
> Again, because the browser does not have a proper drag and drop API to do it.
I haven't had that much trouble when I had to use the HTML5 DnD API. Well, not more than with the frameworks I've seen; touch screen DnD support sucks on all platforms I've tried.
Popular browsers such as Firefox and Safari don't have native date controls: https://caniuse.com/input-datetime
I mean... maybe in some legacy plugins that budget-shops drop into a Wordpress site without thinking. This stuff doesn't really happen anymore in real projects; there's not much point.
> Whenever a feature gets added to standard HTML, web frameworks and "polyfills" keep implementing their own versions because the standards don't fit them and they don't want to rewrite (or keep their own implementation as a mere fallback).
I think you misunderstand what polyfills are. Polyfills exist as an implementation of the standard, before the standard has been fully supported. They get stripped out when possible. In no way are they "their own version" of the standard.
> Even if a data binding framework would be standardized today, it would take years for browsers to catch up and gain critical mass.
It definitely wouldn't. All major browsers get silent auto-updates now, and Chromium alone has over 75% of the market share now that Edge is based on it. Google was the one pushing web components in the first place, and today Firefox and Safari would face pressure to keep up lest they lose ground when more sites become "just for Chrome". The silver lining of the browser monoculture is that features get implemented quickly.
> There'd only be more polyfills and Javascript to help support people running IE11 or whatever.
Possibly. But in today's world polyfills are less and less necessary (see my previous statement). Most companies these days just write off IE and outdated browsers as not worth bothering with. And for all those other browsers, there would be a dramatic drop in the amount of Javascript.
> HTML templates have been introduced and then ignored by frameworks already
HTML templates are the prime example of how useless the web component standard is in its current form: they literally just hold DOM nodes. Those DOM nodes can't appear on the page without being cloned by JavaScript. They gain no special functionality. They just sit there. Templates without databinding are hardly better than an HTML string.
That's the idea, but many projects never actually remove the polyfills once browsers catch up to a given standard. In theory they solve the problem, but in practice I'm still ending up downloading polyfills on Firefox and Chrome because Safari doesn't support a particular API. Sure, the code barely executes, but the bandwidth is wasted regardless.
> It definitely wouldn't. All major browsers get silent auto-updates now [..]
Tell that to mobile Safari. Updates are packed into OS updates and features regularly take ages to be implemented. One day we'll get WebP and notification support. One day...
> Templates without databinding are hardly better than an HTML string.
Templates without databinding provide everything you need to render a component; structured elements that can be filled out with code. With class names and query selectors they can be filled and rendered very quickly with little code and no need for a framework.
Using the API properly can ensure that inserted text is never seen as code, making it free of the injection attacks that HTML string replacing often exposes. Content and structure are clearly separated and provide no challenges for the browser to parse. Generated components are always well-formed, which string replacement also doesn't guarantee, modification of contents is no different from regular DOM updates.
And we still separate concerns on the desktop. The model/view/viewmodel paradigm is pretty good.
It's the same reason I prefer a structured MVC project over a PHP file with the contents echo'd in with <?= ?> statements. Both get the job done in the end, but one is clear about where what responsibilities lie.
With some minimal JS, you can update each web component already. Is writing nameField.innerText = response.name really that difficult? What problem does it solve to make a standard for it? As for (de)serialization, JS has built-in support for JSON and XML. HTML attributes are everything but rickety in my opinion, as any decent parser will allow you to access them as if they are a normal dictionary. Put JSON in them if you really want to encode complex data in attributes, although you probably shouldn't.
I strongly believe the abhorrent overuse of React and other such libraries on the web is the sole reason our computers have gotten hundreds of times faster but the web is only slightly as quick. I don't see a place in web standards for a React-style functional design because of the specific rules each of these libraries have.