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

Improve the build times of your project is not ...

Avatar for antonicg antonicg
July 05, 2024
130

Improve the build times of your project is not impossible. How we achieved in N26 #dcbln24

Slides for the talk in Droidcon Berlin 2024

Avatar for antonicg

antonicg

July 05, 2024
Tweet

Transcript

  1. Antoni Castejón Improve the build times of your project is

    not impossible. How we achieved it in N26
  2. single_feature_app 1 feature_app feature_lib single_feature_app 2 feature_app feature_lib single_feature_app 3

    feature_app feature_lib single_feature_app 4 feature_app feature_lib The N26 android project Setup before the initiative app features folder
  3. single_feature_app 1 feature_app feature_lib single_feature_app 2 feature_app feature_lib single_feature_app 3

    feature_app feature_lib single_feature_app 4 feature_app feature_lib The N26 android project Setup before the initiative app core libraries folder features folder
  4. core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib core_lib core_lib core_lib core_lib single_feature_app 1 feature_app feature_lib single_feature_app 2 feature_app feature_lib single_feature_app 3 feature_app feature_lib single_feature_app 4 feature_app feature_lib The N26 android project Setup before the initiative app core libraries folder features folder
  5. single_feature_app 1 feature_app feature_lib The N26 android project Single feature

    apps • The feature code • Runs independently • Entry point
  6. single_feature_app 1 feature_app feature_lib The N26 android project Single feature

    apps • The feature code • Runs independently • Entry point • Less dependencies
  7. single_feature_app 1 feature_app feature_lib The N26 android project Single feature

    apps • The feature code • Runs independently • Entry point • Less dependencies • Less build time
  8. single_feature_app 1 feature_app feature_lib The N26 android project Single feature

    apps • Login • Activity entry point • No production code
  9. single_feature_app 1 feature_app feature_lib The N26 android project Single feature

    apps • Login • Activity entry point • No production code • com.android.application
  10. single_feature_app 1 feature_app feature_lib The N26 android project Single feature

    apps • Feature code • Production code • com.android.library
  11. The N26 android project Overview before the initiative • 312

    total modules • 119 core libraries core libraries folder core_lib core_lib core_lib core_lib
  12. The N26 android project Overview before the initiative • 312

    total modules • 119 core libraries • 70 SFAs single_feature_app 1 feature_app feature_lib single_feature_app 1 feature_app feature_lib
  13. Chat GPT 3.5 A visual representation of the dependencies between

    different components in a Gradle-based project. It refers to the relationships between different modules, libraries, and other dependencies that make up a gradle application. The Gradle dependency graph
  14. Wikipedia - Glossary of graph theory (https://en.wikipedia.org/wiki/Glossary_of_graph_theory#height) The height of

    a node in a rooted tree is the number of edges in a longest path, going away from the root, that starts at that node and ends at a leaf.
  15. About Gradle Executing a gradle task… Current execution Previous execution

    Gradle incremental builds and caching Outputs Outputs
  16. About Gradle Executing a gradle task… Current execution Previous execution

    Skips execution! Gradle incremental builds and caching Outputs Outputs
  17. About Gradle But… Current execution Gradle incremental builds and caching

    Reexecution is NOT only needed for those tasks…
  18. About Gradle But… Current execution Previous execution Gradle incremental builds

    and caching Reexecution is NOT only needed for those tasks…
  19. About Gradle But… Current execution Previous execution Reexecution is needed

    for those tasks Gradle incremental builds and caching Reexecution is NOT only needed for those tasks…
  20. About Gradle Gradle incremental builds and caching Reexecution is NOT

    only needed for those tasks… … but also for the tasks that depend on them
  21. Apply dependency inversion Solution proposed for the hypothesis • High-level

    modules should depend on abstractions rather than in low-level modules.
  22. Apply dependency inversion Solution proposed for the hypothesis • High-level

    modules should depend on abstractions rather than in low-level modules. • Abstractions should not depend on details. Details should depend on abstractions.
  23. Apply dependency inversion Solution proposed for the hypothesis • High-level

    modules should depend on abstractions rather than in low-level modules. • Abstractions should not depend on details. Details should depend on abstractions. SOLID D
  24. Apply dependency inversion Solution proposed for the hypothesis • High-level

    modules should depend on abstractions rather than in low-level modules. • Abstractions should not depend on details. Details should depend on abstractions. Dependency inversion principle
  25. Apply dependency inversion Solution proposed for the hypothesis public interface

    NetworkApi { fun connectToInternet() fun disconnectFromInternet() } Abstraction
  26. Apply dependency inversion Solution proposed for the hypothesis public interface

    NetworkApi { fun connectToInternet() fun disconnectFromInternet() } Abstraction public class Network : NetworkApi { override fun connectToInternet() { // Starting connection... } override fun disconnectFromInternet() { // Disconnecting... } } Details
  27. Apply dependency inversion Solution proposed for the hypothesis High-level modules

    should depend on abstractions rather than low- level modules.
  28. Apply dependency inversion Solution proposed for the hypothesis High-level modules

    should depend on abstractions rather than low- level modules. feature_lib details
  29. Apply dependency inversion Solution proposed for the hypothesis High-level modules

    should depend on abstractions rather than low- level modules. feature_lib details
  30. Apply dependency inversion Solution proposed for the hypothesis High-level modules

    should depend on abstractions rather than low- level modules. feature_lib details feature_lib abstraction
  31. Apply dependency inversion Solution proposed for the hypothesis High-level modules

    should depend on abstractions rather than low- level modules. feature_lib details feature_lib abstraction
  32. Apply dependency inversion Solution proposed for the hypothesis Abstractions should

    not depend on details. Details should depend on abstractions.
  33. Apply dependency inversion Solution proposed for the hypothesis Abstractions should

    not depend on details. Details should depend on abstractions. feature_lib abstraction
  34. Apply dependency inversion Solution proposed for the hypothesis Abstractions should

    not depend on details. Details should depend on abstractions. feature_lib abstraction details
  35. Apply dependency inversion Solution proposed for the hypothesis Abstractions should

    not depend on details. Details should depend on abstractions. feature_lib abstraction details
  36. Apply dependency inversion Solution proposed for the hypothesis Abstractions should

    not depend on details. Details should depend on abstractions. feature_lib abstraction details feature_lib abstraction
  37. Apply dependency inversion Solution proposed for the hypothesis Abstractions should

    not depend on details. Details should depend on abstractions. feature_lib abstraction details feature_lib abstraction details
  38. Apply dependency inversion Solution proposed for the hypothesis Abstractions should

    not depend on details. Details should depend on abstractions. feature_lib abstraction details feature_lib abstraction details
  39. public class Network : NetworkApi { override fun connectToInternet() {

    // Starting connection... } override fun disconnectFromInternet() { // Disconnecting... } } public interface NetworkApi { fun connectToInternet() fun disconnectFromInternet() } Apply dependency inversion Solution proposed for the hypothesis
  40. public class Network : NetworkApi { override fun connectToInternet() {

    // Starting connection... } override fun disconnectFromInternet() { // Disconnecting... } } public interface NetworkApi { fun connectToInternet() fun disconnectFromInternet() } Apply dependency inversion Solution proposed for the hypothesis abstraction
  41. public class Network : NetworkApi { override fun connectToInternet() {

    // Starting connection... } override fun disconnectFromInternet() { // Disconnecting... } } public interface NetworkApi { fun connectToInternet() fun disconnectFromInternet() } Apply dependency inversion Solution proposed for the hypothesis abstraction api
  42. public class Network : NetworkApi { override fun connectToInternet() {

    // Starting connection... } override fun disconnectFromInternet() { // Disconnecting... } } public interface NetworkApi { fun connectToInternet() fun disconnectFromInternet() } Apply dependency inversion Solution proposed for the hypothesis abstraction details api
  43. public class Network : NetworkApi { override fun connectToInternet() {

    // Starting connection... } override fun disconnectFromInternet() { // Disconnecting... } } public interface NetworkApi { fun connectToInternet() fun disconnectFromInternet() } Apply dependency inversion Solution proposed for the hypothesis abstraction details api core
  44. Apply dependency inversion Solution proposed for the hypothesis core_lib core_lib

    core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib single_feature_app 1 feature_app feature_lib single_feature_app 2 feature_app feature_lib single_feature_app 3 feature_app feature_lib single_feature_app 4 feature_app feature_lib app core libraries folder features folder core_lib
  45. feature_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib Before

    dependency inversion core_lib 🔄 🔄 🔄 🔄 🔄 🔄 🔄
  46. feature_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib Before

    dependency inversion core_lib 🔄 🔄 🔄 🔄 🔄 🔄 🔄 SEQUENTIALLY
  47. With dependency inversion app feature_app feature_lib core_lib lib core_lib api

    api api api legacy app feature_app feature_lib core core 😃
  48. With dependency inversion app feature_app feature_lib core_lib lib core_lib api

    api api api legacy app feature_app feature_lib core core
  49. With dependency inversion app feature_app feature_lib core_lib lib core_lib api

    api api api legacy app feature_app feature_lib core core 🔄
  50. Process we follow Iterative Discovery Pick the top 5 core

    libraries with: ✅ More edges ✅ Easy to apply
  51. Process we follow Iterative Discovery Pick the top 5 core

    libraries with: ✅ More edges ✅ Easy to apply Implementation Apply DI
  52. Process we follow Iterative Discovery Pick the top 5 core

    libraries with: ✅ More edges ✅ Easy to apply Implementation Apply DI Benchmark Compare results: master changes
  53. Chat GPT 3.5 Monolith: A monolith refers to an application

    that is built as a single, unified unit. All components and features of the application are tightly integrated into a single codebase, often resulting in a large and complex code structure. Legacy monoliths
  54. Chat GPT 3.5 Legacy: Refers to older software systems that

    are still in use but are no longer actively developed or maintained. These systems are usually built using older technologies, frameworks, and practices that might not align with modern software development trends and best practices. Legacy systems can pose challenges in terms of scalability, maintenance, and integration with newer technologies. Legacy monoliths
  55. core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib injectLegacy injectLegacy Legacy monoliths
  56. core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib injectLegacy injectLegacy feature_lib core_lib Legacy monoliths app
  57. Anvil VS Hilt Anvil • Kotlin compiler plugin • Needs

    Dagger Hilt • Dependency injection framework
  58. Anvil VS Hilt Anvil • Kotlin compiler plugin • Needs

    Dagger Hilt • Dependency injection framework • Independent library
  59. Anvil VS Hilt Anvil • Kotlin compiler plugin • Needs

    Dagger • Merges components and modules using annotations Hilt • Dependency injection framework • Independent library
  60. Anvil VS Hilt Anvil • Kotlin compiler plugin • Needs

    Dagger • Merges components and modules using annotations Hilt • Dependency injection framework • Independent library • Simpli fi es Dagger DI for Android.
  61. Anvil VS Hilt Anvil • Kotlin compiler plugin • Needs

    Dagger • Merges components and modules using annotations • @ContributesBinding is nice Hilt • Dependency injection framework • Independent library • Simpli fi es Dagger DI for Android.
  62. Anvil VS Hilt Anvil • Kotlin compiler plugin • Needs

    Dagger • Merges components and modules using annotations • @ContributesBinding is nice Hilt • Dependency injection framework • Independent library • Simpli fi es Dagger DI for Android. Both makes Dagger setup simpler
  63. KAPT • Kotlin Annotation Processor Tool necessary for Dagger •

    It makes the builds slower • Hilt needs kapt
  64. KAPT • Kotlin Annotation Processor Tool necessary for Dagger •

    It makes the builds slower • Hilt needs kapt • Anvil doesn’t need kapt for:
  65. KAPT • Kotlin Annotation Processor Tool necessary for Dagger •

    It makes the builds slower • Hilt needs kapt • Anvil doesn’t need kapt for: ✅ Modules without a @Component
  66. KAPT • Kotlin Annotation Processor Tool necessary for Dagger •

    It makes the builds slower • Hilt needs kapt • Anvil doesn’t need kapt for: ✅ Modules without a @Component ✅ Pure Kotlin modules
  67. core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib injectLegacy injectLegacy feature_lib core_lib Legacy monoliths app
  68. core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib injectLegacy injectLegacy BaseComponent BaseSessionComponent feature_lib core_lib Legacy monoliths app
  69. Legacy monoliths injectLegacy core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib core_lib core_lib core_lib injectLegacy BaseComponent BaseSessionComponent feature_lib core_lib
  70. Legacy monoliths injectLegacy core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib core_lib core_lib core_lib injectLegacy BaseComponent BaseSessionComponent feature_lib core_lib ✅ Removed injectLegacy dependency ✅ Add Anvil plugin (if necessary) Done by Platform team 1
  71. app Legacy monoliths injectLegacy core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib core_lib core_lib core_lib core_lib injectLegacy BaseComponent BaseSessionComponent feature_lib core_lib ✅ ✅ Done 1 ✅ Adds Anvil Plugin ✅ Removed injectLegacy dependency Done by Product teams 2
  72. Involving product teams 1. Step by step guide 2. Tracked

    the process 3. Capacity of the teams 👩💻👨💻
  73. Involving product teams 1. Step by step guide 2. Tracked

    the process 3. Capacity of the teams 4. Explained the bene fi ts Explained the bene fi ts 💉
  74. Involving product teams Explained the bene fi ts ✅ Height

    of the SFA ✅ Skip Kapt The build time of their SFA library will be reduced :
  75. Involving product teams Explained the bene fi ts ✅ Height

    of the SFA ✅ Skip Kapt The build time of the app will be ALSO reduced :
  76. core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib injectLegacy BaseComponent BaseSessionComponent feature_lib core_lib Legacy monoliths injectLegacy ✅ Removed injectLegacy dependency ✅ Add Anvil plugin (if necessary) Done by Platform team 1 ✅ Adds Anvil Plugin ✅ Removed injectLegacy dependency Done by Product teams 2
  77. core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib injectLegacy BaseComponent BaseSessionComponent feature_lib core_lib Legacy monoliths injectLegacy ✅ ✅ Done 1 ✅ Adds Anvil Plugin ✅ Removed injectLegacy dependency Done by Product teams 2
  78. core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib core_lib

    core_lib core_lib injectLegacy BaseComponent BaseSessionComponent feature_lib core_lib Legacy monoliths injectLegacy ✅ ✅ Done 1 ✅ ✅ Done 2 ✅ Delete injectLegacy Done by Platform team 3