From 90406f796718dc63a6723fcda8b7c84379544972 Mon Sep 17 00:00:00 2001 From: mozzie Date: Tue, 26 Dec 2023 02:53:44 +0200 Subject: [PATCH] refactor(mergePaths): improve performance on large files (#1764) --- package.json | 2 +- plugins/convertPathData.js | 3 ++- plugins/mergePaths.js | 54 +++++++++++++++++++++++++++++++------- yarn.lock | 18 ++++++------- 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index e0b4873c4..3b51fb00e 100644 --- a/package.json +++ b/package.json @@ -103,6 +103,6 @@ "rollup": "^2.79.1", "rollup-plugin-terser": "^7.0.2", "tar-stream": "^3.1.6", - "typescript": "^4.8.4" + "typescript": "^5.3.3" } } diff --git a/plugins/convertPathData.js b/plugins/convertPathData.js index 5272ac775..23c9b56ab 100644 --- a/plugins/convertPathData.js +++ b/plugins/convertPathData.js @@ -154,7 +154,8 @@ exports.fn = (root, params) => { precision !== false ? +Math.pow(0.1, precision).toFixed(precision) : 1e-2; - roundData = precision > 0 && precision < 20 ? strongRound : round; + roundData = + precision && precision > 0 && precision < 20 ? strongRound : round; if (makeArcs) { arcThreshold = makeArcs.threshold; arcTolerance = makeArcs.tolerance; diff --git a/plugins/mergePaths.js b/plugins/mergePaths.js index e7b35e5a7..fe982c136 100644 --- a/plugins/mergePaths.js +++ b/plugins/mergePaths.js @@ -1,7 +1,9 @@ 'use strict'; /** + * @typedef {import("../lib/types").PathDataItem} PathDataItem * @typedef {import('../lib/types').XastChild} XastChild + * @typedef {import('../lib/types').XastElement} XastElement */ const { collectStylesheet, computeStyle } = require('../lib/style.js'); @@ -35,6 +37,19 @@ exports.fn = (root, params) => { /** @type {XastChild[]} */ const elementsToRemove = []; let prevChild = node.children[0]; + let prevPathData = null; + + /** + * @param {XastElement} child + * @param {PathDataItem[]} pathData + */ + const updatePreviousPath = (child, pathData) => { + js2path(child, pathData, { + floatPrecision, + noSpaceAfterFlags, + }); + prevPathData = null; + }; for (let i = 1; i < node.children.length; i++) { const child = node.children[i]; @@ -45,6 +60,9 @@ exports.fn = (root, params) => { prevChild.children.length !== 0 || prevChild.attributes.d == null ) { + if (prevPathData && prevChild.type === 'element') { + updatePreviousPath(prevChild, prevPathData); + } prevChild = child; continue; } @@ -55,6 +73,9 @@ exports.fn = (root, params) => { child.children.length !== 0 || child.attributes.d == null ) { + if (prevPathData) { + updatePreviousPath(prevChild, prevPathData); + } prevChild = child; continue; } @@ -65,12 +86,17 @@ exports.fn = (root, params) => { computedStyle['marker-mid'] || computedStyle['marker-end'] ) { + if (prevPathData) { + updatePreviousPath(prevChild, prevPathData); + } prevChild = child; continue; } - const childAttrs = Object.keys(child.attributes); if (childAttrs.length !== Object.keys(prevChild.attributes).length) { + if (prevPathData) { + updatePreviousPath(prevChild, prevPathData); + } prevChild = child; continue; } @@ -84,25 +110,33 @@ exports.fn = (root, params) => { }); if (areAttrsEqual) { + if (prevPathData) { + updatePreviousPath(prevChild, prevPathData); + } prevChild = child; continue; } - const prevPathJS = path2js(prevChild); - const curPathJS = path2js(child); - - if (force || !intersects(prevPathJS, curPathJS)) { - prevPathJS.push(...curPathJS); - js2path(prevChild, prevPathJS, { - floatPrecision, - noSpaceAfterFlags, - }); + const hasPrevPath = prevPathData != null; + const currentPathData = path2js(child); + prevPathData = prevPathData ?? path2js(prevChild); + if (force || !intersects(prevPathData, currentPathData)) { + prevPathData.push(...currentPathData); elementsToRemove.push(child); continue; } + if (hasPrevPath) { + updatePreviousPath(prevChild, prevPathData); + } + prevChild = child; + prevPathData = null; + } + + if (prevPathData && prevChild.type === 'element') { + updatePreviousPath(prevChild, prevPathData); } node.children = node.children.filter( diff --git a/yarn.lock b/yarn.lock index 49e179584..8baf0bdf7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4449,7 +4449,7 @@ __metadata: rollup: ^2.79.1 rollup-plugin-terser: ^7.0.2 tar-stream: ^3.1.6 - typescript: ^4.8.4 + typescript: ^5.3.3 bin: svgo: ./bin/svgo languageName: unknown @@ -4572,23 +4572,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^4.8.4": - version: 4.8.4 - resolution: "typescript@npm:4.8.4" +"typescript@npm:^5.3.3": + version: 5.3.3 + resolution: "typescript@npm:5.3.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 3e4f061658e0c8f36c820802fa809e0fd812b85687a9a2f5430bc3d0368e37d1c9605c3ce9b39df9a05af2ece67b1d844f9f6ea8ff42819f13bcb80f85629af0 + checksum: 2007ccb6e51bbbf6fde0a78099efe04dc1c3dfbdff04ca3b6a8bc717991862b39fd6126c0c3ebf2d2d98ac5e960bcaa873826bb2bb241f14277034148f41f6a2 languageName: node linkType: hard -"typescript@patch:typescript@^4.8.4#~builtin": - version: 4.8.4 - resolution: "typescript@patch:typescript@npm%3A4.8.4#~builtin::version=4.8.4&hash=a1c5e5" +"typescript@patch:typescript@^5.3.3#~builtin": + version: 5.3.3 + resolution: "typescript@patch:typescript@npm%3A5.3.3#~builtin::version=5.3.3&hash=a1c5e5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 563a0ef47abae6df27a9a3ab38f75fc681f633ccf1a3502b1108e252e187787893de689220f4544aaf95a371a4eb3141e4a337deb9895de5ac3c1ca76430e5f0 + checksum: f61375590b3162599f0f0d5b8737877ac0a7bc52761dbb585d67e7b8753a3a4c42d9a554c4cc929f591ffcf3a2b0602f65ae3ce74714fd5652623a816862b610 languageName: node linkType: hard