Open
Description
Use case: description, code
In an ideal world we want to optimize SVG output by removing styles that can be inherited.
This mainly has an impact at >>1K nodes where the output is in the 1MB scale of magnitude.
There's not much of a story here at the moment, but the library did previously lean on unset
until the #90 regression:
dom-to-image-more/src/dom-to-image-more.js
Lines 915 to 934 in 2c54d7f
There's two strategies I tried to research:
- The curveball method: reimplement CSSOM in the "cloning" stage using
document.styleSheets
- Multiple PITAs and footguns involved (specificity, source order and the size of this library)
- Inheritance is done with a
while
loop on.parentNode
, and a hardcoded list of inheritable CSS props
- The easier, "just as good" way: a post-process op in
toSvg
- Append the output to our iframe sandbox
- use a
TreeWalker
to iterate over the nodes - see if removing an inline value changes the computed style
Some starter code, but this code snippet:
- doesn't restore CSS props in place, making it indeterministic and liable to break styling
- doesn't go in ascending order up the DOM tree, thus removing inherited properties that are necessary
const treeWalker = document.createTreeWalker(document.querySelector('foreignObject > *'), NodeFilter.SHOW_ELEMENT)
const elementList = [];
let currentNode = treeWalker.currentNode;
while (currentNode) {
elementList.push(currentNode);
currentNode = treeWalker.nextNode();
}
elementList.forEach(function(element) {
const inlineStyles = element.style;
const computedStyles = getComputedStyle(element);
util.asArray(inlineStyles).forEach(function(name) {
if (inlineStyles.cssText.includes(name + ': ' + value + ';')) {
const value = inlineStyles.getPropertyValue(name);
inlineStyles.removeProperty(name);
if (value !== computedStyles.getPropertyValue(name)) {
inlineStyles[name] = value;
}
}
});
});
Metadata
Metadata
Assignees
Labels
No labels