Hi Harbs,

As I see your major changes is adding _explicitHeight/width and this queue.
Am I understand right all ? Which one actually helps so much ? Adding
_explicitHeight/width or that queue ?

Thanks,
Piotr

2018-03-24 22:04 GMT+01:00 Harbs <[email protected]>:

> I just pushed some changes to a layout-optimization branch.
>
> I’m seeing about a 5 *times* improvement in performance with layouts and I
> don’t see any issues with the layout. It seems to me like this optimization
> was a lot more painless than I feared.
>
> Where I was seeing a layout take about 150 ms, it’s not taking about 30
> ms. The only place I’m seeing the dreaded "Forced reflow” warning now is in
> my own code where it needs optimization.
>
> I don’t see any down-side to the code I committed, but I’ll wait for
> feedback before I merge it in.
>
> Harbs
>
> > On Mar 24, 2018, at 10:17 PM, Harbs <[email protected]> wrote:
> >
> > This is all good info.
> >
> > Here’s the problem as I see it:
> >
> > 1. Measuring width and height cause reflows if css properties were set
> and/or the Dom structure was changed.
> > 2. EVERY layout reads the host width and height before and after layout.
> Every layout (currently) subclasses LayoutBase.
> > 3. It’s pretty unlikely for any layout so not set some property, so what
> happens in #2 will cause a reflow every time unless the width and height is
> explicitly set (using a modification to the width and height getters).
> >
> > I’m looking to solve this by the following:
> > 1. Optimize the width and height getters to return the explicit values
> if they exist. In my case, this seems to yield about a 10% improvement.
> That’s not bad, but I think we can do much better.
> > 2. Delay the layout until the entire DOM structure is measured.
> > 3. The measuring might also need to be delayed until the whole structure
> is created.
> >
> > Basically, I want to make a measuring stage and then a setting stage.
> I’m not sure whether I should use requestAnimationFrame or some other
> method. The trick will be getting the measurements and the layouts executed
> in the correct order.
> >
> > Some links on the topic:
> >
> > http://blog.fogcreek.com/we-spent-a-week-making-trello-
> boards-load-extremely-fast-heres-how-we-did-it/ <
> http://blog.fogcreek.com/we-spent-a-week-making-trello-
> boards-load-extremely-fast-heres-how-we-did-it/>
> > http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/ <
> http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/>
> > http://wilsonpage.co.uk/preventing-layout-thrashing/ <
> http://wilsonpage.co.uk/preventing-layout-thrashing/>
> >
> > I’m planning on spending time on this tomorrow. I’ll see what I can come
> up with…
> >
> > Harbs
> >
> >> On Mar 23, 2018, at 7:11 PM, Alex Harui <[email protected]
> <mailto:[email protected]>> wrote:
> >>
> >> Hi Harbs,
> >>
> >> For sure, it would be great for you to take a look at layout.
> >>
> >> Besides what Peter wrote below, there are other things to consider:
> >>
> >> 1) Like Flex, Royale layouts assume that (when necessary) parents size
> >> their children.  That just makes sense for responsive apps that respond
> to
> >> the size of the application window.
> >> 2) Like Flex, Royale's UIBase has APIs that "temporarily" set a size.
> >> Setting width/height also sets explicitWidth/explicitHeight, but the
> >> setWidth/setHeight/setWidthAndHeight calls only set the width/height
> and
> >> do not set explicitWidth/explicitHeight in order for that layout pass to
> >> set the size but not have the explicitWidth/Height factored into the
> next
> >> layout pass.
> >> 3) The code snippet you posted I'm pretty sure is used for when a
> child's
> >> size changes and the parent's size should then change.  As Peter said,
> >> some components are sized to content and the layout should be responsive
> >> to the content.
> >>
> >> But what I think is most important is really what the DOM looks like.
> The
> >> only goal for Royale layouts for JS is to set up the DOM.  In theory,
> the
> >> default VerticalLayout and HorizontalLayouts do not measure anything nor
> >> do they set the width and height on the children.  They merely set the
> >> display style to block or inline-block.  Then it is up to the browser to
> >> decide when/how to layout.  Ideally, our JS code is creating widgets and
> >> setting display styles in the most optimal way to create the same DOM
> you
> >> would by hand with an HTML editor.
> >>
> >> So, for your app, the first question is: did Royale set up the DOM in
> the
> >> best possible way?  I think you said there was a fair amount of absolute
> >> positioning in your app.  If the Royale absolute positioning layout is
> not
> >> allowing the construction of the DOM in the best possible way, the next
> >> question is then: should the current layout algorithm be changed because
> >> it is just plain wrong, or should you create a different absolute
> >> positioning layout that is optimized for the kinds of DOM sub-trees you
> >> like to use?  Or should you be revising your app to use a layout based
> on
> >> FlexBox or CSSGrid?
> >>
> >> So, it might turn out that BasicLayout is always going to be slow but it
> >> will handle just about any absolute positioning from both top-down
> >> percentage sizing as well as sizing to content of children, but that new
> >> layouts should be created that drastically reduce the number of folks
> that
> >> need to use BasicLayout in production.
> >>
> >> My 2 cents,
> >> -Alex
> >>
> >> On 3/23/18, 7:25 AM, "Peter Ent" <[email protected] <mailto:
> [email protected]>> wrote:
> >>
> >>> The code looks familiar, but I'm not 100% sure.
> >>>
> >>> The trick with layouts is that there are the following things to
> consider:
> >>>
> >>> If everything has an explicit width/height, it should be pretty easy.
> >>>
> >>> The percentWidth/height when present changes the _width, _height
> without
> >>> changing the explicit size. This allows a layout to work again on the
> >>> percent value and calculate a new size. If the explicit sizes are set,
> >>> then the next layout pass will take the explicit over the percent
> (setting
> >>> explicit sizes sets the percent sizes to NaN and vice-versa) and what
> was
> >>> once 50% will now be fixed in size.
> >>>
> >>> The tricky part - for me anyway - is when an item has no size set. Then
> >>> its supposed be sized by its content. Labels and Buttons sized by their
> >>> text or icons while containers are sized by their children and so
> forth.
> >>>
> >>> Let's say you have one container nested inside of another and in the
> inner
> >>> most container is a single button. The outer most layout cannot
> determine
> >>> its container-child's size because it doesn't have one yet. The inner
> >>> container needs to get the size of its children (the button) and that
> then
> >>> becomes its size. But it should not be setting the explicit sizes. That
> >>> allows the button to be resized which means its container becomes
> bigger
> >>> which means the outer container becomes bigger. Once you set those
> >>> explicit sizes, then its game over - use case #1 essentially.
> >>>
> >>> So - I think that code has to do with determining size-by-content and
> so
> >>> isLayoutRunning was created to prevent a recursion.
> >>>
> >>> For me, working with Flex and Royale - determining the size of
> something
> >>> has been one of the biggest challenges.
> >>>
> >>> ‹peter
> >>>
> >>> On 3/23/18, 7:46 AM, "Harbs" <[email protected] <mailto:
> [email protected]>> wrote:
> >>>
> >>>> I¹m working on making layouts more efficient. Currently, there¹s lots
> of
> >>>> setting and reading of width and height which causes many browser
> >>>> reflows. While profiling performance in my app, reflows is a major
> >>>> bottleneck. In one area, it¹s taking about 150ms (on my I7 2.8 Ghz
> >>>> MacBook Pro ‹ on tablets it¹s painfully slow) to execute on area of
> >>>> layout. Almost all of that time is being spent measuring with and
> height
> >>>> of components. The width and height getters trigger reflow because
> >>>> properties are recursively set in layout.
> >>>>
> >>>> I was able to get about a 10% improvement by optimizing the width and
> >>>> height getters to return the explicitWdith and explicitHeight if set.
> It
> >>>> looks to me like almost all of this bottleneck could be eliminated by
> >>>> delaying the property setting until after the measurements are done.
> I¹m
> >>>> working on doing that, but I have a question:
> >>>>
> >>>> LayoutBase.performLayout has the following code:
> >>>>
> >>>>                                    // check sizes to see if layout
> changed the size or not
> >>>>                                    // and send an event to re-layout
> parent of host
> >>>>                                    if (host.width != oldWidth ||
> >>>>                                            host.height != oldHeight)
> >>>>                                    {
> >>>>                                            isLayoutRunning = true;
> >>>>                                            host.dispatchEvent(new
> Event("sizeChanged"));
> >>>>                                            isLayoutRunning = false;
> >>>>                                    }
> >>>>
> >>>> Under what circumstances does this code get executed? This appears to
> be
> >>>> causing a recursive layout. Can I assume that there will be an
> >>>> explicitWidth/height when this will be executed?
> >>>
> >>
> >
>
>


-- 

Piotr Zarzycki

Patreon: *https://www.patreon.com/piotrzarzycki
<https://www.patreon.com/piotrzarzycki>*

Reply via email to