In the update, I improve the filter implementation.
First approach
In the first implementation, I created two filter elements with the following ids:
distortion-filter, which used thefeTurbulenceandfeDisplacementMapelements to create the irregular drawing effectblur-filter, which used thefeGaussianBlurelement to add some blur
With the filter elements defined, I applied them to two nested g elements to apply one filter on top of the other:
I omitted some elements and attributes to keep the code concise.
<svg> <defs> <filter id="distortion-filter"> <feTurbulence /> <feDisplacementMap /> </filter> <filter id="blur-filter"> <feGaussianBlur /> </filter> <!-- `path` elements --> </defs> <!-- `rect` element --> <g filter="url(#blur-filter)"> <g filter="url(#distortion-filter)"> <!-- `use` elements --> </g> </g></svg>This approach worked, but there is a more correct way that performs better.
result, in, and in2 attributes
I used the result, in, and in2 attributes in the previous approach, passing the result of the feTurbulence element to the input of the feDisplacementMap element.
Likewise, this time I used the result of the feDisplacementMap element as input to the feGaussianBlur element, using the result and in attributes, respectively.
Thus, I eliminated the need for two filter elements, and two nested g elements:
I omitted some elements and attributes to keep the code concise.
<svg> <defs> <filter id="distortion-filter"> <feTurbulence type="turbulence" baseFrequency="1" numOctaves="2" seed="0" result="turbulence" > <!-- `animate` element --> </feTurbulence> <feDisplacementMap in="SourceGraphic" in2="turbulence" scale="0.3" result="displacement-map" /> <feGaussianBlur in="displacement-map" stdDeviation="0.06" /> </filter> <!-- `path` elements --> </defs> <!-- `rect` element --> <g filter="url(#distortion-filter)"> <!-- `use` elements --> </g></svg>Result
With this small change, I improved the animation fluidity in Safari:

First approach

Second approach