Hi to optimize my huge svg components I'm tryin to do something similiar to this tutorial: https://medium.com/@ians/rendering-svgs-as-images-directly-in-react-a26615c45770 , so far I've come up with this
import React from 'react';
import { renderToStaticMarkup } from 'react-dom/server'
function Image({children}) {
let draw = <svg xmlns="http://www.w3.org/2000/svg">{children}</svg>
let svgToMiniDataURI = require('mini-svg-data-uri')
let image = svgToMiniDataURI(renderToStaticMarkup(draw))
return <image href={image} />
}
export default Image
It's working pretty good but I don't want to use renderToStaticMarkup for one reason: I use getBBox method inside my SVG components and that's something really hard to avoid using.
Any Idea on how I could achieve something similiar without using SSR? Or any way to get getBBox working on server side (I saw phantomjs but I think that would kill performance instead of helping and it doesn't seem like a really nice solution)
CodePudding user response:
So the alternative to do this would be to get a reference of the component we load in the page, get its html content after it has been rendered by React and then change it. Here's the code for my example function Image({children}) { let svgToMiniDataURI = require('mini-svg-data-uri')
const imageContainer = React.useCallback(node => {
if (node !== null) {
Image.timer = setTimeout(()=>{ //I used this delay so my component get its useEffects done
const image = svgToMiniDataURI(node.outerHTML)
//here we could have also set a state with the href value and then based on that state in the return we choose to render the image instead of the normal comp
if (node.parentNode)
node.outerHTML = `<image href="${image}" />`
}, 0.1)
}
}, [])
React.useEffect(() => {
return () => {
clearTimeout(Image.timer);
}
}, [])
return <svg xmlns="http://www.w3.org/2000/svg" ref={imageContainer}>{children}</svg>
}