-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
perf: optimize non-reactive if statements #13246
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
Conversation
🦋 Changeset detectedLatest commit: 63cc21c The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
5d616d1
to
efd9dbb
Compare
Gah — please don't force push unless it's absolutely essential. I was working on this branch locally and now I have to fight git |
No, it needs to be
It's not a hydration marker, it's only used when not hydrating, and yes it's still necessary |
Made it work in more cases (like {#if typeof window !== 'undefined'}
<span>browser stuff</span>
{/if} So instead of code like this... {
let $$anchor = node;
$.next();
if (typeof window !== 'undefined') {
var span = root_1();
$.append($$anchor, span);
}
} ...we would need to generate code like this... {
let $$anchor = node;
let $$condition = typeof window !== 'undefined';
let $$mismatch = $.hydrate_if($$anchor, $$condition);
if ($$condition) {
var span = root_1();
$.append($$anchor, span);
}
if ($$mismatch) {
$.set_hydrating(true);
}
} ...where function hydrate_if(anchor, condition) {
if (!hydrating) return false;
const is_else = /** @type {Comment} */ (anchor).data === HYDRATION_START_ELSE;
if (condition === is_else) {
// Hydration mismatch: remove everything inside the anchor and start fresh.
// This could happen with `{#if browser}...{/if}`, for example
anchor = remove_nodes();
set_hydrate_node(anchor);
set_hydrating(false);
return true;
}
return false;
} This is obviously quite a bit more code than the status quo... $.if(node, () => typeof window !== 'undefined', ($$anchor) => {
var span = root_1();
$.append($$anchor, span);
}); ...and it won't always be treeshaken away. So there is a trade-off involved here. One other detail: this technically breaks transitions. Today, if you have something like this... {#if foo}
{#if true}
<div transition:fade>...</div>
{/if}
{/if} ...then the transition won't play when |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
requesting changes so we don't merge this until hydration mismatches are solved
Hmm, perhaps we should close this then. My original goal was to shrink the code output, but we'd be going the other direction here. I do still wonder about Here's an example:
Would we run into the same degree of difficult there? Like in that code I think we could determine that |
What would be the benefit? I get why we'd want to do this for |
A standard |
What would the generated code be, for something like this for example? {#each 'abc' as letter}
<span>{letter}</span>
{/each} Today it's this: $.each(node, 0, () => 'abc', $.index, ($$anchor, letter) => {
var span = root_1();
var text = $.child(span);
$.reset(span);
$.template_effect(() => $.set_text(text, letter));
$.append($$anchor, span);
}); Bear in mind it needs to handle hydration (including mismatches), and things like |
Ok, well I'm going to go ahead and close this then |
first part of #13232
I only covered some simple cases for now as I'm still relatively new to working on the compiler so wanted to take baby steps
A couple things to check:
var $$anchor = node;
inside theif
?<!>
hydration marker in this case? I left the code doing that only for{#if}