Yelp Adopted the MVI Structure to Enhance Efficiency and Testability of Their Android App

[ad_1]

4 years into the adoption of the Mannequin-View-Intent (MVI) structure for his or her Android app, Yelp engineer Paul Martin says it allowed them to have performant screens and enhance unit testing.

Earlier than adopting MVI, Yelp was utilizing the Mannequin-View-Presenter (MVP) structure, which had the principle shortcomings of manufacturing bigger and extra complicated information because the app pages grew in complexity.

Our presenters grew to have far too many strains of code and have become unwieldy and awkward to take care of as we would have liked so as to add extra state-management and create extra complicated presenter logic for MVP pages

Yelp engineers additionally evaluated the potential of switching to the Mannequin-View-ViewModel (MVVM) structure, which is extra appropriate for event-driven, reactive UIs. Whereas MVVM mitigated a few of the shortcomings of MVP, it might nonetheless result in bigger knowledge courses with many properties because the view complexity grows. Moreover, Yelp engineers discovered that MVVM blended poorly with their very own Bento framework they based mostly their app consumer interface on.

On the basis of the Mannequin-View-Intent (MVI) structure is the notion of intent, which represents the consumer intention behind a given occasion obtained by the UI. The consumer intent is transformed into an motion which is accountable to replace the view state, which the view then renders on display. In MVI, the circulate of information associated to occasions and states might be represented by means of a reactive stream that each the mannequin and the view subscribe to for modifications.

One weak level in MVI is the mapping between occasions and actions, which is normally completed in huge swap assertion. This results in apparent limitations on scalability. Yelp engineers circumvented this concern by annotating strategies implementing actions with their corresponding occasions, e.g.:


@Occasion(HeaderClicked::class)
enjoyable onHeaderClick() {
  // do one thing
}

@Occasion(BodyClicked::class)
enjoyable onBodyClick() {
  // do one thing
}

@Occasion(FooterClicked::class)
enjoyable onFooterClick() {
  // make community request and many others
}

At runtime, when the view and the mannequin are created, annotations are processed to create a mapping between occasions and actions.

Along with this, Yelp engineers additionally addressed the problem of rising code complexity, on account of views rising extra complicated, with the concept of sub-presenters, which might be although of as sub-models. Briefly, as a substitute of defining all actions in a single mannequin, a sub-presenter allows modularization them. For instance, we will modify the earlier instance so the header and footer click on motion handlers belong to a distinct sub-presenter:


@Occasion(BodyClicked::class)
enjoyable onBodyClick() {
  // do one thing
}

// The remainder of click on occasions are dealt with in right here
@SubPresenter personal val subPresenter = MyFeatureSubPresenter(eventBus)

Since occasions and states are transmitted in a stream — referred to as eventBus within the instance above — any celebration can observe, there are not any added dependencies launched by this method. An extra profit it introduced was simplifying unit testing by enabling recording occasions and states transmitted throughout the bus utilizing presenter guidelines and utilizing asserts to ensure the anticipated consequence is produced:


enjoyable whenButtonClicked_loadingProgressShown() {
     presenterRule.sendEvent(ButtonClicked)
     presenterRule.assertEquals { listOf(ShowLoadingProgress) }
}

Utilizing MVI, Yelp engineers might transfer many actions to background threads, which improved the app efficiency. Particularly, they may scale back by over 50% the typical body render time, and by virtually 4% the variety of frozen frames, which in flip translated into higher outcomes for his or her onboarding and sign-up use circumstances.



[ad_2]

Leave a Comment

Your email address will not be published. Required fields are marked *