Skip to content

Option to disable reconciliation on a per-component basis #5369

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

Closed
benmccann opened this issue Sep 9, 2020 · 1 comment
Closed

Option to disable reconciliation on a per-component basis #5369

benmccann opened this issue Sep 9, 2020 · 1 comment
Labels

Comments

@benmccann
Copy link
Member

benmccann commented Sep 9, 2020

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 item.domain, item.url, item.id, item.title, item.user, item.comments_count, etc. changed. If I got a new item I'm fine assuming they all changed. That allows the component to be much smaller and dumber

Benefits

This change would have two large benefits:

  • Smaller file size. E.g. 20% of lines in hn.svelte.dev's [page].js are the p methods and those could be removed. This would result in faster network transfer as well as reduced script parsing times.
  • Hydration could potentially be much cheaper. The main reason we do hydration is to make sure the client UI is in sync with the client's data state. However, if we don't store data state on the client for some components because we don't do reconciliation, then possibly we don't need to update the UI or even transfer the data to the client in the first place. This could be a cool way of doing incremental/partial hydration by allowing to basically skip hydration on a per component-basis. This might make the file size 10% smaller still not to mention the runtime improvements, which would be substantial

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 <svelte:options>. Perhaps something like <svelte:options reconcile=false />. There may be cases where you would want to call a component in a reconciled fashion and non-reconciled fashion. In that case you would simply use the standard reconciled component everywhere. Once you are including that extra code in your app in one place, there's not much need to do something different elsewhere

Though I wonder if there might be some other way to accomplish this as well. It almost feels like the combination of immutable and a keyed each block should give this to me

I implemented this for the page component of the hn.svelte.dev example just by editing the output of the compiler as can be seen below. create_fragment initialized some values that I had to update in p by duplicating the initialization code and that could be refactored out into a separate function to reduce the duplication if desired.

m: function mount(target, anchor) {
	this.target = target;
	...
},
p: function update(ctx, [dirty]) {
	t0_value = /*item*/ ctx[0].title + "";
	if_block0 = /*item*/ ctx[0].domain && create_if_block_1(ctx);
	var anchor = article.nextElementSibling;
	this.d(true);
	this.c();
	this.m(this.target, anchor);
},

Unanswered questions

  • What to call this?
  • I'm not that familiar with Svelte internals, so I'm sure there are things I'm overlooking that might be challenges. But this seems powerful enough that it'd be interesting to brainstorm if it can be made to work
@benmccann
Copy link
Member Author

Closing as duplicate of #4006

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant