Louis Lecouturier
Louis Lecouturier

Reputation: 408

Optimize svg filter turbulence to get better performance

I'm using a svg turbulence filter to create a water effect but it is lagging on low-end and mid-end computers so I was wondering if there was any way to optimize the animation or if there were any workarounds to get the same result...

I've heard about requestAnimationFrame but as I am using ReactJS, I didn't figured out how I could use it and if it would solve any performance issues...

Here's my code :

<svg>
            <filter
              id="turbulence"
              x="0"
              y="0"
              width="100%"
              height="100%"
              colorInterpolationFilters="sRGB"
            >
              <feTurbulence
                id="sea-filter"
                numOctaves="2"
                seed="4"
                baseFrequency="0.02 0.05"
              ></feTurbulence>
              <feDisplacementMap
                scale="25"
                numOctaves="3"
                in2="turbulence"
                in="SourceGraphic"
              ></feDisplacementMap>
            </filter>
            <animate
              xlinkHref="#sea-filter"
              attributeName="baseFrequency"
              dur="120s"
              keyTimes="0;0.5;1"
              values="0.02 0.06;0.04 0.08;0.02 0.06"
              repeatCount="indefinite"
            />
</svg>
<div className={styles.sea} style={{ background: `url(${sea})` }}></div>

How I apply it in CSS :

.sea {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background-image: url("../../../assets/images/Hero/Sea/sea.webp");
  background-size: cover;
  filter: url("#turbulence");
  transform: scale(1.5);
  animation: floating 60s ease forwards infinite;
}

@keyframes floating {
  0% {
    transform: translateY(0) scale(1.5) rotate(0);
  }
  25% {
    transform: translateY(10%) scale(1.5) rotate(2.5deg);
  }
  50% {
    transform: translateY(0) scale(1.5) rotate(0);
  }
  75% {
    transform: translateY(-10%) scale(1.5) rotate(-2.5deg);
  }
  100% {
    transform: translateY(0) scale(1.5) rotate(0);
  }
}

Upvotes: 0

Views: 1280

Answers (1)

Michael Mullany
Michael Mullany

Reputation: 31715

Animating baseFrequency can be performance intensive. When I need to animate turbulence, I add a feColorMatrix/hueRotate animation which seems to be better optimized in browsers.

    <feColorMatrix in="cloudbase" type="hueRotate" values="0" result="cloud">
    <animate attributeName="values" from="0" to="360" dur="20s" repeatCount="indefinite"/>
  </feColorMatrix>

Full example at https://codepen.io/mullany/pen/AZqQqB

Upvotes: 2

Related Questions