What does this code do?

im about to release my app and i noticed on 2 android devices a drop in frames with expandable cards. and poor FPS in general. so i did performance profiling with chrome and i see framework7 making a lot of function request that cause rendering after i open and close a card. and it keeps on going even after i close the card.
so i found that this code is making it:

function requestAnimationFrame(callback) {
if (win.requestAnimationFrame) {
return win.requestAnimationFrame(callback);
else if (win.webkitRequestAnimationFrame) { return win.webkitRequestAnimationFrame(callback); }
return win.setTimeout(callback, 1000 / 60);

so i comment it out like so:

function requestAnimationFrame(callback) {
if (win.requestAnimationFrame) {
//return win.requestAnimationFrame(callback);
else if (win.webkitRequestAnimationFrame) { return win.webkitRequestAnimationFrame(callback); }
//return win.setTimeout(callback, 1000 / 60);

and now its butter smooth animations and there is nothing running on chrome performance profiler.

my question: did i break something by this change?

Need more context to know what this will effect.

This is just a wrapper function for window.requestAnimationFrame (Window.requestAnimationFrame() - Web APIs | MDN)

Looks like an old wrapper too as webkitRequestAnimationFrame hasnt been needed in 8 years or so.

Additionally if “win” isn’t defined somewhere its going to ReferenceError.

In order to understand what this change impacts you need to find out what is calling this function and give that information, as well as where this function is defined. Especially since F7 uses nextFrame$1 internally to do this kind of wrapping, so its not internal.

chrome doesn’t tell me where is this called. just when.
and as i said in the post. F7 call this alot of times after i open and close expandable card.
here is the graph when the app load:

here after i open expandable card and close it then wait a second

here is detail of one of those calls:

and this will keep on going until i restart the app.

i should point im on 5.7.14

Why are you still on v5?

This issue could well have been fixed in v6. Migration from 5 to 6 isnt too bad.

Upgrade aside, requesting an animation frame is standard behavior. The code you quoted is not causing the issue, just facilitating it. Commenting out what you have doesn’t fix the issue itself.

In your last screenshot initiator should show you more information about what is calling it.

But I really recommend that you update to v6, particularly if you are yet to release. You’re just borrowing trouble for the future if you release with older frameworks.

its not easy to upgrade when you are about to release. plus im on the latest release of v5 and im not even sure that upgrading will fix this issue.

v6 updates the way that Dom7 and Framework7 handle animation frames, so theres every chance it could.

Fork your repo and have a go. If you’re struggling to get the info out of the performance inspector then check some console.trace()'s in those functions you commented out and see where its being generated.

The problem at this point is with deprecated code or your code.

thanks for the suggestion with console.trace();
i was able to trace it to this code

  function render(time) {
    if ( time === void 0 ) time = new Date().getTime();

    if (startTime === null) {
      startTime = time;
    var progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
    var easeProgress = easing === 'linear' ? progress : (0.5 - (Math.cos(progress * Math.PI) / 2));
    var done;
    if (animateTop) { scrollTop = currentTop + (easeProgress * (newTop - currentTop)); }
    if (animateLeft) { scrollLeft = currentLeft + (easeProgress * (newLeft - currentLeft)); }
    if (animateTop && newTop > currentTop && scrollTop >= newTop) {
      el.scrollTop = newTop;
      done = true;
    if (animateTop && newTop < currentTop && scrollTop <= newTop) {
      el.scrollTop = newTop;
      done = true;
    if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {
      el.scrollLeft = newLeft;
      done = true;
    if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {
      el.scrollLeft = newLeft;
      done = true;

    if (done) {
      if (callback) { callback(); }
    if (animateTop) { el.scrollTop = scrollTop; }
    if (animateLeft) { el.scrollLeft = scrollLeft; }

the last line requestAnimationFrame(render); is what keep getting called forever after closing a card.

This is part of the scrollTo function, looks like its trying to scroll to something but never managing it.

Is this where the trace ends or was there more?

From here you can stick another one in to the scrollto function and see what is calling it, or console.log el in the scrollto function and see what element its trying to scroll to.

You could also just replace render and the initial requestAnimationFrame from just below it with the version from v6 and see if that helps, looks like it should be a straight swap and there are some very minor changes.

Or take a look at the whole scrollto function side by side and see if that can be dropped in.

1 Like