Enhancing webpage performance by updating CSS properties dynamically based on mouse movement using JavaScript

My jQuery function is changing the background-position property of three elements when the user moves their mouse, but it's causing some performance problems.

It's worth mentioning that the background images of these elements are SVGs.

Here's an example of the code:

$(window).on('mousemove', function(event) {
    window.requestAnimationFrame(function() {

        $banner.find('.pattern').each(function(key) {

            var modifier = 20 * (key + 1);

            $(this).css({
                'background-position': (event.pageX / modifier)+'px '+(event.pageY / modifier)+'px'
            });

        });

    });
});

You can view my working code here: https://codepen.io/thelevicole/project/full/DarVMY/

I am using window.requestAnimationFrame() and I have added the css attribute

will-change: background-position;
to each element.

However, this effect is causing lagging issues, especially on larger window sizes.

I suspect that the problem lies in using SVGs for the background images instead of PNGs. The reason behind using SVGs is the high pixel density screens.

If anyone has suggestions on how to improve the frames per second without resorting to PNGs, I would greatly appreciate it. Thank you.

Answer №1

My progress towards a solution has been a result of incorporating various suggestions.

While attempting to change the transform property of each element, I encountered another issue. The keyframe animation on those elements was being ignored when JavaScript styles were applied.

To resolve this, I nested the keyframe animation elements and utilized JS to transform the parent element.

I have integrated the advice from @CristianTraìna by moving window.requestAnimationFrame() outside of my mousemove function.

You can view the updated version at the original link: https://codepen.io/thelevicole/project/full/DarVMY/

Unfortunately, CodePen does not offer versioning for projects.


Final functioning code:

(function($) {
'use strict';

var $banner = $('section.interactive');
if ($banner.length) {
var $patterns = $banner.find('.pattern');

var x = 0,
y = 0;

// Bind animation to cursor
$(window).on('mousemove', function(event) {
x = event.pageX;
y = event.pageY;
});

/**
 * Request browser for animation performance
 * @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
 */
window.requestAnimationFrame(function animation() {

// Loop through each pattern layer
$patterns.each(function(key) {

// Modify the x,y coords per element to provide "depth"
var modifier = 20 * (key + 1);

// Move background position
$(this).css({
'transform': 'translate('+(x / modifier)+'px, '+(y / modifier)+'px)'
});

});

window.requestAnimationFrame(animation);

});
}

})(jQuery);
/* CSS Styles Here */ 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8>
<title>Animation Performance</title>
</head>
<body>
<section class="interactive">
<div class="layers">
<div class="pattern pattern-3">
<div class="inner"></div>
</div>
<div class="pattern pattern-2">
<div class="inner"></div>
</div>
<div class="pattern pattern-1">
<div class="inner"></div>
</div>
</div>
</section>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</body>
</html>

Answer №2

By utilizing the on method, you are creating a chain of asynchronous functions that respond to events. The initial function listens for an event and triggers another function to listen for subsequent events.

In this scenario, you're monitoring the mousemove event and triggering the requestAnimationFrame event upon detection. However, if multiple mousemove events occur rapidly before requestAnimationFrame executes its callback, it can lead to potential issues.

An effective solution to this issue involves optimizing the code structure:

var x = 0;
var y = 0;
$patterns = $banner.find('.pattern');
$(window).on('mousemove', function(event) {
  x = event.pageX;
  y = event.pageY;
});

window.requestAnimationFrame(function moveBackground() {
  $patterns.each(function(key) {
    var modifier = 20 * (key + 1);
    $(this).css({
      'background-position': (x / modifier)+'px '+(y / modifier)+'px'
    });
  });
  window.requestAnimationFrame(moveBackground);
});

To view a functioning example of this setup (excluding JQuery), feel free to access my project here

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

leveraging JQuery plugins alongside Grails resources plugin

How can I easily integrate a JQuery plugin like FancyBox into a Grails application using the resources plugin? The FancyBox plugin comes with .js, .css, and image files. It assumes that the image and .css files are located in the same directory. In some ...

ajax is providing identical data when called too frequently

Using my barcode scanner triggers the function below, but scanning multiple barcodes quickly results in duplicate data being processed. The issue seems to be related to the async setting - when it's false, the process slows down significantly. Is the ...

"Exploring the World of Button Coloration

I'm struggling with customizing the colors of each of the 4 buttons that link to different tables using CSS. I want to assign a specific color to each button, like red for the first one and blue for the second. Your assistance in this matter would be ...

