Responses inline.

> On Mar 26, 2018, at 7:51 AM, Alex Harui <[email protected]> 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

Reply via email to