-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stateless lightweight components #4006
Comments
Just a little warning here, your workaround should not be used as it because it introduces xss vulnerabilities. |
(Another way of solving the above issue...) Another thing I noticed (about simple stateless components) is that bundle size significantly increases when I extract portion of my svelte HTML into a component. Initial SituationFor example, if I had the following fragment: my-page.svelte:
and I want to extract the MyIcon.svelte:
and use it as: my-page.svelte:
Problemthen the bundle size increases significantly only because I moved some HTML into a new component. Probable SolutionSo, I feel like if the Svelte compiler can figure out that So, after compilation (or transpilation?) my-page.svelte:
could become my-page.svelte:
I have seen tremendous bundle size reductions when avoiding separate components (when used in lots of places in my project). But loose the benefits of making them in their own component files. |
Issue #3898 directly relates to this. |
I'm not so sure your solution of not using components has the benefits you think it does. Consider this REPL https://svelte.dev/repl/5a97ad55d3834ab595fdd4996c7f6fd6?version=3.15.0 There is also the obvious downside of, if not using a component, making any changes to the uses will be a nightmare. Like needing to find all uses of class="fas fa- and replace that with some other icon class library. You should also probably consider minification and gzipping, where repeat uses of the same functions are trivialized by gzip. That isn't to say it can't be handled differently, but I don't believe the bundle size is significantly increased by making components, especially the more they are reused. |
@vipero07 Run some tests using your unmodified code from the REPL you posted above I downloaded it into a zip file and modified only
Note that the |
Fair, however you are forgoing OOP principals like DRY in favor of 0.78 KB (in this case). I get that having a bunch of smaller components this may add up but I imagine the actual difference between many components and copy pasta is just as trivial. 1KB is nothing compared to something like the entire React library. I'm not railing against the idea of helping reduce the overall size. However personally I'd avoid copy pasta or any of the other solutions for that small a savings, and code with the expectation that a future release implements #3898 or something similar. Consider that change occurs in the next release and now you have to refactor everything. |
Overview Svelte generates classes that are able to reconcile changes to data. However, quite often I find myself knowing that the data will change completely when updated and that there is no UI that can store user state like form fields. In this case, the reconciliation may be largely unnecessary and we would do just as well to blast away what's there and start anew. As an example, on the homepage of hn.svelte.dev, if I hit "More..." to go to the next page then there's probably not a need to compare the new data to the old data. I don't need to individually check if Benefits This change would have two large benefits:
Drawback In terms of costs, there is likely some savings we get today by reusing the existing DOM structure that we would lose. However, most of any savings could be gained back by simply working on optimizing fragment creation (#3898). E.g. by creating a template and cloning it instead of recreating the DOM structure for each instance. Implementation I'm thinking this would be specified in Though I wonder if there might be some other way to accomplish this as well. It almost feels like the combination of I implemented this for the
Unanswered questions
|
is there a better or more recent discussion about island architecture or partial hydration with svelte? I saw several issues opened about this (across different repos) but it doesn't seem like anything has been accepted as the plan? As for myself, I think it would be cool to control what the default is, for mostly static sites, I would want to opt-into hydration and for mostly dynamic sites, I would want to be able to opt out. But is this the right place to talk about this? |
This issue could use some love. |
Svelte 5 solves this through better compiler output (example), therefore closing. |
svelte5 output is very different from svelte3/4: // Stateless.svelte (Svelte v5.0.0-next.87)
// Note: compiler output will change before 5.0 is released!
import "svelte/internal/disclose-version";
import * as $ from "svelte/internal/client";
var root = $.template(`<div> </div>`);
export default function Stateless($$anchor, $$props) {
$.push($$props, true);
var div = root();
var text = $.child(div);
$.render_effect(() => $.set_text(text, `Hello ${$.stringify($$props.name)}`));
$.append($$anchor, div);
$.pop();
} svelte 4: /* Stateless.svelte generated by Svelte v4.2.12 */
import {
SvelteComponent,
append,
detach,
element,
init,
insert,
noop,
safe_not_equal,
set_data,
text
} from "svelte/internal";
import "svelte/internal/disclose-version";
function create_fragment(ctx) {
let div;
let t0;
let t1;
return {
c() {
div = element("div");
t0 = text("Hello ");
t1 = text(/*name*/ ctx[0]);
},
m(target, anchor) {
insert(target, div, anchor);
append(div, t0);
append(div, t1);
},
p(ctx, [dirty]) {
if (dirty & /*name*/ 1) set_data(t1, /*name*/ ctx[0]);
},
i: noop,
o: noop,
d(detaching) {
if (detaching) {
detach(div);
}
}
};
}
function instance($$self, $$props, $$invalidate) {
let { name } = $$props;
$$self.$$set = $$props => {
if ('name' in $$props) $$invalidate(0, name = $$props.name);
};
return [name];
}
class Stateless extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, { name: 0 });
}
}
export default Stateless; and just now sniped by @dummdidumm 😂 |
I want svelte to handle simple stateless components better
I've always run into situations where I have lots of simple dumb components that don't have states but the compiler ends up generating a full blown svelte components instead of a simple JS function (a pure function somewhat similar to React's function component) that emits HTML string.
In other words, why can't the svelte compiler generate code for simple stateless components in SSR fashion for the front-end?
Current work-around
{@html MyStatelessComponent(arg1, arg2)}
The solution I would like
An ideal implementation would be for svelte compiler to identify stateless components and emit an efficient code like the one above.
{@html MyStatelessComponent(arg1, arg2)}
type of codeHow important is this feature to you?
Couple of important points:
.svelte
file components with.js
file components is giving us trouble when bundling (specially css purging). It would have been a lot easier if all of our components are ordinary.svelte
components.Additional context
Demo for the above component in REPL: https://svelte.dev/repl/eb9e018b42574c43b788af809e3e8582?version=3.15.0
Look at the unnecessary JS output of the compiler in the above REPL code
The text was updated successfully, but these errors were encountered: