1.5.3 • Published 4 years ago

svg-slimming v1.5.3

Weekly downloads
36
License
MIT
Repository
-
Last release
4 years ago

svg-slimming

npm version

Change Log

View change log

Introduction

svg-slimming is an SVG compression tool that provides rich customization and follows the W3C SVG specification

Installation

npm install svg-slimming

Use

const svgSlimming = require('svg-slimming');
svgSlimming(svgcode[, config]).then(result => {
	console.log(result);
});

Where svgcode is svg text in string format and config is user-defined optimized configuration

Use svg-slimming-loader

svg-slimming-loader is a loader plugin for webpack, which supports optimization of imported SVG files

Use postcss-svg-slimming

postcss-svg-slimming is a plugin for postcss that supports optimizing inline SVG in CSS

Why choose svg-slimming?

  • Rich and powerful functions, enough personalized configuration parameters
  • Pursue the ultimate optimization effect
  • Try not to destroy the original svg effect
  • Follow the latest svg specifications

vs svgo

Optimization classificationOptimization projectsvg-slimmingsvgo
Basicsvg parsingBuilt-in parser xml-parsersax
BasicNon-svg xml node processing logicRemoveReport error
BasicOversized svg processing×
BasicCompressing Redundant Blanks
BasicRemove Comments
BasicRemove xml declaration and doctype
BasicMerging Text Nodes
BasicSupport optimization CDATA node×
ElementsRemove unnecessary elements
ElementsRemove Invisible Elements
ElementsCollapse unnecessary group nodes
ElementsCollapse unnecessary text container nodes×
Elementsremove elements that do not conform to the svg specification
ElementsOptimize nesting of irregular elements
Elementsoptimization defs
ElementsApply defs directly to the elementv1.5.3
svg elementviewBox vs sizesize preferredviewbox preferred
svg elementremove version attribute
svg elementoptimization xmlns
path elementd attribute of path optimized by calculation
path elementdiscard empty subpaths×
path elementremove invalid waypoints for continuous line instructions×
path elementmerge a instruction under certain conditions×
path elementthinning path node×
path elementsmall size curve command to line commandv1.5.0
path elementremove a directive flag trailing spacev1.5.0
path elementmerge path
shapeshape to path
shaperemove empty shapes (such as circle with radius 0, rect with width and height 0, etc.)×
shapeellipsis and circle rotationv1.5.0
shapesupport thinning path node optimization polyline and polygon×
AttributesRemove empty attributes
AttributesRemove invalid and illegal attributes×
AttributesRemove attributes with the same default values×
AttributesOptimize attributes by analyzing style inheritance chains×
AttributesShorten ID
AttributesRemove px units
AttributesRemove unnecessary fills and strokes×
NumbersOptimize Digital
NumbersPrecisely optimize different types of values×
NumbersDigital to Scientific Notation×
Matrixmerge and shorten transform
MatrixApply transform directly to attributesv1.5.2
ColorOptimize Color
ColorSupport hsl / hsla format color×
ColorSupport rgba format color×
ColorSupports hex color in #rrggbbaa format×
csscss parsingcsscsso
cssmerge style elements×
cssOptimize style content
cssshorten className×
cssstyle to attributes
cssattribute to style√ (badcase exists)×
cssremove css styles not supported by svg√ (badcase exists)×
cssApply style content directly to elements×

Optimized Configuration

The optimized configuration is an object in JSON format, where key is the corresponding configuration item, value is the array, the first item in the array is the switch of the rule, and the second item (if any) is the detailed configuration of the rule.

The following is an example of an optimized configuration:

{
	"collapse-g": [false],
	"combine-transform": [true, {
		"trifuncDigit": 3,
		"sizeDigit": 2,
		"angelDigit": 2
	}]
}

Note: Although the old configuration method can also take effect, it may be removed in the future

{
	"collapse-g": false,
	"combine-transform": [true, 3, 2, 2]
}

collapse-g

  • Default configuration:
{
	"collapse-g": [true]
}
  • Explanation: When the g element has no children, remove the element When the g element has no attribute value, replace the element with a child element * When the g element has only one child element and has no id, class, and mask attributes, copy the attributes of the g element to the child element and replace it with the child element

E.g:

<g></g>
<g fill="red"><rect width="100" height="100"/></g>

After optimization will become:

<rect fill="red" width="100" height="100"/>

collapse-textwrap

  • Default configuration:
{
	"collapse-textwrap": [true]
}
  • Explanation: * For all nested text containers, when the inner text container does not contain any valid attributes, remove the element and promote the text content to the child nodes of the parent element

E.g:

<text></text>
<text fill="red"><tspan>123</tspan></text>

After optimization will become:

<text fill="red">123</text>

combine-path

  • Default configuration:
{
	"combine-path": [true, {
		"disregardFill": false,
		"disregardOpacity": false
	}]
}
  • Explanation: * Merge path nodes that meet the following conditions: 1. All attributes and styles (including inherited styles) are the same 2. adjacent 3. no fill 4. stroke transparency is not less than 1 5. No marker-start, marker-mid, marker-end
  • Configuration parameters: disregardFill Default: false Whether to allow paths that meet the following conditions: 1. stroke is empty 2. fill-rull is not evenodd 3. The transparency of fill is not less than 1 disregardOpacity Default: false Whether to allow paths with transparency less than 1 E.g:
<path d="M0,0L100,100" fill="none" stroke="red" stroke-width="2"/>
<path d="M0,50L100,150" fill="none" stroke="red" stroke-width="2"/>

After optimization will become:

<path d="M0,0L100,100M0,50L100,150" fill="none" stroke="red" stroke-width="2"/>

combine-transform

  • Default configuration:
{
	"combine-transform": [true, {
		"angelDigit": 2,
		"sizeDigit": 2,
		"trifuncDigit": 3
	}]
}
  • Explanation: * Analyze and merge transform attributes
  • Configuration parameters: angelDigit Default value: 2 Limited to 0 or positive integer Angle parameter accuracy of skewX, skewY, rotate sizeDigit Default value: 2 Limited to 0 or positive integer matrix e, f position parameter precision, translate parameter precision, and 3 parameter precision after 2 value rotate trifuncDigit Default: 3 Limited to 0 or positive integer matrix a, b, c, d position parameter precision, scale parameter precision

E.g:

<rect fill="red" width="100" height="100" transform="translate(100,100)scale(2)rotate(180)"/>

After optimization will become:

<rect fill="red" width="100" height="100" transform="matrix(-2,0,0,-2,100,100)"/>

compute-path

  • Default configuration:
{
	"compute-path": [true, {
		"angelDigit": 2,
		"sizeDigit": 2,
		"straighten": 0,
		"thinning": 0
	}]
}
  • Explanation: * Calculate the d attribute of path to make it shorter
  • Configuration parameters: angelDigit Default value: 2 Limited to 0 or positive integer Accuracy of a / A instruction x-axis-rotation sizeDigit Default value: 2 Limited to 0 or positive integer Precision of coordinate type values straighten Default value: 0 Limited to 0 or positive integer Turn the curve command within the specified threshold into a shorter straight command If it is 0, it means that no conversion will be performed. thinning Default value: 0 Limited to 0 or positive integer Thin out path nodes for shorter results 0 means no path thinning is performed, non-zero will be considered as the threshold of thinning nodes

E.g:

<path fill="red" d="M0,0L100,0,100,100,0,100z"/>

After optimization will become:

<path fill="red" d="m0,0h100v100H0z"/>

rm-attribute

  • Default configuration:
{
	"rm-attribute": [true, {
		"keepAria": false,
		"keepEvent": false,
		"rmDefault": true
	}]
}
  • Explanation: * Remove non-canonical attributes (not in SVG spec and not attributes of the xmlns class)
  • Configuration parameters: keepAria Default: false Keep all aria attributes, currently removed by default keepEvent Default: false Keep all Event Monitoring attributes, currently removed by default rmDefault Default: true * Remove the same attribute as the default (if the attribute is inheritable and the parent element has an attribute with the same name, it cannot be removed)

E.g:

<g fill="red">
	<rect fill="black" width="100" height="100" aa="1" bb="2" cc="3" aria-autocomplete="both" onclick="console.log('a');"/>
</g>

After optimization will become:

<g fill="red">
	<rect fill="black" width="100" height="100"/>
</g>

rm-comments

  • Default configuration:
{
	"rm-comments": [true]
}
  • Explanation: * Remove comment

rm-doctype

  • Default configuration:
{
	"rm-doctype": [true]
}
  • Explanation: * Remove DOCTYPE declaration

rm-hidden

  • Default configuration:
{
	"rm-hidden": [true]
}
  • Explanation: Remove elements with display attribute none Removed graphic elements with fill and stroke properties of none Remove text container without children Remove other graphic elements that are not rendered for some reason

The following will be removed:

display IS none

<g style="display:none"></g>

stroke and fill are none

<rect fill="none" stroke="none" width="100" height="100"/>

use element references a non-existing id

<use href="#undefined"/>

Some elements that are not visible because the size attribute is 0, e.g:

<pattern id="pattern-1" width="0" height="0" />

rm-irregular-nesting

  • Default configuration:
{
	"rm-irregular-nesting": [true, {
		"ignore": []
	}]
}
  • Explanation: * Remove irregularly nested tags
  • Configuration parameters: ignore Default:[] * Restricted to a list of strings. If the tag name of an element is in the list, neither the element nor its child elements will validate the nesting rules.

E.g:

<rect fill="red" width="100px" height="100px"><circle cx="100" cy="100" r="100"/></rect>

After optimization will become:

<rect fill="red" width="100" height="100"/>

rm-irregular-tag

  • Default configuration:
{
	"rm-irregular-tag": [true, {
		"ignore": []
	}]
}
  • Explanation: * Remove tags that are not in SVG Specification
  • Configuration parameters: ignore Default:[] * Restricted to a list of strings. If the tag name of an element is in the list, the element will not be removed although it is not a standard SVG tag

rm-px

  • Default configuration:
{
	"rm-px": [true]
}
  • Explanation: * Remove px units and 0 units

E.g:

<rect fill="red" width="100px" height="100px" rx="0pt"/>

After optimization will become:

<rect fill="red" width="100" height="100" rx="0"/>

rm-unnecessary

  • Default configuration:
{
	"rm-unnecessary": [true, {
		"tags": ["desc", "discard", "foreignObject", "video", "audio", "iframe", "canvas", "metadata", "script", "title", "unknown", "image"]
	}]
}

rm-version

  • Default configuration:
{
	"rm-version": [true]
}
  • Explanation: * Remove version attribute from svg element

rm-viewbox

  • Default configuration:
{
	"rm-viewbox": [true]
}
  • Explanation: * When x, y, width, height are exactly the same, remove viewBox property

E.g:

<svg width="1000" height="600" viewBox="0 0 1000 600">

After optimization will become:

<svg width="1000" height="600">

rm-xml-decl

  • Default configuration:
{
	"rm-xml-decl": [true]
}
  • Explanation: * Remove xml declaration

rm-xmlns

  • Default configuration:
{
	"rm-xmlns": [true]
}
  • Explanation: * Remove unreferenced xmlns definitions, remove attributes containing undefined namespaces

E.g:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
	<rect fill="red" width="100" height="100"/>
</svg>

After optimization will become(Since the xlink namespace is not referenced, it was removed):

<svg xmlns="http://www.w3.org/2000/svg">
	<rect fill="red" width="100" height="100"/>
</svg>

shorten-animate

  • Default configuration:
{
	"shorten-animate": [true, {
		"remove": false
	}]
}
  • Explanation: * Optimize animation elements and remove illegal animation elements
  • Configuration parameters: remove Default: false * Remove all animation elements without any verification

E.g:

<animate/><!-- no attributeName -->
<animate attributeName="title" to="test"/><!-- title is not animatable attribute -->
<animate attributeName="x"/><!-- no from/to/by/values -->
<animate attributeName="x" to="abc"/><!-- the value of to does not match x -->

经过优化以上元素都会被移除

shorten-class

  • Default configuration:
{
	"shorten-class": [true]
}
  • Explanation: Shorten className Remove unreferenced className

E.g:

<style>.red_rect {fill: red;}</style>
<rect class="red_rect blue_rect" width="100" height="100"/>

After optimization will become (.red_rect is shortened to .a, .blue_rect is removed directly):

<style>.a {fill: red;}</style>
<rect class="a" width="100" height="100"/>

