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

research: why YUI dragdrop is so slow

Expand Messages
  • Peter Michaux
    Hi, I spent some time trying to pin down exactly why the Yahoo! UI dragdrop library is so slow for me during the drag. I think it is the use of
    Message 1 of 15 , Jun 16, 2006
    • 0 Attachment
      Hi,

      I spent some time trying to pin down exactly why the Yahoo! UI
      dragdrop library is so slow for me during the drag. I think it is the
      use of YAHOO.util.Dom.setXY().

      If you have a slow computer (or fast) I am interested in your
      experience with the two examples I posted as part of my blog article.

      http://peter.michaux.ca/articles/2006/06/16/yui-dragdrop-v0_10-performance

      Peter
    • Adam Moore
      ... Peter, thanks for drilling into this. Originally drag and drop did not rely on setXY, but was later updated to use it in order to benefit from the
      Message 2 of 15 , Jun 16, 2006
      • 0 Attachment
        On Fri, Jun 16, 2006 at 08:06:24AM -0700, Peter Michaux wrote:
        > Hi,
        >
        > I spent some time trying to pin down exactly why the Yahoo! UI
        > dragdrop library is so slow for me during the drag. I think it is the
        > use of YAHOO.util.Dom.setXY().

        Peter, thanks for drilling into this. Originally drag and drop did not rely
        on setXY, but was later updated to use it in order to benefit from the
        accuracy it provides. While setXY can't be replaced, we should be able to
        improve the performance by caching the initial position produced by setXY and
        using that value to set the position directly during the drag. I am
        investigating incorporating this change for the 0.11 release.

        -Adam
      • Tim Hosking
        Hrrmmmm, ahem. cough. Any more thoughts about speeding up the caching? :-) -- Munger ... Munger
        Message 3 of 15 , Jun 16, 2006
        • 0 Attachment
          Hrrmmmm, ahem. cough. Any more thoughts about speeding up the
          caching? :-)

          --
          Munger

          On 16 Jun 2006, at 21:30, Adam Moore wrote:

          > On Fri, Jun 16, 2006 at 08:06:24AM -0700, Peter Michaux wrote:
          >> Hi,
          >>
          >> I spent some time trying to pin down exactly why the Yahoo! UI
          >> dragdrop library is so slow for me during the drag. I think it is the
          >> use of YAHOO.util.Dom.setXY().
          >
          > Peter, thanks for drilling into this. Originally drag and drop did
          > not rely
          > on setXY, but was later updated to use it in order to benefit from the
          > accuracy it provides. While setXY can't be replaced, we should be
          > able to
          > improve the performance by caching the initial position produced by
          > setXY and
          > using that value to set the position directly during the drag. I am
          > investigating incorporating this change for the 0.11 release.
          >
          > -Adam
          >
          >
          > ------------------------ Yahoo! Groups Sponsor --------------------
          > ~-->
          > See what's inside the new Yahoo! Groups email.
          > http://us.click.yahoo.com/2pRQfA/bOaOAA/yQLSAA/edFolB/TM
          > --------------------------------------------------------------------
          > ~->
          >
          >
          > Yahoo! Groups Links
          >
          >
          >
          >
          >
          >
          >
          >

          Munger
        • Peter Michaux
          ... Adam, I like your solution idea. I tried it and it works fine except I get a gnarly flicker in Safari and Firefox when I setXY in the mousedown handler. In
          Message 4 of 15 , Jun 16, 2006
          • 0 Attachment
            On 6/16/06, Adam Moore <adamoore@...> wrote:
            >
            > On Fri, Jun 16, 2006 at 08:06:24AM -0700, Peter Michaux wrote:
            > > Hi,
            > >
            > > I spent some time trying to pin down exactly why the Yahoo! UI
            > > dragdrop library is so slow for me during the drag. I think it is the
            > > use of YAHOO.util.Dom.setXY().
            >
            >
            > Peter, thanks for drilling into this. Originally drag and drop did not rely
            > on setXY, but was later updated to use it in order to benefit from the
            > accuracy it provides. While setXY can't be replaced, we should be able to
            > improve the performance by caching the initial position produced by setXY and
            > using that value to set the position directly during the drag. I am
            > investigating incorporating this change for the 0.11 release.

            Adam, I like your solution idea. I tried it and it works fine except I
            get a gnarly flicker in Safari and Firefox when I setXY in the
            mousedown handler. In the handler I've tried the following. The Dom
            line causes the flicker.

            this.initialPageX = YAHOO.util.Event.getPageX(event);
            this.initialPageY = YAHOO.util.Event.getPageY(event);

            YAHOO.util.Dom.setXY(this.element, YAHOO.util.Dom.getXY(this.element));

            this.initialLeft = parseInt(this.element.style.left.split("px", 1), 10);
            this.initialTop = parseInt(this.element.style.top.split("px", 1), 10);


            Here is the new example

            http://peter.michaux.ca/examples/yui-dragdrop-v0_10-performance/with-setXY-new.html

            Peter
          • Peter Michaux
            ... Tim, You never did respond about why you have so many targets. Did you see that email I wrote? Peter
            Message 5 of 15 , Jun 16, 2006
            • 0 Attachment
              On 6/16/06, Tim Hosking <tim@...> wrote:
              >
              > Hrrmmmm, ahem. cough. Any more thoughts about speeding up the
              > caching? :-)

              Tim,

              You never did respond about why you have so many targets. Did you see
              that email I wrote?

              Peter
            • Tim Hosking
              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
              Message 6 of 15 , Jun 16, 2006
              • 0 Attachment
                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.

                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.

                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?

                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. In some cases, I think it may be faster if we had a
                function to find DOM nodes given a specific root node as a starting
                point, but whether that could beat the browser's built-in
                getElementById() is debatable.



                On 16 Jun 2006, at 23:54, Peter Michaux wrote:

                > On 6/16/06, Tim Hosking <tim@...> wrote:
                >>
                >> Hrrmmmm, ahem. cough. Any more thoughts about speeding up the
                >> caching? :-)
                >
                > Tim,
                >
                > You never did respond about why you have so many targets. Did you see
                > that email I wrote?
                >
                > 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
                >
                >
                >
                >
                >
                >
                >
                >

                Munger
              • Peter Michaux
                Hi Tim, ... 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
                Message 7 of 15 , Jun 16, 2006
                • 0 Attachment
                  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
                • Tim Hosking
                  ... Because there may be 1000 draggable items. I m not doing the caching, YUI is. ... The only problem I can see with this is that you would have to make the
                  Message 8 of 15 , Jun 17, 2006
                  • 0 Attachment
                    On 17 Jun 2006, at 04:32, Peter Michaux wrote:

                    > Hi Tim,
                    >
                    > 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?

                    Because there may be 1000 draggable items. I'm not doing the caching,
                    YUI is.

                    > 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.

                    The only problem I can see with this is that you would have to make
                    the dragged object jump shift at the start off the drag to align the
                    hole with the mouse cursor. This may not look so bad with a small,
                    squarish object, but with a long, narrow object, like a line of
                    textual data, the jump could be significant, and make it look really
                    jerky.

                    > Maybe I'm missing something. I haven't ever used firebug.

                    Oh you really should. It's free (maybe because it's priceless)

                    > 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.

                    Interesting. I notice you use YAHOO.util.DD. I just changed my code
                    to use it, and as you say, I don't see mouseover events. I have been
                    using YAHOO.util.DragProxy, and guess what. Yep, it *does* generate
                    the mouseover events .... try it. Obviously DD & DragProxy are doing
                    things differently, one of which is not good. Here's a suggestion.

                    Create a subclass of YAHOO.util.DragProxy and override startDrag() to
                    do something like this:-

                    var proxy = this.getDragEl();
                    var len = proxy.childNodes.length;

                    for(var i = 0; i < len; i++) {
                    proxy.removeChild( proxy.childNodes[ i ] );
                    }

                    var element = this.getEl().cloneNode( true );
                    proxy.style.border = "";
                    proxy.style.borderStyle = "none";
                    proxy.appendChild( element );

                    Also, if you wish, hide you original element and show it again on
                    mouseup. This should give you solid dragging (or translucent if you
                    add a style to the proxy element), and mouseover events.


                    > 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

                    Aha! That actually worked! Thank you! What a stupid problem :-)

                    > Peter

                    Tim
                  • Peter Michaux
                    Hi Tim, ... Are all 1000 draggables targets? You have set isTarget = false? If YUI dragdrop is caching non-target draggables i think that needs to be changed.
                    Message 9 of 15 , Jun 17, 2006
                    • 0 Attachment
                      Hi Tim,

                      On 6/17/06, Tim Hosking <tim@...> wrote:
                      > > 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?
                      >
                      > Because there may be 1000 draggable items. I'm not doing the caching,
                      > YUI is.

                      Are all 1000 draggables targets? You have set isTarget = false? If YUI
                      dragdrop is caching non-target draggables i think that needs to be
                      changed. It is unnecessary. You could always override some method in
                      the library and submit a patch.


                      > > 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.
                      >
                      >
                      > The only problem I can see with this is that you would have to make
                      > the dragged object jump shift at the start off the drag to align the
                      > hole with the mouse cursor. This may not look so bad with a small,
                      > squarish object, but with a long, narrow object, like a line of
                      > textual data, the jump could be significant, and make it look really
                      > jerky.

                      There is no need for the jump shift. The hole does not have to be
                      centered in the donut. It can be close to one corner if that is where
                      you mousedowned on the original element. This is a be-creative
                      situation. Only the whole has to be under the cursor. Otherwise the
                      donut proxy can look like anything.


                      > > 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.
                      >
                      >
                      > Interesting. I notice you use YAHOO.util.DD. I just changed my code
                      > to use it, and as you say, I don't see mouseover events. I have been
                      > using YAHOO.util.DragProxy, and guess what. Yep, it *does* generate
                      > the mouseover events .... try it.

                      It doesn't for me

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


                      > Obviously DD & DragProxy are doing
                      > things differently,

                      They are both dragging an element under the cursor. That is the
                      similarity for detecting events.


                      > one of which is not good. Here's a suggestion.
                      >
                      > Create a subclass of YAHOO.util.DragProxy and override startDrag() to
                      > do something like this:-
                      >
                      > var proxy = this.getDragEl();
                      > var len = proxy.childNodes.length;
                      >
                      > for(var i = 0; i < len; i++) {
                      > proxy.removeChild( proxy.childNodes[ i ] );
                      > }
                      >
                      > var element = this.getEl().cloneNode( true );
                      > proxy.style.border = "";
                      > proxy.style.borderStyle = "none";
                      > proxy.appendChild( element );
                      >

                      This still doesn't work for me

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

                      Can you post a complete HTML document that shows this working in a
                      compact example?


                      > > 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
                      >
                      >
                      > Aha! That actually worked! Thank you! What a stupid problem :-)

                      I'm glad it worked.

                      This is more evidence to me that since dragdrop was not an intended
                      feature in browsers that we have to be very creative to make it work
                      well in difficult situations. This includes situations with many
                      targets or overlapping or nested targets.

                      Peter
                    • Scott Schiller
                      Regarding this demo: http://peter.michaux.ca/examples/donut-dragdrop/event-test.html One interesting thing to note here is that if while dragging, you move
                      Message 10 of 15 , Jun 17, 2006
                      • 0 Attachment
                        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/

                      • Peter Michaux
                        Hi Scott, ... These accidental fire s that occur when the dragged item lags behind is exactly how I discovered the donut idea. In my first few days with
                        Message 11 of 15 , Jun 17, 2006
                        • 0 Attachment
                          Hi Scott,

                          On 6/17/06, Scott Schiller <idliketowork@...> wrote:
                          >
                          > Regarding this demo:
                          > http://peter.michaux.ca/examples/donut-dragdrop/event-test.html
                          >
                          > 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.

                          These accidental fire's that occur when the dragged item lags behind
                          is exactly how I discovered the donut idea. In my first few days with
                          dragdrop I just assumed that even if the dragged item was under the
                          cursor that target mouseovers would still fire.


                          > 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.)

                          Yes the donut proxy can still lag behind but when it catches up the
                          hole will be under the cursor and the native browser events will fire.
                          Only very small holes make this a big problem. If the user can
                          tolerate a 10x10px hole things work relatively smoothly.


                          > 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 knew this wasn't completely new:) The donut method would likely
                          require JavaScript repositioning of four divs for most
                          implementations. The remainder of elements inside these divs would be
                          repositioned by the browser which must be faster than JavaScript doing
                          the work.


                          > 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.

                          The boring outline donut is the simplest and fastest. I think the next
                          fastest would be a single image drag. It would be very easy to
                          position a single image inside the donut's four divs to make a nice
                          punctured image proxy.

                          Peter
                        • Scott Schiller
                          This is more generic and not implementation-specific, but I think it s an interesting topic, and I d be interested in hearing of any others
                          Message 12 of 15 , Jun 19, 2006
                          • 0 Attachment
                            This is more generic and not implementation-specific, but I think it's an interesting topic, and I'd be interested in hearing of any others' findings/experience in the area.
                             
                            From some of the more recent work I've done, I've seen some pretty interesting correlations between javascript animation performance (render speed / frame rate / CPU use) and graphics cards on the PC with Firefox in particular.
                            IE appears to be able to take advantage of ActiveX and/or rendering hardware acceleration which results in lower CPU use and higher frame rates when doing javascript animation, even on older computers or graphics cards. In my particular cases, I'm animating multiple elements at the same time and also applying both PNG and CSS-based opacity effects.
                             
                            Firefox does not perform as well as IE nicely on a computer with an older or onboard graphics card (CPU use is higher / frame rate is lower,) but I've noticed it can be as fast as IE when using a newer, slightly higher-performance graphics card on machines with even slower CPUs.
                             
                            I'm not exactly sure how it all works, but it would make logical sense that the graphics card handles rendering and redraw of elements where possible (particularly transparency/opacity effects,) and where hardware acceleration is not possible on the graphics card itself, the work is offloaded to the CPU - presumably much less efficient - and therefore slower.
                             
                            From what I've seen, onboard/"integrated" graphics cards on typical desktop set-ups such as the Intel 82865G don't perform very well in this regard, so animation in Firefox is slower / requires more CPU in these cases.
                             
                            On my computer at work (A 2.8 GHz P4 with onboard Intel 82865G graphics), IE has no problems with JS animation for most cases; Firefox doing the same work however is noticeably slower. I have seen several 1.6 GHz laptops with nicer graphics cards, which ran the same JS effects smoothly also in Firefox despite having much slower CPUs (eg. a 1.6 GHz with non-onboard graphics runs faster than a 2.8 GHz with onboard, in Firefox.) This seems to be indicative of some video or other hardware acceleration going on.
                             
                            It should be noted that I can run the same effects quite smoothly on an old 866-MHz Pentium III with IE, and again Firefox is slower (also, this system has an old/integrated graphics card - I would imagine with a faster card, I would see similar performance gains.) Several years ago, my old Celeron 433 with onboard graphics would run a Javascript version of "Arkanoid" perfectly smoothly in IE, but Firefox would run slower.
                             
                            Unfortunately most common desktops may not have graphics cards that would enable this kind of performance gain under Firefox; at this point I'm not exactly sure what, if any, hardware feature makes this all happen.
                             
                            For what it's worth, I've spent a fair bit of time playing around with animation and performance experiments on previous personal projects, some more general findings are noted on my site.
                             
                             
                            - Scott

                             
                            ----- Original Message ----
                            From: Peter Michaux <petermichaux@...>
                            To: ydn-javascript@yahoogroups.com
                            Sent: Saturday, June 17, 2006 12:19:35 PM
                            Subject: Re: [ydn-javascript] research: why YUI dragdrop is so slow

                            Hi Scott,

                            On 6/17/06, Scott Schiller <idliketowork@...> wrote:
                            >
                            > Regarding this demo:
                            > http://peter.michaux.ca/examples/donut-dragdrop/event-test.html
                            >
                            > 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.

                            These accidental fire's that occur when the dragged item lags behind
                            is exactly how I discovered the donut idea. In my first few days with
                            dragdrop I just assumed that even if the dragged item was under the
                            cursor that target mouseovers would still fire.


                            > 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.)

                            Yes the donut proxy can still lag behind but when it catches up the
                            hole will be under the cursor and the native browser events will fire.
                            Only very small holes make this a big problem. If the user can
                            tolerate a 10x10px hole things work relatively smoothly.


                            > 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 knew this wasn't completely new:) The donut method would likely
                            require JavaScript repositioning of four divs for most
                            implementations. The remainder of elements inside these divs would be
                            repositioned by the browser which must be faster than JavaScript doing
                            the work.


                            > 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.

                            The boring outline donut is the simplest and fastest. I think the next
                            fastest would be a single image drag. It would be very easy to
                            position a single image inside the donut's four divs to make a nice
                            punctured image proxy.

                            Peter


                            ------------------------ Yahoo! Groups Sponsor --------------------~-->
                            Great things are happening at Yahoo! Groups.  See the new email design.
                            http://us.click.yahoo.com/TISQkA/hOaOAA/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/

                          • Peter Michaux
                            Hi Scott, The dragdrop perfomance I experience with Yahoo! UI dragdrop v0.10 is much worse in Firefox 1.5 than Safari 1.3 on my Mac. Perhaps since IE and
                            Message 13 of 15 , Jun 19, 2006
                            • 0 Attachment
                              Hi Scott,

                              The dragdrop perfomance I experience with Yahoo! UI dragdrop v0.10 is
                              much worse in Firefox 1.5 than Safari 1.3 on my Mac.

                              Perhaps since IE and Safari are designed to run on only one platform,
                              there isn't the need for a platform independent layer between the
                              browser and the OS like Firefox might need to run on so many different
                              platforms. I don't know about browser internals. Just a guess.

                              Peter


                              On 6/19/06, Scott Schiller <idliketowork@...> wrote:
                              >
                              > This is more generic and not implementation-specific, but I think it's an interesting topic, and I'd be interested in hearing of any others' findings/experience in the area.
                              >
                              > From some of the more recent work I've done, I've seen some pretty interesting correlations between javascript animation performance (render speed / frame rate / CPU use) and graphics cards on the PC with Firefox in particular.
                              >
                              > IE appears to be able to take advantage of ActiveX and/or rendering hardware acceleration which results in lower CPU use and higher frame rates when doing javascript animation, even on older computers or graphics cards. In my particular cases, I'm animating multiple elements at the same time and also applying both PNG and CSS-based opacity effects.
                              >
                              > Firefox does not perform as well as IE nicely on a computer with an older or onboard graphics card (CPU use is higher / frame rate is lower,) but I've noticed it can be as fast as IE when using a newer, slightly higher-performance graphics card on machines with even slower CPUs.
                              >
                              > I'm not exactly sure how it all works, but it would make logical sense that the graphics card handles rendering and redraw of elements where possible (particularly transparency/opacity effects,) and where hardware acceleration is not possible on the graphics card itself, the work is offloaded to the CPU - presumably much less efficient - and therefore slower.
                              >
                              > From what I've seen, onboard/"integrated" graphics cards on typical desktop set-ups such as the Intel 82865G don't perform very well in this regard, so animation in Firefox is slower / requires more CPU in these cases.
                              >
                              > On my computer at work (A 2.8 GHz P4 with onboard Intel 82865G graphics), IE has no problems with JS animation for most cases; Firefox doing the same work however is noticeably slower. I have seen several 1.6 GHz laptops with nicer graphics cards, which ran the same JS effects smoothly also in Firefox despite having much slower CPUs (eg. a 1.6 GHz with non-onboard graphics runs faster than a 2.8 GHz with onboard, in Firefox.) This seems to be indicative of some video or other hardware acceleration going on.
                              >
                              > It should be noted that I can run the same effects quite smoothly on an old 866-MHz Pentium III with IE, and again Firefox is slower (also, this system has an old/integrated graphics card - I would imagine with a faster card, I would see similar performance gains.) Several years ago, my old Celeron 433 with onboard graphics would run a Javascript version of "Arkanoid" perfectly smoothly in IE, but Firefox would run slower.
                              >
                              > Unfortunately most common desktops may not have graphics cards that would enable this kind of performance gain under Firefox; at this point I'm not exactly sure what, if any, hardware feature makes this all happen.
                              >
                              > For what it's worth, I've spent a fair bit of time playing around with animation and performance experiments on previous personal projects, some more general findings are noted on my site.
                              > http://www.schillmania.com/content/projects/javascript-animation-2/
                              >
                              >
                              > - Scott
                            • Peter Michaux
                              Adam, Any luck with this? Thanks, Peter
                              Message 14 of 15 , Jun 19, 2006
                              • 0 Attachment
                                Adam,

                                Any luck with this?

                                Thanks,
                                Peter

                                On 6/16/06, Peter Michaux <petermichaux@...> wrote:
                                > On 6/16/06, Adam Moore <adamoore@...> wrote:
                                > >
                                > > On Fri, Jun 16, 2006 at 08:06:24AM -0700, Peter Michaux wrote:
                                > > > Hi,
                                > > >
                                > > > I spent some time trying to pin down exactly why the Yahoo! UI
                                > > > dragdrop library is so slow for me during the drag. I think it is the
                                > > > use of YAHOO.util.Dom.setXY().
                                > >
                                > >
                                > > Peter, thanks for drilling into this. Originally drag and drop did not rely
                                > > on setXY, but was later updated to use it in order to benefit from the
                                > > accuracy it provides. While setXY can't be replaced, we should be able to
                                > > improve the performance by caching the initial position produced by setXY and
                                > > using that value to set the position directly during the drag. I am
                                > > investigating incorporating this change for the 0.11 release.
                                >
                                > Adam, I like your solution idea. I tried it and it works fine except I
                                > get a gnarly flicker in Safari and Firefox when I setXY in the
                                > mousedown handler. In the handler I've tried the following. The Dom
                                > line causes the flicker.
                                >
                                > this.initialPageX = YAHOO.util.Event.getPageX(event);
                                > this.initialPageY = YAHOO.util.Event.getPageY(event);
                                >
                                > YAHOO.util.Dom.setXY(this.element, YAHOO.util.Dom.getXY(this.element));
                                >
                                > this.initialLeft = parseInt(this.element.style.left.split("px", 1), 10);
                                > this.initialTop = parseInt(this.element.style.top.split("px", 1), 10);
                                >
                                >
                                > Here is the new example
                                >
                                > http://peter.michaux.ca/examples/yui-dragdrop-v0_10-performance/with-setXY-new.html
                                >
                                > Peter
                                >
                              • Philip Tellis
                                ... firefox on FreeBSD is terrible when it comes to opacity. The larger the size of a semi transparent div, the slower the box gets (yes, not just the
                                Message 15 of 15 , Jul 3, 2006
                                • 0 Attachment
                                  Sometime on Jun 19, SS cobbled together some glyphs to say:

                                  > From some of the more recent work I've done, I've seen some pretty
                                  > interesting correlations between javascript animation performance
                                  > (render speed / frame rate / CPU use) and graphics cards on the PC
                                  > with Firefox in particular.

                                  firefox on FreeBSD is terrible when it comes to opacity. The larger the
                                  size of a semi transparent div, the slower the box gets (yes, not just
                                  the browser, but the entire box). The lightbox effect can make a
                                  browser really slow, and trying to drag over that is very jerky.

                                  Dragging a large semi-transparent div is also jerky and sometimes leaves
                                  trails behind.

                                  Philip

                                  --
                                  YOU [humans] NEED TO BELIEVE IN THINGS THAT AREN'T TRUE. HOW ELSE CAN THEY BECOME?
                                  (Hogfather)
                                Your message has been successfully submitted and would be delivered to recipients shortly.