Improving animation performance on mobile devices using AngularJS

I've reached the final stages of developing a mobile application using AngularJS wrapped in a cordova webview. However, I'm encountering some issues with the panel transition animations.

After experiencing strange behavior with ngAnimate, I decided to utilize two divs that remain in the DOM permanently to encapsulate the current and next panel content I compile. To animate them, I turned to the GSAP Framework, known for its performance. Yet, the animations are still sluggish.

To troubleshoot, I conducted a frame-by-frame profiling using Chrome Dev Tools Timeline and discovered that my scripting time was excessively long during controller initialization.

As a solution, I have come up with two ideas: either find a way to detect when the controller initialization is complete (though unsure how in Angular) or devise a method to spread out the execution across multiple frames.

Could anyone provide guidance in this matter?

Below is the structure in index.html:

<!doctype html>
<html ng-app="SparterApp" lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
        <title>MyApp</title>
        <link rel="stylesheet" href="styles/styles.css">
    </head>
    <body>

        <div id="panelCtrl" ng-controller="panelCtrl">
            <nav id="menu" ng-include="'views/menu.html'"></nav>
            <section id="currentPanel"></section>
            <section id="nextPanel"></section>
        </div>
        <script src="bower_components/angular/angular.min.js"></script>
        <script src="scripts/TweenMax.min.js"></script>
        <!-- Various vendor scripts and custom Angular scripts -->
    </body>
</html>

Here is my panel controller code:

'use strict';

angular.module('SparterApp')
    .controller('panelCtrl', function ($scope, $compile, $http, $timeout, animService) {

        nextPanelHandler = $('#nextPanel');
        currentPanelHandler = $('#currentPanel');
        var protect = false;

        $scope.callbackNextPanel = function () {
            currentPanelHandler.hide();
            nextPanelHandler.attr('id', 'currentPanel');
            currentPanelHandler.attr('id', 'nextPanel');
            var buffer = nextPanelHandler;
            nextPanelHandler = currentPanelHandler;
            currentPanelHandler = buffer;
            protect = false;
        };



        /*
        **  Load the next panel in the 'section.nextPanel' element, compile it with angular, and execute the setted animation
        **
        **  templateUrl : the desired template url relative to the views folder or 'close' for closing popup
        **  options : an object with two attributes
        **      enterClass : the initialisation class for the next panel
        **      time : the time of the animation
        **  params : an object with all the arguments you want to transfer between panels
        */

        $scope.nextPanel = function (templateUrl, options, params) {
            // Prevent multi trigger
            if (!protect) {
                protect = true;
                var tl = new TimelineLite({
                    paused: true,
                    onComplete: $scope.callbackNextPanel
                });

                // Get a initialisation in a list
                var enterAnimFrom = animService.getAnimFrom(options.enterClass);
                enterAnimFrom.onComplete = nextPanelHandler.show;
                //Prepare the animation
                tl.fromTo(
                    nextPanelHandler,
                    options.time,
                    enterAnimFrom,
                    {
                        x: 0,
                        y: 0,
                        scale: 1,
                        rotation: 0,
                        opacity: 1,
                        ease: options.ease
                    },
                    'start'
                );
                // Get the template to compile
                var newPanel = $http({method: 'GET', url: 'views/' + templateUrl})
                .success(function(data, status, headers, config) {
                    nextPanelHandler.html(data);
                    $scope.params = params;
                    $compile(nextPanelHandler.contents())($scope);
                    // Play the animation
                    tl.play();
                })
                .error(function(data, status, headers, config) {
                    alert('An error occured with the next panel loading');
                });
            }
        };

    });

Lastly, here is the structure of a panel:

<div ng-controller="loginCtrl" class="panel">
    <!-- Panel content goes here -->
</div>

If sharing the timeline would aid in resolving the issue, please let me know.

Answer №1

Sharing some personal challenges encountered while trying to implement animations reliably. I've found that GSAP struggles with full-page animations on mobile devices, requiring various optimization attempts to improve performance. Despite its dominance in comparison to CSS animations, the rendering process seems to pose a challenge for GSAP. A related discussion can be found at . Currently, I rely on CSS3 transitions for my website but still utilize GSAP for smaller animation tasks rather than full-page transitions.

Transitioning between whole pages presents varying degrees of difficulty based on page size and transition type, especially on tablets and phones. In my experience, iOS devices outperform Android counterparts, with recent improvements noted in FireFox over the past 8 months.

One major advantage of GSAP is its consistent performance across different platforms, with minimal frame rate discrepancies. On the other hand, CSS3 lacks this universal compatibility and often leads to time-consuming troubleshooting efforts. In cases where cssTransitions are not supported, I have resorted to using JQuery.animate, although it may not be as aesthetically pleasing as CSS equivalents.

Additionally, there seem to be limitations related to caching strategies for optimizing graphics acceleration, particularly when transitioning from a long scrolling page to a shorter one. Despite these challenges, I anticipate improvements in the future as technologies evolve.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Displaying minute scale from right to left using jQuery technology

