diff --git a/src/server/render-context.js b/src/server/render-context.js index b23cbd0fd6..3da91d0abc 100644 --- a/src/server/render-context.js +++ b/src/server/render-context.js @@ -66,55 +66,54 @@ export class RenderContext { } next () { - const lastState = this.renderStates[this.renderStates.length - 1] - if (isUndef(lastState)) { - return this.done() - } - /* eslint-disable no-case-declarations */ - switch (lastState.type) { - case 'Element': - case 'Fragment': - const { children, total } = lastState - const rendered = lastState.rendered++ - if (rendered < total) { - this.renderNode(children[rendered], false, this) - } else { + // eslint-disable-next-line + while (true) { + const lastState = this.renderStates[this.renderStates.length - 1] + if (isUndef(lastState)) { + return this.done() + } + /* eslint-disable no-case-declarations */ + switch (lastState.type) { + case 'Element': + case 'Fragment': + const { children, total } = lastState + const rendered = lastState.rendered++ + if (rendered < total) { + return this.renderNode(children[rendered], false, this) + } else { + this.renderStates.pop() + if (lastState.type === 'Element') { + return this.write(lastState.endTag, this.next) + } + } + break + case 'Component': this.renderStates.pop() - if (lastState.type === 'Element') { - this.write(lastState.endTag, this.next) + this.activeInstance = lastState.prevActive + break + case 'ComponentWithCache': + this.renderStates.pop() + const { buffer, bufferIndex, componentBuffer, key } = lastState + const result = { + html: buffer[bufferIndex], + components: componentBuffer[bufferIndex] + } + this.cache.set(key, result) + if (bufferIndex === 0) { + // this is a top-level cached component, + // exit caching mode. + this.write.caching = false } else { - this.next() + // parent component is also being cached, + // merge self into parent's result + buffer[bufferIndex - 1] += result.html + const prev = componentBuffer[bufferIndex - 1] + result.components.forEach(c => prev.add(c)) } - } - break - case 'Component': - this.renderStates.pop() - this.activeInstance = lastState.prevActive - this.next() - break - case 'ComponentWithCache': - this.renderStates.pop() - const { buffer, bufferIndex, componentBuffer, key } = lastState - const result = { - html: buffer[bufferIndex], - components: componentBuffer[bufferIndex] - } - this.cache.set(key, result) - if (bufferIndex === 0) { - // this is a top-level cached component, - // exit caching mode. - this.write.caching = false - } else { - // parent component is also being cached, - // merge self into parent's result - buffer[bufferIndex - 1] += result.html - const prev = componentBuffer[bufferIndex - 1] - result.components.forEach(c => prev.add(c)) - } - buffer.length = bufferIndex - componentBuffer.length = bufferIndex - this.next() - break + buffer.length = bufferIndex + componentBuffer.length = bufferIndex + break + } } } } diff --git a/src/server/write.js b/src/server/write.js index e642081852..9d81d2a8e0 100644 --- a/src/server/write.js +++ b/src/server/write.js @@ -1,6 +1,6 @@ /* @flow */ -const MAX_STACK_DEPTH = 1000 +const MAX_STACK_DEPTH = 900 const noop = _ => _ const defer = typeof process !== 'undefined' && process.nextTick