Skip to content

Commit

Permalink
refactor(mergePaths): improve performance on large files (svg#1764)
Browse files Browse the repository at this point in the history
  • Loading branch information
mozzie committed Dec 26, 2023
1 parent a287a2a commit 90406f7
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 21 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
3 changes: 2 additions & 1 deletion plugins/convertPathData.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
54 changes: 44 additions & 10 deletions plugins/mergePaths.js
Original file line number Diff line number Diff line change
@@ -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');
Expand Down Expand Up @@ -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];
Expand All @@ -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;
}
Expand All @@ -55,6 +73,9 @@ exports.fn = (root, params) => {
child.children.length !== 0 ||
child.attributes.d == null
) {
if (prevPathData) {
updatePreviousPath(prevChild, prevPathData);
}
prevChild = child;
continue;
}
Expand All @@ -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;
}
Expand All @@ -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(
Expand Down
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<compat/typescript>":
version: 4.8.4
resolution: "typescript@patch:typescript@npm%3A4.8.4#~builtin<compat/typescript>::version=4.8.4&hash=a1c5e5"
"typescript@patch:typescript@^5.3.3#~builtin<compat/typescript>":
version: 5.3.3
resolution: "typescript@patch:typescript@npm%3A5.3.3#~builtin<compat/typescript>::version=5.3.3&hash=a1c5e5"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 563a0ef47abae6df27a9a3ab38f75fc681f633ccf1a3502b1108e252e187787893de689220f4544aaf95a371a4eb3141e4a337deb9895de5ac3c1ca76430e5f0
checksum: f61375590b3162599f0f0d5b8737877ac0a7bc52761dbb585d67e7b8753a3a4c42d9a554c4cc929f591ffcf3a2b0602f65ae3ce74714fd5652623a816862b610
languageName: node
linkType: hard

Expand Down

0 comments on commit 90406f7

Please sign in to comment.