What is the best way to create a brand new item using these characteristics?

Here is the object I'm working with: const sampleData = [ { main: 7, second: 2 otherData: 'some string' } ] I want to create a new object only containing specific properties, like this: const newDataObject = { 7: { ...

Incorporating a jQuery word count and limit within PHP code: a step-by-step guide

I am encountering an issue with a textarea count code. It functions perfectly on its own but when I integrate it as shown below, it stops working without throwing any errors. I have been trying to resolve this for more than 3 days now. Any assistance would ...

Stop the form from refreshing upon submission using an Ajax call in AngularJS

Currently, I am in the process of developing a search form that requires two inputs: Job title and Location. These keywords are used to gather data from various websites. However, upon submitting the form, the page refreshes itself. To prevent this, I have ...

I am in need of eliminating repetitive comments from each post

data structure can you help figure out what is causing the issue in this code that seems to be removing old comments? mutations:{ getPosts(state) { let unique = [...new Set(state.posts)]; for (let i = 0; i < uniq ...

Using html() to load dynamic data can cause the script to malfunction if the content being loaded contains special characters

Utilizing the html() function, I am retrieving dynamic data from the database and appending it to my HTML. Everything functions correctly, except when the dynamic data contains '>' or '<' tags as data. In this scenario, the script ...

Refresh in AJAX, automated loading for seamless transition to a different page

Having an issue with the page not auto-refreshing, although it loads when I manually refresh. P.S Loading the page onto another page. Below is my HTML and AJAX code along with its database: The Trigger Button <?php $data = mysqli_query ...

To center a div vertically within a Bootstrap 4.1 container-fluid > row > col, you can use the following method

I'm currently working on incorporating Bootstrap 4.1's align-middle into a col nested within a row. Despite my efforts, the content within is not aligning to the middle as expected. Take a look at my code below: <body class="d-flex"> < ...

Creating a dynamic route in Node Express allows for flexible path handling

Is there a way to incorporate a dynamic route or path using the Express package? The challenge is that the path is an ID passed by the client and we have no control over it. const express = require('express'); const dynamicPath = express(); dyn ...

Using JavaScript to retrieve data from a JSON file and showcase it on a jQuery mobile webpage

I am struggling to retrieve JSON data from a PHP URL using JavaScript and display it within a JQuery mobile "li" tag as a category list. Despite spending the last 8 hours on it, I can't seem to get it working using the code provided below. Any help wo ...

Highcharts stretching beyond parent container width in Chrome exclusive

On my webpage, I have multiple charts displayed in individual bordered boxes. However, upon the initial page load, all the charts exceed the width of their parent container. An interesting observation is that if I slightly resize the page, everything adju ...

Using JavaScript to we can transfer the function result to an HTML input field

Is there a way to display the result of a JavaScript function in an HTML input field? Here is an example form: https://i.sstatic.net/HHHl2.png When I click "Run - Script," the following simple script is executed: <button type="submit" class="btn btn ...

My SF2 app is experiencing issues with AngularJS integration

I am currently developing a straightforward API using Symfony2 and now I am experimenting with integrating AngularJS into my bundle to visualize the results of my API calls. How can I effectively implement AngularJS? I initiated a bundle via app/console ...

Guide to adding a label following an input field in a Formik (Input) form using React.js

I am looking to customize the label text for the Formik Input Component, specifically positioning it after the input field. However, I am unsure of how to target it and apply CSS styling. Here is a code snippet example: <div className="editable-jo ...

Client-side image upload problem in Next.js API routes

I've been banging my head against this bug for a couple of hours now and I just can't seem to figure out the reason behind it. The issue is with an API route I'm trying to set up in next.js where I need to modify an image and then upload it ...

What is the best way to prevent jest.mock from being hoisted and only use it in a single jest unit test?

My goal is to create a mock import that will be used only in one specific jest unit test, but I am encountering some challenges. Below is the mock that I want to be restricted to just one test: jest.mock("@components/components-chat-dialog", () ...

Access the information within the tags from a different page

I have multiple articles and blogs on one page that I want to display as a list of titles on another page under the heading "Check Out My Latest Blogs". My goal is to extract all the div elements with a specific class from a particular page and showcase t ...

Having trouble with SCSS styles not being applied after refactoring to SCSS modules?

Currently, I am in the process of restructuring an application to ensure that component styles are separated from global styles using CSS modules. However, I have come across an issue where the styles are not being applied correctly. The original code sni ...