If you have dreams and dry goods, you can search for [Great Move to the World] on WeChat and pay attention to this Shawanzhi who is still washing dishes in the early hours of the morning.
This article GitHub https://github.com/qq449245884/xiaozhi has been included, there are complete test sites, materials and my series of articles for interviews with first-line manufacturers.
This article is a translation, the original author is Chris , he is the chief front-end engineer of Bitski, a member of the core team of Ember.js, and a former front-end engineer of LinkedIn, Addepar, Ticketfly (now EventBrite), anyway, he is a great guy. The first person refers to the big guy.
Back in 2012, I started coding mostly in JavaScript. I did a PHP application from start to finish for a local business, a basic CMS and website, and the company decided to rewrite it and add some functionality.
The project manager wanted me to use .NET, partly because he knew it, but also because he wanted the app to feel like a native app -- no page refreshes or long waits for action actions. After some research and prototyping, I convinced the manager that I could use the brand new JS framework that was just starting to emerge, which could do these things.
The first framework I chose was actually Angular 1. Before I ran into some issues with routers, had built a fairly large app and used FuelPHP's backend - it flickers whenever child routes/exits are re-rendered, and it really feels like it's designed This scenario was not taken into consideration.
Later, someone recommended Ruby on Rails + Ember to me, and after trying it, I think it works well. I also like the idea of both frameworks, these community ecosystems, and overall it's been very productive compared to the alternatives at the time.
A lot has changed since then - frameworks have popped up and evolved a lot. Going away from the idea that you can build applications in JavaScript in the browser has become somewhat of a fringe to a standard practice. The infrastructure we've built has been completely transformed, enabling a whole host of new possibilities.
During this time, there was also a fair amount of competition and conflict between ideas. Which JavaScript framework to use, how to write CSS, functional versus object-oriented programming, how to best manage state, which build system or tool is the most flexible and fast, etc. Looking back, it's interesting that we often argue about the wrong things and ignore some forward-looking things, which of course are hindsight.
So I wanted to do a retrospective of JavaScript development over the past few decades and see how far we've come. We can roughly divide it into four main eras. :
- primitive age
- first frame
- Component-centric view layer
- full stack framework
Each era has its own themes and core contradictions, while also thinking about drawing key lessons and making steady progress.
Today, the debate continues. Is the web getting too bloated? Does the average website really need to be written in React? Should we even use JavaScript? Of course, the current does not represent the future, and the existing framework is likely to be replaced in the future, but it is also based on some existing viewpoints to help us move forward.
primitive age
JavaScript was first released in 1995. Like I mentioned above, I started writing JS in 2012, almost 20 years later, near the beginning of what I call the first framework. You can argue that I might be covering up a lot of history here, and that the era could be broken down into many sub-eras, each with its own patterns, libraries, build tools, etc.
That said, I can't write about things I haven't experienced. When I started writing front-end applications, a new generation of frameworks was just starting to mature. Angular.js, Ember.js, Backbone, etc.
Before that, the state-of-the-art were libraries like jQuery and MooTools. These libraries were very important in their day -- they helped smooth out the differences between how browsers implemented JavaScript, and those differences were very important.
For example, IE implements events in a completely different way than Netscape -- bubbling events versus capturing events. That's why our standard today finally implements both ways, but before that, we need to use libraries to write code that works on both browsers.
These libraries are mainly used to make small, self-contained user interface components. Most of the application's business logic still goes through forms and standard HTTP requests -- rendering HTML on the server and serving it to the client.
There are also no build tools in this day and age, at least as far as I know. JavaScript at the time had no modules (at least not standard modules), so there wasn't any way to import code. Everything is global and it is very difficult to organize these things.
In this environment, it's understandable that JS is often seen as a toy language rather than one you use to write a full-fledged application. The most common thing we did back then was add jQuery, write some scripts for some UI widgets, and that was it.
Over time and with the introduction and popularity of XHR, people started putting parts of their UI processes into a single page, especially for complex processes that required many back-and-forth interactions between client and server, but applications Most of the content remains on the server.
This is in stark contrast to what happened when mobile apps started appearing. From the very beginning, mobile apps on iOS and Android are complete apps written in serious languages™ like Objective C and Java. Also, they are completely API driven - all UI logic is on the device and communication with the server is purely data format. This led to a better user experience and an explosion of mobile applications, leading directly to the debate we have today about which is better, mobile or the web.
Doing all this in JavaScript was considered ridiculous at first. But over time, apps started to become more ambitious. Social networks added chat, DM and other real-time features, Gmail and Google Docs showed that it was possible to write the equivalent of desktop apps in the browser, and more and more companies were turning to writing web apps because the web worked anywhere and more Easy long-term maintenance. This has propelled the entire industry - it is now clear that JS can be used to write non-trivial applications.
JavaScript at the time didn't have all the features it has today, everything was global and usually required to manually download and add each external library to a static folder. Back then there was no NPM, modules didn't exist, and JS didn't have half the functionality of today.
In most cases, each application is customized, each page has different plugin settings, and each plugin has a different system for managing state and rendering updates. To solve these problems, the earliest JavaScript frameworks began to appear.
first frame
Around the late 2000s and early 2010s, the first JS frameworks dedicated to writing full client-side applications began to appear. Several famous frameworks of this era:
- Backbone.js
- Angular 1
- Knockout.js
- SproutCore
- Ember.js
- Meteor.js
Of course, there are many others, and probably some bigger in some circles. These are what I remember, mainly because Xiao Ming used them to code, and they were more popular.
This is a generational framework that is entering uncharted territory. On the one hand, what they were trying to do was very ambitious, and a lot of people thought it would never really succeed.
There are many naysayers who argue that single-page JS applications (SPAs) are fundamentally worse, and in many ways they are right - client-side rendering means that bots can't easily crawl these pages, and users even have to wait a few seconds clock to start the drawing application. A lot of these apps are accessibility nightmares that simply won't work if JavaScript is turned off.
On the other hand, we have no experience building full applications in JS, so there are plenty of competing ideas about the best approach. Most frameworks try to emulate popular practices on other platforms, so almost all of them end up as some kind of iteration of Model-View-*
. Model-View-Controller
, Model-View-Producer
, Model-View-ViewModel
and so on. But these aren't really successful in the long run -- they're not particularly intuitive, and they get very complicated very quickly.
This was also an era when we really started experimenting with how to compile JavaScript applications. Node.js was released in 2009, and NPM followed in 2010, introducing packages for (server-side) JavaScript.
CommonJS and AMD battle over how to best define JS modules, while build tools like Grunt, Gulp, and Broccoli battle over how to combine these modules into a deliverable end product.
For the most part, these are pretty generic task runner-like tools that can really build anything, just happen to build JavaScript -- but also HTML, CSS/SASS/LESS, and many others that go into web apps s things.
However, we have learned a lot from this era:
- URL-based routing is the foundation. An application without this routing would break the web, so this needs to be taken into account in the framework from the start.
- Extending HTML through templating languages is a powerful abstraction layer. Even though it can be a bit clunky at times, it makes it easier to keep the UI in sync with state.
- SPAs perform poorly, and the web has many additional limitations that native apps don't. We need to publish all the code over the web, let it JIT, and then run to start our application, and the native application has been downloaded and compiled, which is a daunting task.
- As a language, JavaScript has a lot of problems and it really needs to be improved to make things better - frameworks can't do that alone.
- We absolutely need better build tools, modules and wrappers to write applications at scale.
Overall, the era was productive. Despite the drawbacks, as the complexity of the application increases, the benefits of separating the client from the API are enormous, and in many cases the resulting user experience is amazing. If there are no special circumstances, this era may continue, and we are still iterating on MV*
style ideas.
But then an asteroid popped up and smashed the existing paradigm to pieces, causing a mini-extinction event that propelled us into the next era -- the asteroid is called React .
Component-centric view layer
I don't think React invented components, but honestly I don't really know where they came from in the first place. But at least it goes back to XAML in .NET, and web components started to evolve as a specification back then. Ultimately it doesn't matter - once the idea came along, every major framework adopted it quickly.
In hindsight, this makes perfect sense - extend HTML, reduce long-lived state, bind JS business logic directly to templates (whether it's JSX or Handlebars or Directives).
A component-based application removes most of the abstractions needed to get the job done, and significantly simplifies the code lifecycle - everything is tied to the component's lifecycle rather than the application's lifecycle, which means that as a As a developer, you have far fewer things to think about.
However, there was a shift at the time: frameworks started touting themselves as "view layers" rather than full-fledged frameworks. Instead of solving all the problems a front-end application needs, they focus on solving rendering problems.
Other issues, such as routing, API communication, and state management, are left to the user's discretion. Famous frameworks of this era are:
- React.js
- Vue.js
- Svelte
- Polymer.js
There are many others. Looking back now, I think it was a popular framework for second generation frameworks because it really did two main things.
- It narrows it down dramatically. The core of the framework is not trying to solve all these problems up front, but focusing on rendering, and many different ideas and directions can be explored in the wider ecosystem for other capabilities. There are many bad solutions, but also good ones, paving the way for the next generation to pick the best ideas from the best.
- This makes it easier for us to accept them. Taking a full framework to take over your entire web page means rewriting most of your application, which is not possible with existing server-side monoliths. Using frameworks like React and Vue, you can drop small parts of them into an existing application one widget or component at a time, allowing developers to incrementally migrate their existing code.
These two factors led to the rapid development of the second-generation frame that eclipsed the first-generation frame, and from a distance, it all seemed to make sense and was a reasonable evolution. But being in it at the time was quite a frustrating experience.
First, when we debate at work which framework to use, or whether we should rewrite our application, we don't often encounter such a framework. Instead, a lot of times it's "it's faster!" or "it's smaller!" or "it's all you need!".
There's also the debate about functional programming versus object-oriented programming, and many people see FP as the solution to all of our problems. To be fair, these things are true. View layer-only frameworks are smaller (at first), faster (at first), and all you need (if you build or stitch a lot yourself).
Of course, functional programming patterns solve a ton of problems that plague JavaScript, and I think on average, JS is better because of them.
The reality, however, is that there is simply no magic bullet. Applications are still large, bloated and complex, state is still difficult to manage, and fundamental issues like routing and SSR still need to be addressed.
For many of us, what people seem to want is to drop a solution that tries to solve all of these problems for a solution that the reader can solve on their own.
In my experience, this is also a common practice for engineering groups that will happily accept this change in order to deliver a new product or feature, and then not fund the time it takes to fully develop all those extra features.
The result is home-made frameworks built around these view layers, which are themselves bloated, complex, and very difficult to manipulate.
I think a lot of the problems people have with SPAs come from this fragmented ecosystem that comes at a time when SPA usage is exploding. I still often come across a new site that doesn't do routing correctly or handle other little details well, and it's absolutely frustrating.
But on the other hand, the existing first-generation full-service frameworks are also not very good at solving these problems. Part of this is due to the massive technical debt burden. The first generation of frameworks was built before ES6, before modules, before Babel and Webpack, before we figured out many things.
Iterative evolution is very hard, and rewriting them completely, like Angular did with Angular 2, kills the momentum of their community.
So when it comes to JavaScript frameworks, developers are in a dilemma - either choose an all-in-one solution that's starting to show its age, or jump into the free-for-all, DIY half-framework and hope for the best.
It was very frustrating at the time, but in the end it resulted in a lot of innovation. As these frameworks figured out their best practices, the JavaScript ecosystem has grown very rapidly, along with some other key changes.
- Transpilers like Babel became the norm and helped modernize the language. Instead of waiting years for feature standardization, it's available today, and the language itself starts adding features at a faster, more iterative pace.
- ES modules were standardized so that we finally started building modern build tools around them like Rollup, Webpack, and Parcel. Import-based bundling is slowly becoming the norm, even for non-JS resources like styles and images, which greatly simplifies configuration of build tools, making them leaner, faster, and more comprehensive.
- The gap between Node and web standards is slowly but steadily narrowing as more and more APIs are standardized. SSR started out as a real possibility, and then something every serious app is doing, but it's a bespoke setup every time.
- Freed up Edge Computing to give JavaScript-based server applications the benefits of SPAs in terms of distribution/response time (Spas used to be static files on the CDN, and generally started loading faster, even if they took longer time to fully load and at the end).
At the end of this era, some questions remain. State management and responsiveness are still (and are) thorny issues, although we have better patterns than before.
Performance is still a difficult issue, and while things are improving, there are still many, many bloated SPAs out there.
The accessibility situation has also improved, but it is still often an afterthought for many engineering agencies. But these changes paved the way for the next generation of frameworks, and I would say that we are now entering the next generation of frameworks.
full stack framework
Personally, the last framework era has really come quietly. I guess it's because I've spent the past 4 years or so getting deep inside the Ember rendering layer trying to address the aforementioned technical debt that affected it as a first-gen framework (still). But that's also because it's more subtle, because all these third-generation frameworks are built around the previous generation's view-layer framework. These frameworks include:
- Next.js (React)
- Nuxt.js (Vue)
- Remix (React)
- SvelteKit (Svelte)
- Gatsby (React)
- Astro (Any)
These frameworks started as the view layer matured and consolidated. Now that we all agree that components are built on top of the core, it makes sense to start standardizing the rest of the application - routers, build systems, folder structures, etc.
Slowly, these meta-frameworks started to build on the same functionality that first-generation all-in-one solutions did out of the box, picking the best patterns from their respective ecosystems and incorporating them as they matured.
Then they went a step further.
Until then, SPAs have been focused solely on the client. SSR is something that every framework wants to solve, but only as an optimization, a way to get rendering, which will eventually be superseded when megabytes of JS finally load.
Only one first-generation framework dared to think further, namely Meteor.js
, but its idea of isomorphic JS never really came to fruition.
But as applications grew in size and complexity, the idea was revisited.
We noticed that it is actually very useful to pair the backend with the frontend so that you can do things like hide API secrets for certain requests, modify headers when returning to the page, proxy API requests. As Node and Deno implement more and more web standards, the gap between server-side JS and client-side JS is narrowing every year, and it's starting to seem like it's not a crazy idea after all. Combine that with edge-computing and amazing tools and there's some incredible potential.
The latest generation of frameworks takes full advantage of this potential, blending client and server seamlessly, and I can't stress enough how amazing that feels. Over the past 9 months of working with SvelteKit, I don't know how many times I've sat down and said to myself, "This is what we should always be doing."
Here are some tasks I've come across recently that have been surprisingly easy with this setup.
- Add server-side OAuth to our app so the authentication token doesn't leave the server, and an API proxy that adds the token when sending requests to our API.
- Proxy some routes directly to our CDN so we can host static HTML pages built in any other framework, allowing users to make their own custom pages (a service we serve some clients).
- When we need to use an external service that requires a key, add several different one-time API routes (no need to add a whole new route to our API and coordinate with the backend people).
- Moving our use of LaunchDarkly to the server side, so we can load less JS, reducing the overall cost.
- Proxy our Sentry requests through the backend routing so we can catch errors that go unreported due to ad blockers.
And that's just the tip of the iceberg. There's really a lot of cool things about this pattern, the biggest of which is how it revives the idea of progressive enhancement, leveraging the combined nature of the server and client, allowing the client to fall back to the basics if the user disables JavaScript HTML + HTTP.
When I started working in spas, I myself had completely abandoned the practice, thinking they were the future, but it's really cool that we might see a world where it makes a comeback.
These are new features, and from experience, I would classify these frameworks as a new generation of frameworks. Problems that were previously intractable or impossible to solve are now trivial with just a small change in the response handling logic.
Reliable performance and user experience are available out of the box and do not require any additional configuration. Instead of building a whole new service, we can add some additional endpoints or middleware as needed. This has changed lives.
I think this generation also addresses some of the main points of conflict between the first and second generation frameworks and their users.
It started with a shift to zero-configuration terms, but I think it's ultimately driven by the maturity and stability of the ecosystem around second-generation frameworks, which is also a cultural shift.
The third-generation framework is now trying to be an all-in-one solution again, trying to solve all the basic problems we need to solve as front-end developers - not just rendering.
Now more than ever, it feels like the community is aligned in addressing all of the many issues plaguing SPAs and, importantly, collectively addressing them.
Where are we going next?
Overall, I think the JavaScript community is moving in the right direction. We have finally developed full-fledged solutions to build complete applications from scratch that are not "just a view layer".
We are finally starting to compete on the same starting line with the SDK for native apps, providing a complete toolkit out of the box.
We still have a lot of work to do in this regard. Accessibility has long been an afterthought in the SPA world, and outside of GraphQL I still think data stories could use some work (like it or not, most of the web still runs on REST).
But the trend is right, and if we continue to move in the direction of shared solutions, I think we can solve these problems in a better way than before.
I'm also excited about the potential behind taking these patterns even further into the web platform itself. Web Components are still quietly iterating, working on issues like SSR and getting rid of global registries, which will make them more compatible with these third-generation frameworks.
In another direction, WebAssembly can iterate this pattern in an incredible way. Imagine being able to write a full stack framework in any language.
Isomorphic Rust, Python, Swift, Java, etc. could finally reduce the barrier between front and back to almost zero - just a little bit of HTML templating at the edge of your system (which ironically takes us almost in a circle) , albeit with a better user experience).
My best hope here is that we are moving through an era of fragmentation and an era of new JS frameworks every day. Freedom and flexibility breed innovation, but they also lead to cluttered, disconnected, and often fundamentally disruptive web experiences.
When developers had to choose among 50+ options and cobble them together with limited resources and tight deadlines, that's the experience we've seen, and it's also plausible. Some apps are fast, consistent, reliable, and fun to use, while others are frustrating, confusing, slow, and broken.
If we could give developers easier-to-use tools that do the right things by default, maybe the average website would be a little better, and the average experience would be a little smoother.
It won't fix every website -- not much code can fix bad UX design. But it will lay a common foundation, so each site starts out a little better and each developer has more time to focus on other things.
The bugs that may exist in editing cannot be known in real time. In order to solve these bugs afterwards, a lot of time is spent on log debugging. By the way, here is a useful BUG monitoring tool , Fundebug .
Author: Chris Translator: Xiaozhi Source: pzuraq
Original: https://www.pzraq.com/blog/four-eras-of-javascript-frameworks
comminicate
If you have dreams and dry goods, you can search for [Great Move to the World] on WeChat and pay attention to this Shawanzhi who is still washing dishes in the early hours of the morning.
This article GitHub https://github.com/qq449245884/xiaozhi has been included, there are complete test sites, materials and my series of articles for interviews with first-line manufacturers.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。