I successfully created a minute scale that is functioning well, but now I am encountering an issue with displaying my scale. Instead of being oriented left to right, I would like it to be displayed from right to left. Can anyone suggest what might be wron ...

I could use some direction on implementing csrf token security measures for API communication between AngularJs and Slim PHP

I am currently in the process of developing a mobile application using AngularJS for the frontend, SlimPHP as the API provider connecting to Mysql. The frontend and backend are hosted on separate domains. When a user submits the login form from Angular, ...

Encountering an issue when passing a response using coverage.js

I am utilizing coverage.js to showcase data. When I pass my variable containing the coverage response into an HTML file, similar to how it's done in Angular to display expressions, I encounter a syntax error: <div class="container" style="margin- ...

Having two custom directives within the same module is causing functionality issues

While working with a module called validationMod for form validation, I encountered an issue with two custom directives. Surprisingly, only the second directive was executing, displaying an alert for test2. However, upon removing the second directive, the ...

Ajax fails to transmit information

Currently, I am in the process of familiarizing myself with the usage of ajax. An issue that I am encountering is that clicking a submit button in a form does not effectively send data. Below you can find the JQuery code I am using: $('input[name=" ...

Increase the controller value through an Ajax call made in the URL

I've encountered a peculiar issue. When I run my Visual Studio and click on a specific button in the browser, an ajax function is triggered but displays an error. After some debugging, I discovered that the URL is causing the problem: POST http://l ...

What is the best way to apply a class to a button in Angular when clicking on

Creating a simple directive with two buttons. Able to detect click events on the buttons, but now looking to add a custom class upon clicking. There is a predefined class: .red { background-color: red; } The goal is to dynamically apply this class whe ...

Increase the worth of current value

Whenever a user enters their name into an input box, I want it to be shown after the word 'hello'. However, currently, the word 'hello' gets replaced by the user's name instead of being displayed after it. var name = document.ge ...

What is the best way to interact with Redis without using any external modules?

I am curious about the communication process between the node redis wrapper and the RESP (REdis Serialization Protocol) database. Here is a simple example: const redis = function(uri) { this.client = '' // How do we establish a connection wit ...

Issue with Material UI Autocomplete: onChange event not firing

When using Material UI's Autocomplete example, I am trying to choose an option using keyboard events: Navigate through options with the Up and Down arrow keys Press ENTER to select the desired option However, the onChange event is not being triggere ...

Animating changes on a webpage using CSS transitions in conjunction with the

Can the border color of a simple line div be changed from top to bottom using GreenSock? .line { position: relative; border: 1px solid #c3ced8; width: 0; height: 50px; display: block; content: ''; z-index: 1; top: -19px; marg ...

Obtaining data from an external ng-repeat element

My list contains items that are being repeated using ng-repeat details. I want to be able to hover over one of the li elements and have the background of a div called background (which is outside of the ng-repeat) change to the url of the corresponding d ...

Is it possible to modify parameter values while transitioning?

While transitioning, I need the ability to modify parameter values. After researching the documentation, I discovered a method called `params('to')` that allows accessing target state's parameters. This is how it looks in my code: $transiti ...

Using express and sequelize to load different models in a single route

In my express application, I have successfully loaded related bus, family, and person models to supply them separately to the view. Now, I am trying to load the volunteerTypes model and pass it as a separate object to the view. exports.get = (request, res ...

Unable to transfer bootstrap form data from the view to the controller due to issues with bootstrap validations

Scenario I have integrated a bootstrap form into my codeigniter application with bootstrap validation to ensure data accuracy. I want the submit button to work properly so that users can successfully submit the form and be redirected to the action page ...

Accessing a file located in a specific directory using the node fs module

Currently, I am attempting to access a file from my local system using the 'fs' module in node.js. However, I have encountered an issue where the 'fs' module does not seem to function properly when an absolute path is provided. Here is ...

Is there a way to make this AngularJS service wait until it has a value before returning it?

Multiple controllers call a service that loads data into an object named categories: .service('DataService', ['$http', '$q', function($http, $q) { var categories = {}; // Public API. return({ setCategory ...

What are the steps to implementing AJAX pagination without utilizing a database?

Is it possible to implement AJAX pagination without relying on MySQL? Can I create a PHP file containing the text and markup needed for display, and by clicking on page numbers, serve that content to the user? Can this be achieved using only jQuery and PHP ...

transfer the output from the second selection to the adjacent div

I am utilizing a library called select2 specifically for single choice scenarios. My goal is to transfer the selected option to a different div once it has been chosen. Here is the code I have so far: https://jsfiddle.net/hxe7wr65/ Is there a way to ach ...

Displaying information in ejs format

I am currently working on a project to develop a basic webpage that requires the user to input a specific time and then click on submit. Once submitted, I want the relevant data linked to that input to be displayed on the webpage. Upon clicking the submit ...