Loading ...
Sorry, an error occurred while loading the content.

2365Re: [ydn-javascript] research: why YUI dragdrop is so slow

Expand Messages
  • Scott Schiller
    Jun 17, 2006
      Regarding this demo:
       
      One interesting thing to note here is that if while dragging, you move your mouse around quickly enough (IE and Firefox on my machine,) the dragged element will "lag" behind the mouse cursor and therefore will not be directly underneath the cursor. At this point, a mouseover can fire on the drag target since the cursor's "view" of the elements underneath is unobstructed.
       
      The "donut" idea (moving a few proxy elements around the mouse, containing containing dragged items and leaving a "hole" under the cursor) sounds feasible, particularly if just the proxy element(s) can be repositioned to effectively move all items being dragged as this is likely more efficient (ie. the dragged items are children of the donut element(s), which are being moved around rather than explicitly moving all items individually.)
       
      Again due to "lag," it's possible that elements may fall behind the mouse cursor while moving depending on CPU load etc., effectively "blocking" mouse events if they are sitting underneath the cursor. I suspect this is something that may be difficult to minimize, but the chance of failure should be relatively low. (ie., it's possible a user might drag to a target very quickly and the "lag" works out such that the mouse was always blocked by an element while moving, thus a mouseover may not fire on the target even though the mouse may be hovering over it by the time the drag is finished.)
       
      Earlier prototypes of some drag-and-drop stuff I was working on arranged items in a circle around the mouse cursor while moving, which allowed for native mouseover/out events to fire on elements as the drag was in progress. It was a bit different visually, and all dragged elements' positions were being updated individually, likely not as efficient as moving a single proxy which contained said elements, but native over/out events did fire.
       
      I think this has the potential to be much more efficient than doing coordinate checks (even with caching ie., calculate and store positions/sizes onmousedown, then reference for the duration of mousemove until mouseup), given that the browser is designed to handle mouse events. Even though looping through an array of numeric values and doing <=, >= comparisons etc. for "collision detection" should be quite fast, of course "less" is always better. ;)
      Pardon the short essay. ;) For reference, I work on the new Yahoo! Photos project, and due to the nature of this project I am interested in discussing efficiency, overall performance and so on relating to drag-and-drop and other client-side, javascript-driven features.
       
       
      - Scott
       
       
      ----- Original Message ----
      From: Peter Michaux <petermichaux@...>
      To: ydn-javascript@yahoogroups.com
      Sent: Friday, June 16, 2006 8:32:21 PM
      Subject: Re: [ydn-javascript] research: why YUI dragdrop is so slow

      Hi Tim,

      On 6/16/06, Tim Hosking <tim@...> wrote:
      >
      > Oh. I thought I did. Anyway. The draggable items represent virtual
      >  files retrieved from a mysql query. The user will (hopefully) be able
      >  to select any number of these items and move them between lists.
      >  Rather like moving files on your desktop. In a recent test I created
      >  1000 items in a list (OK, rendering that many items onto the browser
      >  window could be considered DOM abuse :-) When they eventually
      >  appeared, I was able to drag them smoothly in FireFox and Safari, but
      >  the initial delay in the mousedown gave me tennis elbow. I am in the
      >  early stages of writing a class to display the items in columns, thus
      >  greatly reducing the number of items, displayed, but with my test
      >  data I would still get over 200 items in one column.

      What I was trying to get at is why do you have to cache 1000 element
      locations and/or regions. You only need to cache the items you will
      drag and their possible targets. Could you somehow rework the problem
      so this is just a few things at the start of each drag?

      >  I read you article about optimising dragging with the donut method,
      >  and was impressed with it's speed, especially the light show effect
      >  when you drag the target over the top edge of the lower of the two
      >  grouped drop areas :-) (yes, I know it's because you offset the
      >  location of those items when you highlight them). My code uses a
      >  translucent clone of the dragged item as the proxy element, so I'm
      >  not sure how we would go about punching a mouse hole in it.

      This would require creative CSS. I haven't tried this yet but maybe
      you could use the clipping and/or overflow control features of CSS.
      Put some of the things you want to clone in each of the four donut
      divs and then when the donut is assembled things would look normal
      with a one or more pixel hole in the middle. That is my idea anyway.

      >  Correct me if I'm wrong, but I thought you were saying that with YUI
      >  don't see mouseover events for the drop targets because the dragged
      >  item is frontmost and always under the mouse. I checked this with
      >  FireBug, and it does generate mouseover events for the correct items.
      >  Am I missing something here?

      Maybe I'm missing something. I haven't ever used firebug. Here is an
      example that shows that the mouseover event does not fire while
      dragging an element under the cursor.

      http://peter.michaux.ca/examples/donut-dragdrop/event-test.html

      That example convinces me that the mouseover doesn't fire.


      >  My problem is not with the performance of the drag, but the delay in
      >  the mousedown handler at the start of the drag. The refreshCache()
      >  function traverses the DOM tree many times looking for draggable
      >  elements.

      The dragdrop library always holds the id's of all draggable elements.
      refreshCache should not have to look for these items.

      refreshCache calls getLocation which calls getEl. If you haven't
      called getEl for each draggable yet then maybe that is taking some
      time: all the document.getElementById() calls. You could do this after
      each draggable instance is created. As part of your Draggable subclass
      constructor. I think Draggable's constructor should do this anyway.
      Probably the getXY call in getLocation is the really slow problem. If
      you know the geography of your list items (height etc) perhaps you
      could do getXY for the first element and then just increment these
      values for the others in the list.


      Peter


      ------------------------ Yahoo! Groups Sponsor --------------------~-->
      Yahoo! Groups gets a make over. See the new email design.
      http://us.click.yahoo.com/XISQkA/lOaOAA/yQLSAA/edFolB/TM
      --------------------------------------------------------------------~->


      Yahoo! Groups Links

      <*> To visit your group on the web, go to:
          http://groups.yahoo.com/group/ydn-javascript/

      <*> To unsubscribe from this group, send an email to:
          ydn-javascript-unsubscribe@yahoogroups.com

      <*> Your use of Yahoo! Groups is subject to:
          http://docs.yahoo.com/info/terms/

    • Show all 15 messages in this topic