Petite-Vue – 5kb subset of Vue optimized for progressive enhancement
github.com
github.com
Anyway, looking at the docs, my approach wouldn't be as easy in vue-petite. It looks like Components have been functionally gutted. You can still approximate something, but you seem to lose a lot of ecosystem benefits of Vue. Theirs looks great for
Ultimately, this all seems like something coverage and tree-shaking should be able to do. If you're only using 5Kb of Vue, only 5Kb should be bundled. One day, eh? Until then, is the additional 25Kb actually hurting your users?
Also as long as we're talking about Vue, people that have Vue 2 apps and missed the 3.1 release announcement (I don't remember seeing it on HN's frontpage) should check it out, there is a compatibility layer that works really well to migrate progressively.
I started with this post https://blog.ninja-squad.com/2021/06/07/what-is-new-vue-3.1/
Unfortunately the major blocker (for me) is the lack of IE11 support and the bloody paying customers who refuse to move off IE11. One day they'll be gone.
Broadly speaking, I don't disagree. There's a lot of truly awful JS out there, wasting cycles doing things that CSS should be handling, but I think the tooling is slowly getting better.
Thus petite Vue can have much smaller size than Vue.
TBH, Lack of ecosystem will be a hurdle here, then again, if you want to leverage multiple other libraries, then you might as well use Vue directly
Not really.
Nor is an extra 30KB font file.
Or an additional 50KB for an icon set.
Or an extra 18KB for a better select box.
Nor is that 200KB header image.
Why not add that 50KB analytics script too?
The extra 40KB for a nice a animation library is useful.
You need to add 150KB for a UI component library.
And so on, all the way until your page is a 2MB download..
Any individual incremental increase can be justified as part of the page weight, but a few KB here, a few more there, and your site suffers death by a thousand cuts. You have to worry about the extra 25KB here and there if you're going to keep the overall size within a sensible performance budget.
I always go to Bundlephobia before deciding to use an NPM dependency.
In my case, using full-fat Vue lets me do a swathe of complex stuff, pulling in libraries and components we use elsewhere, that also do piles of complex stuff, and it only takes me a couple of hours to progressively enhance a big form, which makes it nicer for the user with pro-active validation, breaking the thing into a wizard, easy dynamic lookups, etc. My work increases conversions, creams KPIs.
Is that worth 30KB? Every day of the week.
Can I batter it down to 20KB? Probably, but it'll take me at least twice as long this time, possibly make the work output less reusable and cost the client twice as much. Is that 10KB worth it? Maybe, maybe not.
Don't get me wrong, I'm not the sort of person who throws JS everywhere. I'm a Django developer who will always push to SSR over SPAs... But I also realise there is occasionally a business case for a but of reasoned splurging. Again, my hope is that within a couple of years tree-shaking gets good enough to automate this nonsense, trim out everything that isn't used.
He also explains some of the Vue optimization tricks like why they ditched the nested JSON and how Vue caches the @click handlers, etc so they don't need to check this on every digest cycle.
I wish there was a free version to link here. Really interesting stuff, shows you how much thought and effort is put in by the creators to optimise so many little things which us users of the framework never even notice is happening.
https://www.vuemastery.com/courses/vue3-deep-dive-with-evan-...
Sorry but it is locked as it's part of the paid course :(
Sounds interesting though, would be awesome if you could give us the gist of how he went about it!
Nice to see an even lighter version optimized for this use-case.
SSR/isometric rendering isn't new, but it's usually hacks around using a frontend JS framework to run the backend and can result in the worst of both worlds. Projects like Blazor (.net) and Livewire (php/laravel) are interesting new solutions to fix this.
It seems like if you are developing solely to meet "SEO friendly" criteria, you aren't exploring many alternative solutions.
Does all this framework tooling exist to just avoid inspecting a user agent and serving from a different upstream?
Having to maintain a large set of template files, with a dependency on a separate language or framework seems contrary to your premise that Vue is specifically better because it uses "HTML templates by default"
Never said I was. In fact that's just another nice benefit of traditional server-side frameworks rather than something you have to worry about implementing all over again.
Blazor specifically is the first non-JS component-based UI framework for the web with multiple modes that bridges backend and frontend as a single service without any impedance mismatch. It's an entirely new way to approach web UIs and interactivity without all the plumbing and frontend-to-backend-for-the-frontend-to-the-backend nonsense. Livewire is not quite as polished but shows how far you can go with tight integration on the JS side.
That is a general theme, I've found - compared to React, Vue makes the easy things easier, but the hard things harder.
JS itself is a single-threaded event loop and all view engines basically follow the same functional pattern of data-> render function -> output. Vue comes with an HTML parser to create that render function, React and others use a JSX parser, or you can write your own from raw javascript.
You can technically use any of them with any render function parser, but Vue starting with HTML by default and all the other niceties around reactivity make it a better fit.
I'd say Vue is the much more powerful tool in the hands of a skilled developer
If you wanted to get fancy, you could also accept a tag prop and v-bind all other $attrs on the container to make that a general purpose component.
You use a dynamic component:
<component :is="condition ? 'WrappedComponent' : 'UnwrappedComponent"></component>
> That is a general theme, I've found - compared to React, Vue makes the easy things easier, but the hard things harder.While react make the easy things annoying. It took me an afternoon to be productive with vue, several weeks with react.
And all that for what?
Having the privilege to "just use javascript"? Here is "just javascript" in jsx:
{items.map((items) => (
{display && <SomeElement
onClick={e => e.preventDefault() && foo()}
className="`${active ? 'current' : ''}`" />}
))}
Here is the same in vue template: <SomeElement
v-for="item in items"
v-if="display"
@click.prevent="foo()"
:class="{'current': active}" />
Not only the react blob is impossible to scan, but it will be different depending of the dev who coded it, because there is no enforced patterns. You must use brain power to parse every single template line. HTML, that thing that was simple and declarative, now becomes complicated and imperative.And that's not even weird or unusual code. That's regular stuff one writes all the time. Don't get me started on state management or spaghetti hooks.
I have yet to work on a react code base I was more productive than on a vue one. And the gaps get wider if the team is not composed of excellent coders, because react code by junior is a nightmare.
Admittedly due to the nature of Vue syntax, it's harder to make a mess because everything is just key/value.. but then you have to learn an API to express things in that way. I enjoy the fact that you don't have that layer/step with react.
I definitely feel that the 3rd party classnames package should be built into React, I agree that out of the box conditional class names look a mess.
I don't have enough experience with either library yet to form an opinion on which I prefer, but I definitely appreciate not having the mental overhead of remembering the vue api. I'd rather have a bit of code that's more explicit/"just javascript" than have to think "what's that symbol I need to use again?". Definitely a personal preference thing though!
{items.map((item) =>
item.display && (
<SomeElement
onClick={(e) => e.preventDefault() && foo()}
className={classNames({'current': item.active})}
/>
)
)}And in the end, I still have to read 2 JS expressions before even figure out what DOM element I'm actually dealing with. Then I still have to evaluate what the heck is happening in onClick and className.
I still have to parse code in my presentational layer, code that is interleaved with my template indentation so it also makes it hard to understand hierarchy and easy to make mistakes.
Of course, the elephant in the room we are not talking about with react is that all those things compounds. When you have 5 of such blobs in your render functions, issues don't add up, they multiply.
Then you add the store system on top of it, with actions, reducers and all that fun stuff.
It's not really that big of a deal to have another import. Vue's directive's (not sure if that's the correct term) are a mix bag of magic strings that tie to functions somehow. Why can't they just be a function variable like in React? The answer of course is there are smart people and smart users behind both projects and those are the trade-offs we tolerate.
But even so, Vuex way better integrated, requires less boilerplate (thanks vue reactivity) than redux, or even zustand, which once you add immer, looks like blobbing all over again.
Honestly, we should do a contest. Take 10 juniors out of school give them a twitter clone to write, 5 in Vue, 5 in React, and come back in a week.
In fact, no need for them to be junior. Let's just take your regular Java dev. Not your 10X HN dev. Just average Joe. See how it goes.
1) Build a clone of a site or implement a design with their tool-of-choice (basic competency). For the ones who opt to start without frameworks, we also get a glimpse at how good their organization skills are.
2) After they are done, we give them several "requirement changes" and see how well/fast they adapt. People can trumpet whatever best practices they believe, but this is the part of the interview where some best practices are more practical than others.
3) Modify an existing project. Here, we pick the opposite of their preferred stack/methods. ie, if they prefer vue, we give them a react or svelte app to modify. If they prefer BEM, we give them functional (we use tailwind); if they prefer utility-first, we give them BEM or smacss, etc. While it may seem on-the-spot, it gives us an insight to how well they work outside their comfort zones and adapt to unfamiliar techs.
Our in-house developers are pragmatists over purists, while still being specialists in various techs. And we're fluid with our tech/tools and everyone is at least an expert in one of the current web techs.
And the best thing (imo) about my team is, everyone is excited about new tech. We always try to one-up each other in our various specializations, hence, are also aware of the limitations of our area-of-expertise.
Which comes in handy during interviews. If a candidate says they are an expert in css, we have a resident css expert that can put their claims to the test. You wouldn't believe how many failed candidates proclaim to be a css purist, only to fall short when it comes to organizing and scaling and documentation.
The whole ecosystem of state management does feel like a bit of a wild west.. but I guess that's often the feeling with javascript.
I ended up settling with easy-peasy, which I think has similar aims to zustand. Definitely appreciate that it uses immer out of the box as that seems like a very sensible default way to go.
import cn from 'classnames'
const prevent = fn => e => e.preventDefault() && fn()
// don't forget key
{items.map(item =>
display && <SomeElement key="" onClick={prevent(foo)} className={cn(current: active)} />
)}And now you have to install and manage deps, import them, while your blob is still less readable because you have maps+lambda+&& to understand before even reaching what DOM element you are manipulating.
The premise of React is that composing primitives is better than having a high level tool to do the job: it's supposed to be more generic, more flexible, easier to learn.
In in my experience, it's true only in the case you don't have a well defined problem. But with frontend UI, we do. We know very well the problem to solve. Give me helpers. Give me wrappers. That's the only case where I welcome a DSL.
I don't want to have to think in functions and workflow in my template.
`onClick={prevent(() => newLambda(what, ever)}}`
That requires you to create 2 new components (which unlike React, will need to be in separate files if you're using SFCs) and pass down all the props another layer.
In the end, I got around it by implementing a "passthrough" component so that you can then do
<component :is="condition ? 'Wrapper' : 'passthrough'>...</component>
but that is far from ideal.> Not only the react blob is impossible to scan
Formatted properly, I don't really find the React example any harder to read.
Your Vue example puts v-for and v-if on the same element, which is confusing - which is evaluated first? (IIRC, the answer depends on which version of Vue you are using).
> it will be different depending of the dev who coded it, because there is no enforced patterns
That applies to the rest of your codebase too, though. It's up to your team to decide on patterns and enforce them through linting, code review, and automatic formatting.
Also, both of your examples are missing `key`, though React will warn you about it and Vue will not.
Vue will warn when you're missing a key on the loop.
>That requires you to create 2 new components (which unlike React, will need to be in separate files if you're using SFCs)
Your components don't need to be in separate files even when using SFC's. Given 'component' can be as simple as adding to any Vue Component or SFC (when adding it to parent component option):
<script>
const myComponent = {
props: ['myProps'],
template: `
<div></div>
`
}
</script>Static typing alone is enough to rule out Vue in my opinion. I even went as far as writing a static type checker for Vue to work around it. It works by compiling the Vue template to a dummy Typescript function that only typechecks if your Vue types are correct.
It found loads of bugs in our code.
However you can use JSX with Vue if you want. All JS libraries are fundamentally the same, and all templating boils to a single function with input->output. Vue just offers HTML instead of JSX by default and it's far more useful in many instances.
No it isn't. There isn't even a way to write down the types properly in Vue templates.
Anyway just saying "it's a tooling issue" doesn't make it not an issue!
> Also Vue supports typescript.
"supports" is a scale, and the support isn't nearly as good as React/TSX.
Simple eh?
Simple eh?
That's just down to a lack of skill and poor decision making in terms of tools to use for the right job.
Don't blame a knife for cutting your finger, don't blame the coffee table for yiur stubbed toe, don't blame tools for your bad code.
But then you are forced to use Javascript on the server side instead of whatever language you are already using. That seems to be a pretty good reason for using Vue as a tool for "progressive enhancement" to me.
For anything else I would most likely use Svelte or maybe React given the right circumstances.
petite-vue is less than half the size of Alpine.
petite-vue has no transition system (maybe this can be an opt-in plugin).
Alpine is developing its own ecosystem and likely will diverge more from Vue in the future. petite-vue aligns with standard Vue behavior whenever possible, so it's less friction moving to standard Vue if needed. It's intended to cover the progressive enhancement use case where standard Vue is less optimized for nowadays.quoted from the link
Now, it may result in an unmaintainable mess in the long run, there is always a threshold for those things.
We initially wanted to use it as a super powered jQuery, then we ended up using Vue as an SPA for part of our app (certain route served a Vue spa to users), now we are going all into the Vue ecosystem for SPA.
I’m a fan of using Vue incrementally, but what you will find is that no editors I have found support Vue inside html templates well. When you use Vue as a jQuery replacement, it gives you some nicety, but it ends having pretty gnarly strings to put html inside of Vue components.
Vue team, if you can get editors to support your string template syntax, that would be killer. Even better, if there was a way to use single file components without the full build step (I.e. bundle up single file components the first time they are needed by a client) and inject that right into the html template that would be amazing.
For only serving SFCs on request, you can use something like https://vitejs.dev/ during local dev, unless I'm misunderstanding, along with code-splitting.
https://v3.vuejs.org/guide/installation.html#runtime-compile...
For more complicated logic, I think working with the @mounted event might work.