2

I have implemented a css transition that translates and scales text, which runs smooth on my computer but not on my phone (Android with Chrome browser), and I'm wondering why.

I've already changed my transition to use translate instead of left/top for positioning in the hope that it would improve performance, but it is till laggy (I reckon ~5fps at the end of the transition). Hence I'm wondering what factor makes my animation slow, is it the fact that it is vector graphics, the large amount of scaling, the fact that it happens during a page transition (I'm using swup), or something else.

Code

My transition:

transition: transform 1.5s

from (--big-me-x is around 50vw, and y around 50vh)

transform: translateX(-50%) translateX(var(--big-me-x))
           translateY(-50%) translateY(var(--big-me-y))
           scale(0.75);

to

transform: translateX(-50%) translateX(50vw) translateX(-18vh)
           translateY(-75%) translateY(50vh)
           scale(5);

Or see it online (it's fast now!).

  • To clarify: do you use Chrome Browser on your desktop as well? – Martin Aug 15 '19 at 14:03
  • Possibly related reading: https://stackoverflow.com/questions/12148012/what-exact-parts-of-css3-are-gpu-accelerated – Martin Aug 15 '19 at 14:05
  • Also [**this topic**](https://stackoverflow.com/questions/14277206/what-are-the-golden-rules-to-increase-css3-transition-performance-on-mobile-de) – Martin Aug 15 '19 at 14:06
  • I have tested it on Chrome, Firefox and Edge on my desktop, and the transition was ~60fps on all of them. Thanks for the links, I gather from them that the transform property should be GPU accelerated. I guess the GPU on my desktop is better than on my phone but the difference in performance shouldn't be that drastic right? There is no way to throttle the GPU in chrome devtools I think so it's a bit hard to test. Anyways, thanks for the comments! – Steven van den Broek Aug 15 '19 at 14:22

1 Answers1

1

Animating shadows is usually discouraged. You can instead use a drop-shadow filter, like in the snippet below.

It would look something like this:

#big-me {
  position: absolute;
  left: 0px;
  top: 0px;
  letter-spacing: 0.04em;
  font-size: 27vh;
  line-height: 14vw;
  font-family: 'Playfair Display';
  font-style: italic;
  font-variant: small-caps;
  font-weight: lighter;
  z-index: 1;
  color: red;
  filter: drop-shadow(-0.05vw 0.2vmin 0.4px black);
  opacity: 0.7;
  transform: translateX(-50%) translateX(50vw) translateY(-50%) translateY(50vh)  scale(0.75);
  transition: opacity 0.3s, transform 0.3s, filter 0.3s;
  will-change: transform;
}

#big-me:hover {
  opacity: 1;
  filter: drop-shadow(-0.1vw 0.4vmin 5px black);
  transform: translateX(-50%) translateX(50vw) translateY(-50%) translateY(50vh) scale(0.8);
}
<a href="/me.html" id="big-me" class="transition-enlarge">ME</a>

If you still see poor results, you can try adding the will-change property to tell the browser that the element will be somewhat animated. You can read more about it here.

  • Thanks, it works much better now. I overlooked the fact that even if you don't specify the shadow in the transition property, it of course still has to recalculate it when you scale the text. Strangely enough, the will-change property didn't help me, putting it in #big-me caused a blur when scaling, and putting it in the hover state styling surprisingly reduced the performance. Also, thanks for pointing out the filter box-shadow property, I wasn't familiar with it. – Steven van den Broek Aug 15 '19 at 15:09