royale-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Harbs <harbs.li...@gmail.com>
Subject Re: Layout optimizations
Date Mon, 26 Mar 2018 10:21:50 GMT
Responses inline.

> On Mar 26, 2018, at 7:51 AM, Alex Harui <aharui@adobe.com.INVALID> wrote:
> 
> I'm replying to this post even if it isn't the latest because it has the
> most discussion items in it.  First, though, thank you for working on this
> and digging up related posts and information.
> 
> Responses inline.
> 
> Grabbing two discussion items from a later post:
> 
> 1) is requestAnimationFrame deployed everywhere?  I think caniuse.com said
> it wasn't on my version of Safari.

Yes. It’s supported on all modern browsers from IE10 and later. It’s supported in Safari
starting from version 6.1. It’s supported in iOS starting from iOS 7. Android from 4.4.
https://caniuse.com/#feat=requestanimationframe <https://caniuse.com/#feat=requestanimationframe>
> 2) Did AMP say they set style.width or just that they set width in CSS
> possibly via class selectors and other selectors?

AMP uses custom HTML attributes which gets converted to (I think inline) css attributes. https://www.ampproject.org/docs/design/amp-html-layout
<https://www.ampproject.org/docs/design/amp-html-layout>
> 
>> 
>> Currently, somewhere up the tree, there’s going to be a component which
>> has a size set explicitly — even if it’s the application. Now it’s
>> possible that the size of the application does not need to be explicitly
>> set in all situations. I’m actually not sure why it’s being set…
> 
>> To facilitate the reflowing of the parent when the host is resized by its
>> children, the original sizes need to be cached and then compared against
>> the new sizes. The problem is due to layouts being recursively called as
>> components are added to their parents.
> 
> PAYG would say that the layouts who care about the parent size run the
> code to figure out what they need and cache sizes they need.  We have some
> methods like isWidthSizedToContent already.

Right, but this is whether the component is sized to content. The problem is knowing whether
the *parent* needs to be sized to content.

>> 
>> You are right that we don’t need to cache these values when there’s only
>> things like (simple) vertical and horizontal layouts being used, but I’m
>> not sure how a layout is supposed to know what the layouts of all its
>> ancestors are to know whether to trigger a resize.
> 
> I think the above paragraph is key:  the PAYG way is to not cache values
> for simple layouts and have the more complex layouts cache and compute
> what they need.  If you have time, I would like to see numbers if all you
> do is move the caching to the layouts that need it.

Caching is pretty cheap, but comparing those values afterwards is pretty expensive.
https://www.evernote.com/l/AI8SyU4hooFKZqb_Qp6cjH5SBXz4_ZUiJuc

In the above screenshot, the full measuring stage takes 0.63 ms and the layout stage takes
16.5 ms. The lion’s share of that time is spent in "Recalculate Style" in the width and
height getters. A significant amount of the time is spent in the x and y getters and setters
in VerticalColumnLayout. There’s concurrent DOM reads and writes there which is a performance
bottleneck. I’m going to do some optimizations there...

Another interesting study is NumericStepperView. NumericStepperView strand setter takes 12.6
ms to run on a single component! There are many subsequent DOM read and writes in that component
causing it to take much longer than necessary to render. I’m going to make some changes
to the class which should vastly improve performance on that.

Performance considerations in general:

It looks like I might have been right that inline css is more performant:
https://stackoverflow.com/questions/8284365/external-css-vs-inline-style-performance-difference
<https://stackoverflow.com/questions/8284365/external-css-vs-inline-style-performance-difference>

Back to simplifying layouts:
It would be great if there was a way to batch write and batch read to the DOM for pieces which
can be run asynchronously. I’m seeing lots of simple things which seem like they are taking
much longer than they need to For example, setDisplayStyleForLayout can take more than a ms.
I think that’s because there’s a read and a write there for each time it’s run.

I definitely think we should have a “simple” layout which does not need to compare widths
and heights (and doesn’t need to run the layout async). But, I’m not sure how to go about
it. We could make it a conscious decision for the developer. If they *know* that they don’t
need to have the child update the parent anywhere in their app, they could use simple layouts.
That does not seem ideal. Any ideas on how the child layout can know whether the parent layout
needs this notification?

One potential issue with my optimization: When the parent *does* need a new layout due to
the child being resized. The parent will only be updated on the *next* animation frame. That
means there will be a single paint between the child layout being run and the parent layout
being run. I don’t know if this an issue. Maybe yes. Another way to go about it might be
to use setImmediate() or functionally equivalent shims instead of requestAnimationFrame.

https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate <https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate>
https://github.com/YuzuJS/setImmediate <https://github.com/YuzuJS/setImmediate>
http://jphpsf.github.io/setImmediate-shim-demo/ <http://jphpsf.github.io/setImmediate-shim-demo/>

Harbs
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message