various optimizations

* avoid teardown for nested textnodes
* avoid detaching children of a nested each
pull/79/head
Arpad Borsos 8 years ago
parent a59dc64880
commit 348c5e4656
No known key found for this signature in database
GPG Key ID: 908EDF65263368B4

@ -14,6 +14,24 @@ export default function generate ( parsed, source, options ) {
const renderers = [];
const generator = {
addElement ( name, renderStatement, needsIdentifier = false ) {
const needsTeardown = generator.current.localElementDepth === 0;
if ( needsIdentifier || needsTeardown ) {
generator.current.initStatements.push( deindent`
var ${name} = ${renderStatement};
${generator.appendToTarget( name )};
` );
} else {
generator.current.initStatements.push( deindent`
${generator.current.target}.appendChild( ${renderStatement} );
` );
}
if ( needsTeardown ) {
generator.current.teardownStatements.push( deindent`
if ( detach ) ${name}.parentNode.removeChild( ${name} );
` );
}
},
appendToTarget ( name ) {
if ( generator.current.useAnchor && generator.current.target === 'target' ) {
return `anchor.parentNode.insertBefore( ${name}, anchor )`;

@ -5,6 +5,7 @@ export default {
enter ( generator, node ) {
const i = generator.counters.each++;
const name = `eachBlock_${i}`;
const anchor = `${name}_anchor`;
const renderer = `renderEachBlock_${i}`;
const listName = `${name}_value`;
@ -13,10 +14,9 @@ export default {
const { dependencies, snippet } = generator.contextualise( node.expression );
generator.current.initStatements.push( deindent`
var ${name}_anchor = document.createComment( ${JSON.stringify( `#each ${generator.source.slice( node.expression.start, node.expression.end )}` )} );
${generator.appendToTarget( `${name}_anchor` )};
generator.addElement( anchor, `document.createComment( ${JSON.stringify( `#each ${generator.source.slice( node.expression.start, node.expression.end )}` )} )`, true );
generator.current.initStatements.push( deindent`
var ${name}_value = ${snippet};
var ${name}_fragment = document.createDocumentFragment();
var ${name}_iterations = [];
@ -25,7 +25,7 @@ export default {
${name}_iterations[i] = ${renderer}( ${generator.current.params}, ${listName}, ${listName}[i], i, component, ${name}_fragment );
}
${name}_anchor.parentNode.insertBefore( ${name}_fragment, ${name}_anchor );
${anchor}.parentNode.insertBefore( ${name}_fragment, ${anchor} );
` );
generator.current.updateStatements.push( deindent`
@ -43,16 +43,15 @@ export default {
${name}_iterations[i].teardown( true );
}
${name}_anchor.parentNode.insertBefore( ${name}_fragment, ${name}_anchor );
${anchor}.parentNode.insertBefore( ${name}_fragment, ${anchor} );
${name}_iterations.length = ${listName}.length;
` );
const needsTeardown = generator.current.localElementDepth === 0;
generator.current.teardownStatements.push( deindent`
for ( let i = 0; i < ${name}_iterations.length; i += 1 ) {
${name}_iterations[i].teardown( detach );
${name}_iterations[i].teardown( ${needsTeardown ? 'detach' : 'false'} );
}
if ( detach ) ${name}_anchor.parentNode.removeChild( ${name}_anchor );
` );
const indexNames = Object.assign( {}, generator.current.indexNames );

@ -56,15 +56,15 @@ export default {
const { params, target } = generator.current;
const name = `ifBlock_${i}`;
const anchor = `${name}_anchor`;
const getBlock = `getBlock_${i}`;
const currentBlock = `currentBlock_${i}`;
const conditionsAndBlocks = getConditionsAndBlocks( generator, node, `renderIfBlock_${i}` );
generator.current.initStatements.push( deindent`
var ${name}_anchor = document.createComment( ${JSON.stringify( `#if ${generator.source.slice( node.expression.start, node.expression.end )}` )} );
${generator.appendToTarget( `${name}_anchor` )};
generator.addElement( anchor, `document.createComment( ${JSON.stringify( `#if ${generator.source.slice( node.expression.start, node.expression.end )}` )} )`, true );
generator.current.initStatements.push( deindent`
function ${getBlock} ( ${params} ) {
${conditionsAndBlocks.map( ({ condition, block }) => {
return `${condition ? `if ( ${condition} ) ` : ''}return ${block};`;
@ -72,7 +72,7 @@ export default {
}
var ${currentBlock} = ${getBlock}( ${params} );
var ${name} = ${currentBlock} && ${currentBlock}( ${params}, component, ${target}, ${name}_anchor );
var ${name} = ${currentBlock} && ${currentBlock}( ${params}, component, ${target}, ${anchor} );
` );
generator.current.updateStatements.push( deindent`
@ -82,18 +82,10 @@ export default {
${name}.update( changed, ${params} );
} else {
if ( ${name} ) ${name}.teardown( true );
${name} = ${currentBlock} && ${currentBlock}( ${params}, component, ${target}, ${name}_anchor );
${name} = ${currentBlock} && ${currentBlock}( ${params}, component, ${target}, ${anchor} );
}
` );
const teardownStatements = [
`if ( ${name} ) ${name}.teardown( detach );`
];
if ( generator.current.localElementDepth === 0 ) {
teardownStatements.push( `if ( detach ) ${name}_anchor.parentNode.removeChild( ${name}_anchor );` );
}
generator.current.teardownStatements.push( teardownStatements.join( '\n' ) );
generator.current.teardownStatements.push( `if ( ${name} ) ${name}.teardown( detach );` );
}
};

@ -4,23 +4,13 @@ export default {
enter ( generator, node ) {
const name = generator.current.counter( 'text' );
generator.addSourcemapLocations( node.expression );
const { snippet } = generator.contextualise( node.expression );
generator.current.initStatements.push( deindent`
var ${name} = document.createTextNode( ${snippet} );
${generator.appendToTarget( name )};
` );
generator.addSourcemapLocations( node.expression );
generator.addElement( name, `document.createTextNode( ${snippet} )`, true );
generator.current.updateStatements.push( deindent`
${name}.data = ${snippet};
` );
if ( generator.current.localElementDepth === 0 ) {
generator.current.teardownStatements.push( deindent`
if ( detach ) ${name}.parentNode.removeChild( ${name} );
` );
}
}
};

@ -2,21 +2,7 @@ import deindent from '../utils/deindent.js';
export default {
enter ( generator, node ) {
if ( generator.elementDepth > 1 ) {
generator.current.initStatements.push( deindent`
${generator.current.target}.appendChild( document.createTextNode( ${JSON.stringify( node.data )} ) );
` );
} else {
const name = generator.current.counter( `text` );
generator.current.initStatements.push( deindent`
var ${name} = document.createTextNode( ${JSON.stringify( node.data )} );
${generator.appendToTarget( name )};
` );
generator.current.teardownStatements.push( deindent`
if ( detach ) ${name}.parentNode.removeChild( ${name} );
` );
}
const name = generator.current.counter( `text` );
generator.addElement( name, `document.createTextNode( ${JSON.stringify( node.data )} )` );
}
};

Loading…
Cancel
Save