Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React NativeのレイアウトエンジンYOGAの仕組み[追体験編] - React Na...

ggtmtmgg
September 13, 2018

React NativeのレイアウトエンジンYOGAの仕組み[追体験編] - React Native Meetup #9

次の記事のスピンオフプレゼンです!

React NativeのレイアウトエンジンYogaの仕組み [前編] https://blog.engineer.adways.net/entry/2018/08/24/202254
React NativeのレイアウトエンジンYogaの仕組み [後編]
https://blog.engineer.adways.net/entry/2018/08/31/180000
React NativeのレイアウトエンジンYogaの仕組み [続編]
https://blog.engineer.adways.net/entry/2018/09/07/193000

React Native Meetup というReact Nativeマンが集うイベントで使ったプレゼン資料です。
https://react-native-meetup.connpass.com/event/97634/

ggtmtmgg

September 13, 2018
Tweet

More Decks by ggtmtmgg

Other Decks in Technology

Transcript

  1. https://github.com/facebook/react-native/issues/20627 Assigning percentage strings to padding, it works incorrect. #20627

    「padding を% 指定した時に, paddingTop とpaddingBottom の大 きさが違う」というissue
  2. 再現する Android + v0.57.0 Android + v0.56.0 Android + Expo

    v29(v0.55.4) iOS + v0.57.0 iOS + v0.56.0 iOS + Expo v29/0.55.4)
  3. 問題1: innerHeight がownerHeight に依存している 誤: innerHeight(40) = availableHight(100) ­ ownerHeight(600)

    * padding(5%) * 2 正: innerHeight(90) = availableHight(100) ­ availableHeight(100) * padding(5%) * 2
  4. 問題1: innerHeight の計算での怪しいところ 1. Yoga のメインルーチンSTEP3 での伸長・伸縮のロジック 2. Yoga のメインルーチンSTEP2

    でのavailableInner の計算 ※ 補足 いきなりYoga を疑ったのは、この手の計算をするのがYoga だと知っていたからで す。 知らなければheight が計算される瞬間を探し求めて、 JavaScript ファイル →Objective−C ファイル→Yoga.cpp と言った形で少しずつ潜っていったと思います。 Yoga.cpp 内で、FlexBox のルールに従って大きさやポジシヨンを計算する一連の処理 がメインルーチンと呼ばれています。 STEP1~STEP11 に分かれていて、複雑な計算をして います。
  5. 1. Yoga のメインルーチンSTEP3 での伸長・伸縮のロジック STEP3 時点でのavailableInnerHeight を確認したい ↓ XCode で該当の行にブレイクポイントを仕込んで

    availableInnerHeight の値を見る ↓ 誤: availableInnerHeight が40 になっている 正: availableInnerHeight が90 以上であるべき
  6. 2. Yoga のメインルーチンSTEP2 でのavailableInner の計算 availableInnerHeight が確定するコードを見つける ↓ float availableInnerHeight

    = YGNodeCalculateAvailableInnerDim(node, YGFlexDirectionColumn, availableHeight, ownerHeight); ↓ ブレイクポイントを仕込んで中の値を見る ↓ 誤: availableInnerHeight が40 になっている 正: availableInnerHeight が90 以上であるべき
  7. YGNodeCalculateAvailableInnerDim() の中を見る float availableInnerDim = availableDim ­ margin ­ paddingAndBorder;

    で40 を代入している ↓ paddingAndBorder が60 になっている 正しくは10 になるはず
  8. node­>getLeadingPaddingAndBorder(axis, widthSize) が 30 になっている node­>getTrailingPaddingAndBorder(axis, widthSize) が30 になっている 正しくはいずれも5

    になるはず ↓ widthSize が600 になっている 正しくは100 になるはず YGNodePaddingAndBorderForAxis() の3 番目の引数を渡してい るところを見に行く
  9. YGNodePaddingAndBorderForAxis() の3 番目の引数を見る const float paddingAndBorder = YGNodePaddingAndBorderForAxis(node, direction, ownerDim);

    ownerDim じゃなくて、availableDim では? ownerDim からpadding を計算するのはおかしい