From e4b1b57fd7117a19cdb376dcb156606e0cc32a94 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 2 Dec 2018 12:31:16 -0500 Subject: [PATCH] fix(ssr): adjust call stack size defer threshold fix #8545 --- src/server/render-context.js | 91 ++++++++++++++++++------------------ src/server/write.js | 2 +- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/src/server/render-context.js b/src/server/render-context.js index b23cbd0fd64..3da91d0abca 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 e642081852c..9d81d2a8e04 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