Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use requestAnimationFrame replace setInterval #392

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Gaubee
Copy link
Contributor

@Gaubee Gaubee commented Jan 15, 2017

requestAnimationFrame can better use of CPU performance than setInterval. Especially when there are a lot of animation running at the same time.

Signed-off-by: Gaubee <gaubeebangeel@gmail.com>
@ChALkeR
Copy link
Member

ChALkeR commented Jan 15, 2017

Good catch!

I think that the fallback could be simplified, though.

The usage share of browsers that implement requestAnimationFrame vendor-prefixed is near zero (Safari 6, Firefox 22, Chrome 22, nothing for ms), according to http://caniuse.com/requestanimationframe, so it would be perfectly fine to fallback to setInterval on those — it wouldn't even break anything.

Also, checking AnimationIntervalIdMap is not necessary — browsers that implement unprefixed requestAnimationFrame support cancelAnimationFrame.

Something like this should work (I haven't tested):

  let startAnimation = callback => setInterval(callback, this.$interval);
  let stopAnimation = clearInterval;
  if (window.requestAnimationFrame && window.cancelAnimationFrame) {
    const animations = [];
    startAnimation = callback => {
      const id = animations.length;
      const ticker = () => {
        callback();
        animations[id] = window.requestAnimationFrame(ticker);
      };
      animations.push(window.requestAnimationFrame(ticker));
      return id;
    };
    stopAnimation = id => {
      window.cancelAnimationFrame(animations[id]);
      animations[id] = null;
    };
  }

That could be further simplified, given that there is only one global ticker per engine, so the animations array isn't actually needed here.

Perhaps something like this will work:

QmlWeb.useAnimationFrames = window.requestAnimationFrame && window.cancelAnimationFrame;
...

  // Start the engine
  start() {
    QmlWeb.engine = this;
    const QMLOperationState = QmlWeb.QMLOperationState;
    if (this.operationState !== QMLOperationState.Running) {
      this.operationState = QMLOperationState.Running;
      if (QmlWeb.useAnimationFrames) {
        const ticker = () => {
          this._tick();
          this._tickerId = window.requestAnimationFrame(ticker);
        };
        this._tickerId = window.requestAnimationFrame(ticker);
      } else {
        startInterval(this._tick.bind(this), this.$interval);
      }
      this._whenStart.forEach(callback => callback());
    }
  }

  // Stop the engine
  stop() {
    const QMLOperationState = QmlWeb.QMLOperationState;
    if (this.operationState === QMLOperationState.Running) {
      if (QmlWeb.useAnimationFrames) {
        window.cancelAnimationFrame(this._tickerId);
      } else {
        clearInterval(this._tickerId);
      }
      this.operationState = QMLOperationState.Idle;
      this._whenStop.forEach(callback => callback());
    }
  }

That would also allow to opt-out from using requestAnimationFrame for whatever reason.

Not tested.

@Gaubee
Copy link
Contributor Author

Gaubee commented Jan 15, 2017

@ChALkeR Very good advice!

@Gaubee
Copy link
Contributor Author

Gaubee commented Jan 15, 2017

@ChALkeR Now I try to work on optimize $updateImplicit.
The $updateImplicit function will be multiple calls in one frame. But I think it should only be called once in a frame. What do you think of this proposal?

If this proposal is feasible, then will need to have a FrameID parameter to mark it. This is also this pull-request original intention, in order to better performance optimization.


Or there is an optimal solution, is the use of virtual DOM. This scheme will be a lot of work, but the advantage is that there can be rendered to the canvas in the possibility. So that more effects can be achieved.

Signed-off-by: Gaubee <gaubeebangeel@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants