only make component dirty if value has changed

pull/1864/head
Rich Harris 7 years ago
parent 05a4f5d7c8
commit 701af7f7fb

@ -145,33 +145,10 @@ export default function dom(
`
: `@noop`;
const body = [
deindent`
$$init($$make_dirty) {
${component.init_uses_self && `const $$self = this;`}
${should_add_css &&
`if (!document.getElementById("${component.stylesheet.id}-style")) @add_css();`}
${component.javascript || component.exports.map(x => `let ${x.name};`)}
${component.partly_hoisted.length > 0 && component.partly_hoisted.join('\n\n')}
return [
// TODO only what's needed by the template
() => ({ ${component.declarations.join(', ')} }),
${inject_props},
${inject_refs}
];
}
$$create_fragment(${component.alias('component')}, ctx) {
${block.getContents()}
}
`
];
const body = [];
const debug_name = `<${component.customElement ? component.tag : name}>`;
const not_equal = component.options.immutable ? `@not_equal` : `@safe_not_equal`;
if (component.options.dev) {
// TODO check no uunexpected props were passed, as well as
@ -219,11 +196,35 @@ export default function dom(
});
builder.addBlock(deindent`
function $$create_fragment(${component.alias('component')}, ctx) {
${block.getContents()}
}
${component.module_javascript}
${component.fully_hoisted.length > 0 && component.fully_hoisted.join('\n\n')}
function $$init($$self, $$make_dirty) {
${should_add_css &&
`if (!document.getElementById("${component.stylesheet.id}-style")) @add_css();`}
${component.javascript || component.exports.map(x => `let ${x.name};`)}
${component.partly_hoisted.length > 0 && component.partly_hoisted.join('\n\n')}
return [
// TODO only what's needed by the template
() => ({ ${component.declarations.join(', ')} }),
${inject_props},
${inject_refs}
];
}
class ${name} extends ${superclass} {
constructor(options) {
super(options, $$init, $$create_fragment, ${not_equal});
}
${body.join('\n\n')}
}
`);

@ -5,7 +5,7 @@ import { blankObject } from './utils.js';
import { children } from './dom.js';
export class $$Component {
constructor(options) {
constructor(options, init, create_fragment, not_equal) {
this.$$beforeRender = [];
this.$$onMount = [];
this.$$afterRender = [];
@ -16,14 +16,15 @@ export class $$Component {
this.$$slotted = options.slots || {};
set_current_component(this);
const [get_state, inject_props, inject_refs] = this.$$init(
const [get_state, inject_props, inject_refs] = init(
this,
key => {
this.$$make_dirty(key);
if (this.$$bindings[key]) this.$$bindings[key](get_state()[key]);
}
);
this.$$ = { get_state, inject_props, inject_refs };
this.$$ = { get_state, inject_props, inject_refs, not_equal };
this.$$refs = {};
@ -35,7 +36,7 @@ export class $$Component {
}
run_all(this.$$beforeRender);
this.$$fragment = this.$$create_fragment(this, this.$$.get_state());
this.$$fragment = create_fragment(this, this.$$.get_state());
if (options.target) {
intro.enabled = !!options.intro;
@ -63,8 +64,11 @@ export class $$Component {
$set(values) {
if (this.$$) {
const state = this.$$.get_state();
this.$$.inject_props(values);
for (const key in values) this.$$make_dirty(key);
for (const key in values) {
if (this.$$.not_equal(state[key], values[key])) this.$$make_dirty(key);
}
}
}
@ -137,7 +141,7 @@ export class $$ComponentDev extends $$Component {
throw new Error(`'target' is a required option`);
}
super(options);
super(...arguments);
this.$$checkProps();
}

@ -47,4 +47,12 @@ export function run_all(fns) {
export function is_function(thing) {
return typeof thing === 'function';
}
export function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
export function not_equal(a, b) {
return a != a ? b == b : a !== b;
}
Loading…
Cancel
Save