eclipsesource / tabris-js

Create native mobile apps in JavaScript or TypeScript.
https://tabrisjs.com
BSD 3-Clause "New" or "Revised" License
1.4k stars 170 forks source link

Research native FlexBox support #2101

Closed tbuschto closed 3 years ago

elshadsm commented 4 years ago

FlexboxLayout

We can add FlexBox support to native Android by implementing FlexboxLayout that was developed by Google.

As they mention: "FlexboxLayout is a library project which brings the similar capabilities of CSS Flexible Box Layout Module to Android."

There are a few differences from the original CSS specification, but I don't think that's actually a problem.

As an initial impression:

Yoga Layout

Another FlexBox support option for Android is Yoga Layout - A cross-platform layout engine (Moritz mentioned it on the Tabris channel).

The library was developed by Facebook and you can get information such as PERFORMANCE, CROSS PLATFORM, and Open Source Adoption from their web sites.

As an initial impression - only about Android side implementation:

To summarize, the project seems powerful but it is not popular in the native Android side.

patrykmol commented 4 years ago

Android & iOS implementations: https://github.com/facebook/yoga https://github.com/vislyhq/stretch

iOS only: https://github.com/layoutBox/FlexLayout

Interestingly Stretch also provides a JS implementation for web use. However almost all tutorials are about Yoga. This makes me assume it is not that popular in iOS world. It is also written in Rust therefore it might add another layer of complexity.

tbuschto commented 4 years ago

Cross-platform solutions are highly preferrable, so let's stick to Yoga and Stretch for now.

Here are some open questions, @patrykmol @elshadsm : 1 - Is either library known to be significantly faster on your platform? 2 - Does either library have known issues or missing features on your platform? 3 - Will either library be significantly more time consuming to integrate on your platform? 4 - Will either library significantly increase the complexity of platform or tabris app builds?

I will also have a look to see if I can find any pro or cons that aren't platform specific.

Edit: 5 - How much does either library increase your platform size?

tbuschto commented 4 years ago

Github Stats:

_ Yoga Stretch
Version 1.8.0 0.3.2
First Commit 04/2014 11/2018
Commits 1,991 355
License MIT MIT
Maintainer Facebook Visly

Claims by Rust:

Yoga is a cross-platform implementation of Flexbox written in C. Yoga is a fantastic project but has some fundamental issues which we hope to resolve. Compared to Yoga we aim to have a stronger adherence to web standards, a flexible architecture eventually supporting multiple layout algorithms, and future performance improvements including multi-threaded layout. In addition to this we aim to use a safer language with a more modern codebase.

There is one significant deviation between yoga and web standard: https://github.com/facebook/yoga/issues/427 - It's not terrible, but considering we may also want to do a web platform at some point it's worth considering.

elshadsm commented 4 years ago

I would like to answering these questions starting with the Yoga Layout.

Yoga Layout

1. Is either library known to be significantly faster on your platform?

I tested the layout on a real device with 2000 child TextView-s and it worked pretty quickly. Even it seemed faster to me than creating the same children in the native ConstraintLayout.

2. Does either library have known issues or missing features on your platform?

Since there is a lack of information for the Android side implementation + link to Android documentation is broken, it is hard to find any information regarding missing features...

P.S. There is an open issue about the Link to Android Documentation is broken.

3. Will either library be significantly more time consuming to integrate on your platform?

4. Will either library significantly increase the complexity of platform or tabris app builds?

5. How much does either library increase your platform size?

elshadsm commented 4 years ago

Stretch Implementation

The Stretch implementation is different than we thought. An answer in this issue explains the purpose of the project more clearly:

"Stretch isn't really designed to be used from user-space code. It is more designed to be used at the heart of GUI libraries and thus provides a very low level api. It is up to higher level libraries and frameworks to provide a consistent api frontend to stretch. The reason for this is so that we can focus on the algorithmic implementation and low level platform bindings in this project and don't need to worry about supporting bindings for every platform and UI framework out there."

So we can't use it directly as Yoga Layout, but I tested the Stretch Implementation like this:

1. Created a RelativeLayout. 2. Created child views and measured their size(including intrinsic views). 3. Computed coordinates(x and y)/layout of children using Stretch. 4. Added them to RelativeLayout with the relevant coordinates that we get from the computation above.

@tbuschto and @patrykmol, your opinion interesting to me as well, what do you think about this implementation?

Questions

1. Is either library known to be significantly faster on your platform?

2. Does either library have known issues or missing features on your platform?

3. Will either library be significantly more time consuming to integrate on your platform?

4. Will either library significantly increase the complexity of platform or tabris app builds?

5. How much does either library increase your platform size?

mpost commented 4 years ago

Thanks for the detailed comparison of the two. It is interesting to read about Stretch and how it is not actually tied to the View system of Android but merely performs the calculation. The binding is a language binding to native api but not the View system.

@elshadsm Do you know how Stretch would handle the case of text measurement? How would it know about a Views intrinsic size when it can be dynamic? Eg. when it contains text or an image.

elshadsm commented 4 years ago

@mpost I have no idea right now, and I think the answer requires a deep level investigation.

I think we should look at how layouts (especially Yoga Layout) tie calculations with views, deal with intrinsic size views, etc. at a deep level.

P.S. I couldn't find any usage of the Stretch Implementation in a real project (especially in an Android project). If so, we could be inspired.

patrykmol commented 4 years ago

Regarding @tbuschto questions:

  1. There are no direct performance comparisons between the two. Both seem to be focused on performance.
  2. Stretch does is just a layout calculation engine. We would have to make a wrapper around it to make it work with UIKit. As for Yoga, there are multiple iOS issues opened (35 at the time of writing) but many are old and are just questions and not bug reports.
  3. I believe Stretch will be more involving since it's more of a layout calculation engine instead of ready to use layouting framework. In the issue Elshad linked that Stretch is replacement for Yoga, not YogaKit and that YogaKit equivalent is what we would have make ourselves.
  4. Stretch will add Rust to the existing build chain. Yoga is C/C++ and both iOS and Android build envs can compile it without much issues.
mpost commented 4 years ago

One more addition to the framework discussion, Several ui elements in tabris are in fact Composite based like Page, Tab, ScrollView etc. If we were to go down the route of replacing it with a predefined view like a "YogaView" or a "StretchView", this could lead to considerable rework. Interestingly bot these frameworks support to only perform the calculation without actually applying the result to any view system. Also both frameworks provide callbacks to help the native side measure intrinsic sizes of widgets.

patrykmol commented 3 years ago

Here's iOS perspective on YogaKit and Stretch.

YogaKit

Stretch

After having done this research I think that YogaKit is much better choice. I could continue with Stretch testing but I am not convinced that it is worth investing time into making bindings.

tbuschto commented 3 years ago

We agree to do it with YogaKit for both platforms