1
\$\begingroup\$

I'm working on a jQuery plugin. The problem is that when I use it I can see a high CPU usage in task manager.

I think the problem is here:

$elementTSMask.on("mousemove", function(event){
    if(isMouseDown && isLeftButton){
    var toScroll;

        if(endPosition != 0){
            toScroll = scrolled + (event.pageY - startPosition);
        }else{
            toScroll = event.pageY - startPosition;
        }
        $elementToScroll.css("top", toScroll + "px");
    }
});

The toScroll variable is calculated every time the user moves the mouse, so the CSS property is continuous changing. What can I do?

(function($) {

	$.fn.dragToScroll = function(options) {

		if (!this.length) { return this; }

		var opts = $.extend(true, {}, $.fn.dragToScroll.defaults, options);

		var $elementToScroll;
		var $elementTSMask;

		var scrolled = 0;
		var maxScroll = 0;

		var startPosition = 0;
		var endPosition = 0;

		var isMouseDown = false;
		var isLeftButton = false;

		this.each(function() {
			var $this = $(this);
			
			$elementToScroll = $this.find('.element-to-scroll');
			$elementTSMask = $this.find('.element-ts-mask');
			maxScroll = parseInt($elementToScroll.height(),10) - parseInt($elementTSMask.height(),10);
			console.log(maxScroll);

			$elementTSMask.on("mousedown", function(event){
				isMouseDown = true;
				startPosition = event.pageY;

				if(event.which == 1){
					isLeftButton = true;
				}else{
					isLeftButton = false;
				}

			});

			$elementTSMask.on("mousemove", function(event){
				if(isMouseDown && isLeftButton){
					var toScroll;

					if(endPosition != 0){
						toScroll = scrolled + (event.pageY - startPosition);
					}else{
						toScroll = event.pageY - startPosition;
					}
					$elementToScroll.css("top", toScroll + "px");
				}
			});

			$elementTSMask.on("mouseup mouseleave", function(event){
				console.log(scrolled);
				endPosition = event.pageY;

				scrolled += endPosition - startPosition;
				isMouseDown = false;
				isLeftButton = false;

				if(scrolled > 0 && Math.abs(scrolled) < maxScroll){
					$elementToScroll.animate({"top": "0px"}, function(){
						scrolled = 0;
					});
				}else if(Math.abs(scrolled) >= maxScroll){
					$elementToScroll.animate({"top": "-" + maxScroll + "px"}, function(){
						scrolled = -maxScroll;
					});
				}

			});


			var mousedownTimeout, startP = 0, endP = 1;
			$this.on({
				mousemove: function(event){
					endP = event.pageY;
					clearTimeout(mousedownTimeout);
				}, mousedown: function(event){
					if(event.which == 1){
						startP = event.pageY;
						mousedownTimeout = setTimeout(function() {
							if(endP == startP){
								$elementTSMask.fadeIn();
							}
						}, 400);
					}
				}, mouseleave: function(event){
					clearTimeout(mousedownTimeout);
					$elementTSMask.fadeOut();
				}
			});

		});
return this;
};

$.fn.dragToScroll.defaults = {
	defaultOne: true,
	defaultTwo: false,
	defaultThree: 'yay!'
};

})(jQuery);
*{
	margin:0;
	padding:0;
}
html,body {
	height: 100%;

}
#container{
	width:400px;
	height:100%;
	position:relative;
	display: block;
	left:0;
	background-color:black;
	overflow: hidden;
}

.element-to-scroll{
	width:100%;
	height:800px;
	position:relative;
	display: block;
	background: green;
}

.element-ts-mask{
	position: absolute;
	top:0;
	left:0;
	width:100%;
	height:100%;
	display: none;
	background:rgba(255,0,0,0.3);
	cursor:all-scroll;
}
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" type="text/css" href="style.css">
	<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
	<script type="text/javascript" src="dragToScroll.js"></script>
	<script type="text/javascript">
		jQuery(document).ready(function($) {
			$('.gesture-scroll').dragToScroll();
		});
	</script>
</head>
<body>
	<div id="container" class="gesture-scroll">
		<div class="element-to-scroll" style="z-index:1;">
			<div style="background:yellow;position:absolute;bottom:0;left:0;">
			Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto ullam minima, veniam, maiores molestiae assumenda pariatur corrupti voluptatum id ea commodi aperiam dignissimos fuga, exercitationem illo eius praesentium suscipit. Velit.	
			</div>			
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
			</p>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
			</p>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
			</p>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
			</p>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
			</p>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
			</p>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
			</p>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quis, asperiores doloribus cum laudantium voluptatum, ullam dicta tempora nulla culpa, placeat et nobis voluptatem harum ipsa est. Deserunt dolor, consequuntur ut!
			</p>
		</div>
		<div class="element-ts-mask" style="z-index:2;"></div>
	</div>
</body>
</html>

Note: What you need to do is to press the mouse button for about 1 second and then you will see some red over the green area. After that you need to release the mouse button and then you should see that the cursor changed. Now you can drag the content by holding the mouse button over the green area.

\$\endgroup\$
  • \$\begingroup\$ I tried to reproduce it by following the steps in your note when running the code snippet. I haven't noticed any high CPU usage whatsoever and I don't think your code is working as it should? \$\endgroup\$ – Kid Diamond Sep 15 '14 at 8:56
  • \$\begingroup\$ Check edited question. Can you see the effect now ? \$\endgroup\$ – TGeorge Sep 15 '14 at 9:11
  • 1
    \$\begingroup\$ Yes, I do. My Chrome browser's CPU usage goes up with about 5% when I drag the content back and forth continuously real fast. It's probably only a real issue with old computers that aren't so powerful. \$\endgroup\$ – Kid Diamond Sep 15 '14 at 9:18
  • \$\begingroup\$ What about smartphones ? \$\endgroup\$ – TGeorge Sep 15 '14 at 14:33
  • \$\begingroup\$ Uncaught ReferenceError: myTimeout is not defined in your snippet.. \$\endgroup\$ – konijn Sep 15 '14 at 14:44
1
\$\begingroup\$

A short review,

  • Attaching handlers to mousemove will spike the CPU load, even if you do nothing in those handlers

  • NAME YOUR FUNCTIONS!@!!

    function(event){
    

    should be

    function dragScollerMouseMove(event){
    

Otherwise people who want to profile your code (P.S. if you have CPU and other performance problems, you should use the Chrome Developer Tools to profile) will see a bunch of anonymous functions and feel miffed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.