Crash on svg optimization
node: 20.10.0 svgo: 3.3.2
Hi We've encountered an issue while using SVGO to optimize SVG inputs. In the following case, the optimization function hangs, causing really high CPU usage and eventually leading the server to crash after some time.
Through step-by-step debugging, we identified a set of plugins that take an unusually long time to run, effectively blocking the entire process (marked as '// too long' in the code snippet below).
Could someone offer any advice on this please?
A more general question related to this issue: is there a way to implement a timeout mechanism to abort the process if it takes too long, and eventually release the occupied resources?
Thanks a lot!
const optimizedSvg = optimize(svg, {
multipass: true,
plugins: [
{ name: 'removeDoctype' },
{ name: 'removeXMLProcInst' },
{ name: 'removeComments' },
{ name: 'removeMetadata' },
{ name: 'removeEditorsNSData' },
{ name: 'cleanupAttrs' },
{ name: 'mergeStyles' },
{ name: 'inlineStyles', params: { onlyMatchedOnce: false } }, // too long
{ name: 'minifyStyles' },
{ name: 'cleanupIds' },
{ name: 'removeUselessDefs' },
{ name: 'cleanupNumericValues' },
{
name: 'convertColors',
params: {
shorthex: false,
},
},
{
name: 'removeUnknownsAndDefaults',
params: { defaultAttrs: false },
}, // too long
{ name: 'removeNonInheritableGroupAttrs' }, // too long
{ name: 'removeUselessStrokeAndFill' },
{ name: 'cleanupEnableBackground' },
{ name: 'removeHiddenElems' }, // too long
{ name: 'removeEmptyText' },
{ name: 'convertShapeToPath' },
{ name: 'convertEllipseToCircle' },
{ name: 'moveElemsAttrsToGroup' },
{ name: 'moveGroupAttrsToElems' },
{ name: 'collapseGroups' },
{ name: 'convertPathData' }, // too long
{ name: 'convertTransform' },
{ name: 'removeEmptyAttrs' },
{ name: 'removeEmptyContainers' },
{ name: 'removeUnusedNS' },
{ name: 'mergePaths' },
{ name: 'sortAttrs' },
{ name: 'sortDefsChildren' },
{ name: 'removeTitle' },
{ name: 'removeDesc' },
],
});
That is the largest SVG I've ever seen It embeds hundreds of clip paths and images It's not just SVGO that it troubles, when I tried to open it with Inkscape it took a few minutes and almost crashed twice
I find it unlikely that SVGO would be able to efficiently handle this SVG at any point, so if I were you I would:
- first, try to get a more simplified, less bloated version of it
- alternatively, just use a raster version (it's actually smaller this way, at 10-20% of the size depending on resolution)
- if for some reason you need to keep using the SVG, exclude it from your SVGO inputs
hi @KTibow ,
Thanks for your reply!
I really appreciate everything the SVGO library provides. I agree with you that it's relatively uncommon to encounter an SVG file over 3MB in size with such intricate details. Typically, we're more likely dealing with simpler SVGs like logos. However, since our application involves public user input, where designers can upload files, we don't have full control over the complexity or size of the SVGs being submitted.
This is why I asked about the possibility of adding a timeout configuration. Do you have any additional suggestions for avoiding situations like this?
Thanks in advance!
Why not only run optimization on small files or implement the timeout inside whatever program is falling SVGO
I’d like to try a timeout solution, but it seems that once optimization starts on such a large input, SVGO quickly consumes CPU resources, leading to server crashes.
Perhaps the simplest solution would be to just limit the size of uploaded SVGs.
Try disabling mergePaths–it has some some complicated logic to check for intersections which may be too much for your case.
This doesn't have much to do with the file size. SVGO doesn't handle styles efficiently, and this file has about 8500 style rules.
I've been looking into some of the scalability problems with SVGO, and working on a version that handles this better - https://www.npmjs.com/package/svgo-ll. It still takes almost a minute on a not particularly fast laptop. Almost all of the time is spent inlining the styles, other than that it's pretty fast.
The inlining could be sped up significantly for this file, but it may be enough of a special case that it's not worth it.
Compression on the current version is 22.7%.
@johnkenny54 Thanks for your feedback! This particular SVG comes from one of our clients and is one of the most complex we've dealt with so far. Since then, we've implemented a file size limit for SVGs (up to 1.5MB) to keep things running smoothly. If SVGO2 has stable releases, we'll definitely run some benchmarks later!