HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Making thousands of DOM elements draggable with JavaScript

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
elementswithdraggablejavascriptdomthousandsmaking

Problem

This is a very simple implementation of dragging elements in html/js. I'm working on a web application that could have thousands of draggable elements on screen at any given time.

Currently, this code works perfectly as shown below (with only one draggable element), however if I copy and paste that element (This is draggable) a few thousand times (I've been using around 4000 for testing) page load is significantly slower, and the framerate slows considerably.

I can understand the page load slowing due to the number of elements, but is there anything that can be done to ensure the frame rate remains smooth while dragging an element given large numbers of draggable elements in the DOM?

Note - The implementation here deliberately ignores various issues like scrolling and so on that I will be implementing later, and I believe will have a largely negligible effect on performance. If that's an incorrect assumption please let me know.

dragdrop.html


    
        Drag + Drop
        
    
    
        
            This is draggable
        
        
        
    


dragdrop.css

span {
    position:absolute;
    background: #FF8888;
    cursor: pointer;
}

.noselect {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}


dragdrop.js

```
var dragDrop = (function() {
var elementBeingDragged;
var clickPointOffsetX;
var clickPointOffsetY;

function _dragging(e) {
elementBeingDragged.style.left = (e.clientX - clickPointOffsetX) + "px";
elementBeingDragged.style.top = (e.clientY - clickPointOffsetY) + "px";
}

function _stopDrag(e) {
document.removeEventListener('mousemove', _dragging);
document.removeEventListener('mouseup', _stopDrag);
}

function startDrag(e) {
elementBeingDragged = this;
document.addEventListener('mouseup', _stopDrag);
document.a

Solution

Here are some suggestions to improve the fluidity of your app:

Use translate instead of top/left positioning

According to this blog post: https://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/, translate is much more efficient regarding the CPU usage

Use requestAnimationFrame

https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

This function allows you to do the computation only if required (see this SO answer on how to combine it with mousemove: https://stackoverflow.com/a/23658815/3207406)

Context

StackExchange Code Review Q#154259, answer score: 5

Revisions (0)

No revisions yet.