diff --git a/formula-android-compose/src/main/java/com/instacart/formula/android/compose/ComposeViewFactory.kt b/formula-android-compose/src/main/java/com/instacart/formula/android/compose/ComposeViewFactory.kt index f0c1bcd1..e32a4573 100644 --- a/formula-android-compose/src/main/java/com/instacart/formula/android/compose/ComposeViewFactory.kt +++ b/formula-android-compose/src/main/java/com/instacart/formula/android/compose/ComposeViewFactory.kt @@ -14,19 +14,28 @@ abstract class ComposeViewFactory : ViewFactory { override fun create(inflater: LayoutInflater, container: ViewGroup?): FeatureView { val view = ComposeView(inflater.context) + var firstRender = true return FeatureView( view = view, - bind = { + bind = { state -> view.setContent { - val model = it.observable.subscribeAsState(null).value + val model = state.observable.subscribeAsState(null).value if (model != null) { val start = SystemClock.uptimeMillis() Content(model) val end = SystemClock.uptimeMillis() - it.environment.eventListener?.onRendered( - fragmentId = it.fragmentId, + state.environment.eventListener?.onRendered( + fragmentId = state.fragmentId, durationInMillis = end - start, ) + + if (firstRender) { + firstRender = false + state.environment.eventListener?.onFirstModelRendered( + fragmentId = state.fragmentId, + durationInMillis = end - state.initializedAtMillis, + ) + } } } null diff --git a/formula-android/src/main/java/com/instacart/formula/android/FeatureView.kt b/formula-android/src/main/java/com/instacart/formula/android/FeatureView.kt index b2ced889..f4b24a53 100644 --- a/formula-android/src/main/java/com/instacart/formula/android/FeatureView.kt +++ b/formula-android/src/main/java/com/instacart/formula/android/FeatureView.kt @@ -22,6 +22,7 @@ class FeatureView( val lifecycleCallbacks: FragmentLifecycleCallback? = null, ) { class State( + val initializedAtMillis: Long, val fragmentId: FragmentId, val environment: FragmentEnvironment, val observable: Observable, diff --git a/formula-android/src/main/java/com/instacart/formula/android/FormulaFragment.kt b/formula-android/src/main/java/com/instacart/formula/android/FormulaFragment.kt index 0c0e421e..2ad51618 100644 --- a/formula-android/src/main/java/com/instacart/formula/android/FormulaFragment.kt +++ b/formula-android/src/main/java/com/instacart/formula/android/FormulaFragment.kt @@ -1,6 +1,7 @@ package com.instacart.formula.android import android.os.Bundle +import android.os.SystemClock import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -29,6 +30,8 @@ class FormulaFragment : Fragment(), BaseFormulaFragment { requireArguments().getParcelable(ARG_CONTRACT)!! } + private val initializedAtMillis = SystemClock.uptimeMillis() + private var featureView: FeatureView? = null private val stateRelay: BehaviorRelay = BehaviorRelay.create() private var cancelable: Cancelable? = null @@ -50,6 +53,7 @@ class FormulaFragment : Fragment(), BaseFormulaFragment { super.onViewCreated(view, savedInstanceState) featureView?.let { value -> val state = FeatureView.State( + initializedAtMillis = initializedAtMillis, fragmentId = getFormulaFragmentId(), environment = FormulaFragmentDelegate.fragmentEnvironment(), observable = stateRelay, diff --git a/formula-android/src/main/java/com/instacart/formula/android/FragmentEnvironment.kt b/formula-android/src/main/java/com/instacart/formula/android/FragmentEnvironment.kt index f907b611..d284d412 100644 --- a/formula-android/src/main/java/com/instacart/formula/android/FragmentEnvironment.kt +++ b/formula-android/src/main/java/com/instacart/formula/android/FragmentEnvironment.kt @@ -25,5 +25,11 @@ data class FragmentEnvironment( * Called after render model was applied to the [FeatureView]. */ fun onRendered(fragmentId: FragmentId, durationInMillis: Long) + + /** + * Called after first render model is rendered. The [durationInMillis] starts + * when formula fragment is initialized and ends after first render model is applied. + */ + fun onFirstModelRendered(fragmentId: FragmentId, durationInMillis: Long) } } diff --git a/formula-android/src/main/java/com/instacart/formula/android/views/FeatureViewBindFunction.kt b/formula-android/src/main/java/com/instacart/formula/android/views/FeatureViewBindFunction.kt index 4b29a51c..56f083e5 100644 --- a/formula-android/src/main/java/com/instacart/formula/android/views/FeatureViewBindFunction.kt +++ b/formula-android/src/main/java/com/instacart/formula/android/views/FeatureViewBindFunction.kt @@ -14,6 +14,7 @@ internal class FeatureViewBindFunction( ) : (FeatureView.State) -> Cancelable? { override fun invoke(state: FeatureView.State): Cancelable { val environment = state.environment + var firstRender = true val disposable = state.observable.subscribe { try { val start = SystemClock.uptimeMillis() @@ -23,6 +24,13 @@ internal class FeatureViewBindFunction( fragmentId = state.fragmentId, durationInMillis = end - start, ) + if (firstRender) { + firstRender = false + environment.eventListener?.onFirstModelRendered( + fragmentId = state.fragmentId, + durationInMillis = end - state.initializedAtMillis, + ) + } } catch (exception: Exception) { environment.onScreenError(state.fragmentId.key, exception) }