From 9e96e1cd84d3378bc37ed835247cc5a4eb9d0542 Mon Sep 17 00:00:00 2001 From: pissang Date: Fri, 24 Sep 2021 13:06:30 +0800 Subject: [PATCH 1/2] fix: optimize arraydiff perf in first render and clear --- src/core/arrayDiff.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/core/arrayDiff.ts b/src/core/arrayDiff.ts index 4c1186d37..26b0a33de 100644 --- a/src/core/arrayDiff.ts +++ b/src/core/arrayDiff.ts @@ -14,6 +14,8 @@ type DiffPath = { newPos: number } +// Using O(ND) algorithm +// TODO: Optimize when diff is large. function diff(oldArr: T[], newArr: T[], equals: EqualFunc): DiffComponent[] { if (!equals) { equals = function (a, b) { @@ -32,17 +34,21 @@ function diff(oldArr: T[], newArr: T[], equals: EqualFunc): DiffComponent[ // Seed editLength = 0, i.e. the content starts with the same values var oldPos = extractCommon(bestPath[0], newArr, oldArr, 0, equals); - if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + if (!oldLen // All new created + || !newLen // Clear + || (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen)) { var indices = []; - for (let i = 0; i < newArr.length; i++) { + var allCleared = !newLen && oldLen > 0; + var allCreated = !oldLen && newLen > 0; + for (let i = 0; i < (allCleared ? oldArr : newArr).length; i++) { indices.push(i); } // Identity per the equality and tokenizer return [{ indices: indices, - count: newArr.length, - added: false, - removed: false + count: indices.length, + added: allCreated, + removed: allCleared }]; } From bba6d959b97fdcfdfd490e8d6cc05543b757b140 Mon Sep 17 00:00:00 2001 From: pissang Date: Fri, 24 Sep 2021 13:36:21 +0800 Subject: [PATCH 2/2] fix(svg): fix arc cmd following close will be wrong. --- src/svg/graphic.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/svg/graphic.ts b/src/svg/graphic.ts index f7bbdfb22..8f27ab2e9 100644 --- a/src/svg/graphic.ts +++ b/src/svg/graphic.ts @@ -151,11 +151,15 @@ function bindStyle(svgEl: SVGElement, style: AllStyleOption, el?: Path | TSpan | } class SVGPathRebuilder implements PathRebuilder { - _d: (string | number)[] - _str: string - _invalid: boolean + private _d: (string | number)[] + private _str: string + private _invalid: boolean + + // If is start of subpath + private _start: boolean; reset() { + this._start = true; this._d = []; this._str = ''; } @@ -182,9 +186,6 @@ class SVGPathRebuilder implements PathRebuilder { endAngle: number, anticlockwise: boolean ) { - - const firstCmd = this._d.length === 0; - let dTheta = endAngle - startAngle; const clockwise = !anticlockwise; @@ -221,15 +222,15 @@ class SVGPathRebuilder implements PathRebuilder { } large = true; + } - if (firstCmd) { - // Move to (x0, y0) only when CMD.A comes at the - // first position of a shape. - // For instance, when drawing a ring, CMD.A comes - // after CMD.M, so it's unnecessary to move to - // (x0, y0). - this._d.push('M', x0, y0); - } + if (this._start) { + // Move to (x0, y0) only when CMD.A comes at the + // first position of a shape. + // For instance, when drawing a ring, CMD.A comes + // after CMD.M, so it's unnecessary to move to + // (x0, y0). + this._add('M', x0, y0); } const x = round4(cx + rx * mathCos(startAngle + dTheta)); @@ -240,7 +241,7 @@ class SVGPathRebuilder implements PathRebuilder { } // FIXME Ellipse - this._d.push('A', round4(rx), round4(ry), + this._add('A', round4(rx), round4(ry), mathRound(psi * degree), +large, +clockwise, x, y); } rect(x: number, y: number, w: number, h: number) { @@ -268,6 +269,7 @@ class SVGPathRebuilder implements PathRebuilder { } this._d.push(round4(val)); } + this._start = cmd === 'Z'; } generateStr() {