1717 * under the License.
1818 */
1919
20+ import { Stats } from 'fs' ;
21+
2022import { materialize , mergeMap , dematerialize } from 'rxjs/operators' ;
2123import { CiStatsReporter } from '@kbn/dev-utils' ;
24+ import fastGlob , { Entry } from 'fast-glob' ;
2225
2326import { OptimizerUpdate$ } from './run_optimizer' ;
2427import { OptimizerState , OptimizerConfig } from './optimizer' ;
2528import { pipeClosure } from './common' ;
2629
30+ const flatten = < T > ( arr : Array < T | T [ ] > ) : T [ ] =>
31+ arr . reduce ( ( acc : T [ ] , item ) => acc . concat ( item ) , [ ] ) ;
32+
2733export function reportOptimizerStats ( reporter : CiStatsReporter , config : OptimizerConfig ) {
2834 return pipeClosure ( ( update$ : OptimizerUpdate$ ) => {
2935 let lastState : OptimizerState | undefined ;
@@ -36,16 +42,60 @@ export function reportOptimizerStats(reporter: CiStatsReporter, config: Optimize
3642
3743 if ( n . kind === 'C' && lastState ) {
3844 await reporter . metrics (
39- config . bundles . map ( ( bundle ) => {
40- // make the cache read from the cache file since it was likely updated by the worker
41- bundle . cache . refresh ( ) ;
42-
43- return {
44- group : `@kbn/optimizer bundle module count` ,
45- id : bundle . id ,
46- value : bundle . cache . getModuleCount ( ) || 0 ,
47- } ;
48- } )
45+ flatten (
46+ config . bundles . map ( ( bundle ) => {
47+ // make the cache read from the cache file since it was likely updated by the worker
48+ bundle . cache . refresh ( ) ;
49+
50+ const outputFiles = fastGlob . sync ( '**/*' , {
51+ cwd : bundle . outputDir ,
52+ onlyFiles : true ,
53+ unique : true ,
54+ stats : true ,
55+ absolute : false ,
56+ ignore : [ '!**/*.map' ] ,
57+ } ) ;
58+
59+ const entryName = `${ bundle . id } .${ bundle . type } .js` ;
60+ const entry = outputFiles . find ( ( f ) => f . path === entryName ) ;
61+ if ( ! entry ) {
62+ throw new Error (
63+ `Unable to find bundle entry named [${ entryName } ] in [${ bundle . outputDir } ]`
64+ ) ;
65+ }
66+
67+ const chunkPrefix = `${ bundle . id } .chunk.` ;
68+ const asyncChunks = outputFiles . filter ( ( f ) => f . path . startsWith ( chunkPrefix ) ) ;
69+ const miscFiles = outputFiles . filter (
70+ ( f ) => f !== entry && ! asyncChunks . includes ( f )
71+ ) ;
72+ const sumSize = ( files : Entry [ ] ) =>
73+ files . reduce ( ( acc : number , f ) => acc + f . stats ! . size , 0 ) ;
74+
75+ return [
76+ {
77+ group : `@kbn/optimizer bundle module count` ,
78+ id : bundle . id ,
79+ value : bundle . cache . getModuleCount ( ) || 0 ,
80+ } ,
81+ {
82+ group : `page load bundle size` ,
83+ id : bundle . id ,
84+ value : entry . stats ! . size ,
85+ } ,
86+ {
87+ group : `async chunks size` ,
88+ id : bundle . id ,
89+ value : sumSize ( asyncChunks ) ,
90+ } ,
91+ {
92+ group : `miscellaneous assets size` ,
93+ id : bundle . id ,
94+ value : sumSize ( miscFiles ) ,
95+ } ,
96+ ] ;
97+ } )
98+ )
4999 ) ;
50100 }
51101
0 commit comments