https://kotlinlang.org logo
#compose
Title
# compose
p

Patrick Yin

07/29/2020, 12:03 AM
About
@Preview
, will the @Preview marked method be removed (or changed) when assembling release build?
thanks mate
g

gildor

07/29/2020, 6:43 AM
But they still will be there if you do not use R8
So you compile all you previews just to build debug version of your app Doesn’t look very scalable thing, if you have multiple previews for every of you composable, you will end up with a lot of code if write project from scratch
Wouldn’t be a better solution to have additional source set for preview, which depends on you main source set but not used for compilation, something similar to testFixtures source set in Gradle
I understand, it looks nice to have preview defined in the same file and say that “it would be shinked by R8”, but I have feeling that it’s the thing which will bite you eventually
j

jim

07/29/2020, 10:59 AM
We would strongly recommend you have R8 enabled. If you don't have R8 enabled,
@Preview
is the least of your worries.
Can you elaborate on what you mean by it not being very scalable?
g

gildor

07/29/2020, 1:54 PM
Nobody uses R8 during development
About scalability I want to say that you pay for every line of code by direct compilation time and by invalidation of already compiler code So you have to compile all preview even if don't use them for debug or tests So if you have hundreds components each of them probably have at least 1 preview, you compile all of them
What even worse, you change your preview, you now have to compile this module, if it changed abi, you have to run annotation processors on all upstream modules
So if non-abi change for our project in best case is 15 second, ABI change is at least 30 seconds
So I wouldn't like to have previews or test data in my main source set
j

jim

07/29/2020, 9:45 PM
Well, yes and no. True: no one uses R8 during development, but the size in development isn't nearly as important. The original question was specifically about reducing the bytecode during a release build. Reducing bytecode during a debug build isn't nearly as important, except in sofar as it impacts compile performance, which brings me to my second point. Your compose widgets should generally be in leaf modules because they shouldn't be depending upon internals of your app. For a well-structured app, this means that changes in your app won't cause the widgets to be rebuilt. Low-level widgets (the type used everywhere) are going to be written and then shouldn't change super often, so the scope of a build invalidation is typically small, assuming you have your build files properly configured. That isn't to say that none of this is matters - build times are critically important - but there is probably lower hanging fruit than trying to avoid
@Preview
functions. Having said that, the annotation is flexible, and if you find that moving your `@Preview`s outside of your main modules does in fact get you significant savings, feel free to do that! You can and should structure your app in whichever way works best for you.
p

Patrick Yin

07/29/2020, 9:58 PM
I’ve found a way to make it work without enabling obfuscations. Sometimes you could not fully enable R8 for the project since it has some reflection usage might be broken. (yes, you could add -keep rules to proguard configuration, but you might not have time to solve all of the issues if you are on a big codebase). So I just tested, the easiest way is just enable R8 and in the proguard configuration, put:
Copy code
-dontobfuscate
-dontoptimize
And then it won’t obfuscate anything, and only remove unused methods. (@Preview methods)
So if you really want to remove preview functions on your debug build, you could do this. (But from my point of view, I don’t really care about Debug build’s size)
g

gildor

07/30/2020, 2:21 AM
So if you really want to remove preview functions on your debug build, you could do this
It’s still build performance penalty, tree shaking is not free
the size in development isn’t nearly as important
I mostly agree, not very important, difference is minor (packing, installation)
Your compose widgets should generally be in leaf modules because they shouldn’t be depending upon internals of your app
It’s true, and what I said is for leaf module, the best case. But you also have hierarchy of modules, a lot of components are reused, or part of another component in another module, which itself part of another component and so on.
are going to be written and then shouldn’t change super often
Until you start working on some changes (or want to play with preview of some core component!) and getting close to full recompilation when you want to change something in those core widgets
but there is probably lower hanging fruit than trying to avoid 
@Preview
 functions
I would love to hear about all those lower hanging fruits, but we very careful with build and configuration time, now most of time is obviously annotation processing, direct compilation and app packing And unfortunately all those “fruits” will not change one fact, you still pay by build time on amount of code which you have to compile
moving your `@Preview`s outside of your main modules does in fact get you significant savings
It would increase amount of modules, adding modules not only boilerplate itself, but also increase configuration time (which will problem even with gradle configuration cache). I think custom source set, same way as it works for tests or for textFixtures is way to go, it allows you have preview separated from main app code without build penalty
I’m sorry if my comments sound harsh, I’m very appreciate work done on compose and very impressed even by current state of
@Preview
But I also a person who responsible for build infrastructure, and spent huge amount of time fighting with build system, AGP, project structure itself to keep the team productive and reduce compilation time. And when we start adopting compose I wouldn’t like to be in a choice between 1. “we will write preview in main code” and ended up in a year or two with significant amount of code which used only for preview rarely, but compiled every time on CI, recompiled often because incremental compilation is not so stable (and without easy way to measure impact of it) and causes more abi changes than it could be 2. Invent own way to move preview away from main source set by creating a custom source set or special system of modules which include only preview, but getting all possible issues with Android Studio preview integration (code preview, live preview, preview on device etc), some build issues and so on, which we have to maintain ourselves And I really don’t know which option I would choose
👍 1
k

Karthick

08/02/2020, 6:14 PM
Is it possible to do a restriction, that a preview function cannot be called from a normal or composable function
5 Views