public class CodeSplitter extends Object
Divides the code in a JsProgram
into multiple fragments. The initial
fragment is sufficient to run all of the program's functionality except for
anything called in a callback supplied to
GWT.runAsync()
. The remaining code should be downloadable via
com.google.gwt.core.client.impl.AsyncFragmentLoader#inject(int)
.
Code splitting is implemented in a two stage process: the first stage decides how runAsyncs are grouped together and the second decides the code in each fragment by computing the appropriate control flow analyses.
The first stage is implemented by a FragmentPartitionStrategy
, that can use fast but
unsound analyses to determine how to group the runAsyncs together, its only requirement is that
the result is a partition of a subset of the runAsyncs. Currently two strategies are implemented:
(1) OneToOneFragmentPartitionStrategy
that assigns each runAsync to one fragment (as in
the original CodeSplitter), and (2) MergeBySimilarityFragmentPartitionStrategy
CodeSplitters.MIN_FRAGMENT_SIZE
is set, this strategy also merge fragments that are
smaller than the minimum fragments size together and if the resulting combined fragment is still
smaller than the minimum fragment size it is left out of the fragmentation so that it is merged
into the leftovers by the second stage.
The second stage assigns program atoms that to fragments that exclusively use them, setting up
and extra fragment for the non exclusive atoms and the runAsyncs that were not assigned to any
fragment. Code that is activated when the application starts and runAsyncs that are part of the
CodeSplitters.PROP_INITIAL_SEQUENCE
are excluded from the first stage and are treated as
special initial fragments that will be downloaded when the application starts.
Whenever this second stage is changed AsyncFragmentLoader
must be updated
in tandem.
The fragment for a runAsync point contains different things depending on whether it is in the initial load sequence or not. If it's in the initial load sequence, then the fragment includes the code newly live once that split point is crossed, that wasn't already live for the set of split points earlier in the sequence. For a split point not in the initial load sequence, the fragment contains only code exclusive to that split point, that is, code that cannot be reached except via that split point. All other code goes into the leftovers fragment.
Modifier and Type | Method and Description |
---|---|
static ControlFlowAnalyzer |
computeInitiallyLive(JProgram jprogram) |
static int |
computeTotalSize(int[] jsLengths)
Computes the "maximum total script size" for one permutation.
|
static void |
exec(TreeLogger logger,
JProgram jprogram,
JsProgram jsprogram,
JavaToJavaScriptMap map,
int expectedFragmentCount,
int minFragmentSize,
MultipleDependencyGraphRecorder dependencyRecorder) |
public static ControlFlowAnalyzer computeInitiallyLive(JProgram jprogram)
public static void exec(TreeLogger logger, JProgram jprogram, JsProgram jsprogram, JavaToJavaScriptMap map, int expectedFragmentCount, int minFragmentSize, MultipleDependencyGraphRecorder dependencyRecorder)
public static int computeTotalSize(int[] jsLengths)
Computes the "maximum total script size" for one permutation. The total script size for one sequence of split points reached is the sum of the scripts that are downloaded for that sequence. The maximum total script size is the maximum such size for all possible sequences of split points.
jsLengths
- The lengths of the fragments for the compilation of one
permutationCopyright © 2018. All rights reserved.