shorten-color

  • Default configuration:
{
	"shorten-color": [true, {
		"opacityDigit": 3,
		"rrggbbaa": false
	}]
}
  • Explanation: * Keep color definitions as short as possible
  • Configuration parameters: opacityDigit Default: 3 Limited to 0 or positive integer Precision of color alpha values in rgba, hsla format rrggbbaa Default: false * Whether to use 8-digit hexadecimal color (E.g: rgba(255,0,0,0.5) => #ff000080)

E.g:

<rect fill="#ff0000" stroke="rgb(255,255,255)" color="rgba(0,0,0,0)" width="100" height="100"/>

After optimization will become:

<rect fill="red" stroke="#fff" color="transparent" width="100" height="100"/>

shorten-decimal-digits

  • Default configuration:
{
	"shorten-decimal-digits": [true, {
		"angelDigit": 2,
		"sizeDigit": 2
	}]
}
  • Explanation: * Narrowing different types of numerical precision
  • Configuration parameters: angelDigit Default value: 2 Limited to 0 or positive integer Accuracy of numerical values such as transparency, angle, and radian sizeDigit Default value: 2 Limited to 0 or positive integer Accuracy of coordinate and size type values

E.g:

<rect fill="red" width="100.00001" height="100.00001" fill-opacity="0.05999"/>

After optimization will become:

<rect fill="red" width="100" height="100" fill-opacity="6%"/>

shorten-defs

  • Default configuration:
{
	"shorten-defs": [true]
}
  • Explanation: Merge all defs tags Remove invalid defs definitions * Remove empty defs tags

E.g:

<defs>
	<circle id="circle-1" fill="#000" cx="60" cy="60" r="60"></circle>
</defs>
<defs>
	<circle fill-opacity="0.599999964" fill="#000000" cx="60" cy="60" r="60"></circle>
</defs>
<mask id="mask-2" fill="white">
	<use xlink:href="#circle-1" />
</mask>

After optimization will become:

<defs>
	<circle id="path-1" fill="#000" cx="60" cy="60" r="60"></circle>
</defs>
<mask id="mask-2" fill="white">
	<use xlink:href="#path-1" />
</mask>

shorten-filter

  • default allocation:
{
"shorten-filter": [true]
}
  • Explanation: Optimized Filter Elements Remove empty filter elements The width and height of the filter element cannot be 0 or negative Duplicate transferFunctionElement is not allowed under feComponentTransfer * transferFunctionElement retains only necessary attributes based on type

E.g:

<filter></filter>
<filter>
	<feComponentTransfer>
		<feFuncR type="gamma" amplitude="1" exponent="1" offset="0"/>
		<feFuncR type="linear" amplitude="1" exponent="1" offset="0" slope="2"/>
	</feComponentTransfer>
</filter>

After optimization will becomes:

<filter>
	<feComponentTransfer>
		<feFuncR type="linear" slope="2"/>
	</feComponentTransfer>
</filter>

shorten-id

  • Default configuration:
{
	"shorten-id": [true]
}
  • Explanation: Shorten ID Remove unreferenced IDs

E.g:

<defs>
	<circle id="circle-1" fill="#000" cx="60" cy="60" r="60"></circle>
</defs>
<mask id="mask-2" fill="white">
	<use xlink:href="#circle-1" />
</mask>
<rect id="rect-3" fill="red" width="100" height="100" mask="url(#mask-2)"/>

After optimization will become (#rect-3 is removed and the other 2 ids are shortened):

<defs>
	<circle id="a" fill="#000" cx="60" cy="60" r="60"></circle>
</defs>
<mask id="b" fill="white">
	<use xlink:href="#a" />
</mask>
<rect fill="red" width="100" height="100" mask="url(#b)"/>

shorten-shape(v1.5.0+)

  • Default configuration:
{
	"shorten-shape": [true, {
		"thinning": 0
	}]
}
  • Explanation: If the result of the shape mapping to path is shorter, use path If the rx and ry of the ellipse shape are the same, convert to circle
  • Configuration parameters: thinning Default value: 0 Limited to 0 or positive integer Thinning polygons and polylines for shorter results * 0 means do not perform thinning nodes, non-zero will be regarded as the threshold of thinning nodes

E.g:

<rect fill="red" width="100" height="100"/>

After optimization will become:

<path fill="red" d="M0,0H100V100H0z"/>

shorten-style-attr

  • Default configuration:
{
	"shorten-style-attr": [true, {
		"exchange": false,
		"rmDefault": true
	}]
}
  • Explanation: Shorten style attribute In-depth analysis of the style attribute inheritance chain, removing attributes without applicable objects * If there is no style tag, the style and attributes are converted according to the situation
  • Configuration parameters: exchange Default: false Regardless of the existence of the style tag, enforce the mutual conversion of style and attributes Note: svg's style override rules are style attributes > style tags > attributes, so coercion may cause incorrect overrides rmDefault Default: true Remove the same property as the default (only the style property is involved) Some attributes may have different default values for different elements, this rule only verifies a single default value

E.g:

<rect fill="red" style="fill:blue;background:red;"/>

After optimization will become (the fill attribute will be overwritten by the definition of the same name in the style, so it is removed, and the background is not a standard svg style, so it is removed) :

<rect style="fill:blue;"/>

如果 svg 中不存在 style 标签,或 exchange 被设定为 true ,则优化结果为:

<rect fill="blue"/>

shorten-style-tag

  • Default configuration:
{
	"shorten-style-tag": [true, {
		"deepShorten": true,
		"rmDefault": true
	}]
}
  • Explanation: Shorten the content of the style tag Remove duplicate definitions * Remove styles that are not in SVG Specification
  • Configuration parameters: deepShorten Default: true Remove invalid selector Merge multiple same selectors Merge multiple same rules rmDefault Default: true Remove the same property as the default (only the style property is involved) * Some attributes may have different default values for different elements, this rule only verifies a single default value

Other optimization work

Listed below are the optimizations that this tool actively performs

  • Remove white space between labels
  • Remove nodes of type OtherSect and OtherDecl (see NodeType description below the documentation)
  • Self-closing labels without content
  • Merge all style tags
  • Merge all script tags
  • Merge adjacent text type nodes or CDATA nodes
  • Merge all redundant whitespace characters
  • Remove text child nodes from nodes without text content
  • If "<" is not included in the CDATA node, it will be converted into a normal text node

xml-parser

Introduction

An XML parsing tool is included in the project and can be used directly after installing the project without additional installation.

Use

const xmlParser = require('svg-slimming/xml-parser.js');

xmlParser.parse(xmlcode).then(result => {
	console.log(result);
});

console.log(xmlParser.NodeType);

Where xmlcode is xml text in string format (not limited to svg)

NodeType

Node types follow the definition of the DOM specification as much as possible Reference Document

The specific definitions are as follows:

  • Element Node | Tag value: 1 nodeName: \ * Contains attributes and childNodes
  • Text Node | Text value: 3 nodeName: #text * Contains the textContent property
  • CDATA value: 4 nodeName: #cdata * Contains the textContent property
  • OtherSect value: 5 nodeName: #\ Contains the textContent property Refers to blocks other than CDATA, such as <![INCLUDE [...]]>
  • OtherDecl value: 6 nodeName: #\ Contains the textContent property Refers to declarations other than DocType, such as <!ENTITY...>
  • xml declaration | XMLDecl value: 7 nodeName: #xml-decl * Contains the textContent property
  • Notes | Comments value: 8 nodeName: #comments * Contains the textContent property
  • document node | Document value: 9 nodeName: #document Contains childNodes attribute The root node object output by xml-parser
  • DocType value: 10 nodeName: #doctype * Contains the textContent property

Node definition (typescript format)

interface INode {
	nodeName: string;
	nodeType: NodeType;
	namespace?: string;
	textContent?: string;

	readonly attributes?: IAttr[];
	readonly childNodes?: INode[];

	parentNode?: INode;

	cloneNode(): INode;

	appendChild(childNode: INode): void;
	insertBefore(childNode: INode, previousTarget: INode): void;
	replaceChild(childNode: INode, ...children: INode[]): void;
	removeChild(childNode: INode): void;

	hasAttribute(name: string, namespace?: string): boolean;
	getAttribute(name: string, namespace?: string): string;
	setAttribute(name: string, value: string, namespace?: string): void;
	removeAttribute(name: string, namespace?: string): void;
}

Attribute definition (typescript format)

interface IAttr {
	name: string; // Attribute name (without namespace)
	value: string;
	fullname: string; // Attribute full name (including namespace)
	namespace?: string;
}

What are the advantages of this xml parser?

  • Strictly follow the xml specification, it will report an error when it encounters non-compliant xml text, instead of trying to repair
  • Supports parsing xml declaration, doctype, comment, CDATA and other types of nodes
  • XML namespaces will be parsed correctly
  • Attributes of element nodes are correctly parsed, including attributes with namespaces
  • Strictly reflects the content order and format of the original document, and does not do additional things such as text node merge
1.5.3

4 years ago

1.5.2

4 years ago

1.5.1

4 years ago

1.5.0

4 years ago

1.4.3

5 years ago

1.4.2

5 years ago

1.4.1

5 years ago

1.4.0

5 years ago

1.3.5

5 years ago

1.3.4

5 years ago

1.3.3

5 years ago

1.3.2

5 years ago

1.3.1

5 years ago

1.3.0

5 years ago

1.2.14

5 years ago

1.2.13

5 years ago

1.2.12

5 years ago

1.2.11

5 years ago

1.2.10

5 years ago

1.2.9

5 years ago

1.2.8

5 years ago

1.2.7

6 years ago

1.2.6

6 years ago

1.2.5

6 years ago

1.2.4

6 years ago

1.2.3

6 years ago

1.2.2

6 years ago

1.2.1

6 years ago

1.2.0

6 years ago

1.1.9

6 years ago

1.1.8

6 years ago

1.1.7

6 years ago

1.1.6

6 years ago

1.1.5

6 years ago

1.1.4

6 years ago