@@ -66,6 +66,7 @@ type CreateBrowserZipBuilderOptions = {
6666type ZipCompressionController = {
6767 trackAsyncCompression : boolean ;
6868 beginAsyncCompression : ( assetSize : number ) => ( ) => void ;
69+ finalize : ( ) => void ;
6970 recordSyncCompression : ( assetSize : number , durationMs : number ) => void ;
7071 shouldUseAsyncCompression : ( assetSize : number ) => boolean ;
7172} ;
@@ -157,6 +158,7 @@ function createStaticZipCompressionController(
157158 return {
158159 trackAsyncCompression : false ,
159160 beginAsyncCompression : ( ) => ( ) => undefined ,
161+ finalize : ( ) => undefined ,
160162 recordSyncCompression : ( ) => undefined ,
161163 shouldUseAsyncCompression : ( assetSize ) => assetSize >= asyncSizeThreshold ,
162164 } ;
@@ -177,15 +179,30 @@ function createAdaptiveZipCompressionController({
177179 maxAsyncJobs,
178180 memorySoftLimit,
179181} : AdaptiveZipCompressionPolicy ) : ZipCompressionController {
182+ const shouldLogDiagnostics = IS_CI ;
183+ const fallbackCounts = {
184+ belowThreshold : 0 ,
185+ maxAsyncBytes : 0 ,
186+ maxAsyncJobs : 0 ,
187+ memorySoftLimit : 0 ,
188+ } ;
180189 let asyncSizeThreshold = initialAsyncSizeThreshold ;
181190 let inflightAsyncJobs = 0 ;
182191 let inflightAsyncBytes = 0 ;
183192 let syncSamples = 0 ;
184193 let asyncSamples = 0 ;
185194 let syncThroughput = 0 ;
186195 let asyncThroughput = 0 ;
196+ let retuneCount = 0 ;
187197 let lastRssSampleAt = - Infinity ;
188198 let cachedRss = 0 ;
199+ let didLogSummary = false ;
200+
201+ if ( shouldLogDiagnostics ) {
202+ console . log (
203+ `[zip-adaptive] start threshold_kib=${ toKiB ( asyncSizeThreshold ) } max_async_jobs=${ maxAsyncJobs } max_async_bytes=${ maxAsyncBytes } memory_soft_limit=${ memorySoftLimit } ` ,
204+ ) ;
205+ }
189206
190207 function beginAsyncCompression ( assetSize : number ) : ( ) => void {
191208 inflightAsyncJobs += 1 ;
@@ -213,6 +230,17 @@ function createAdaptiveZipCompressionController({
213230 } ;
214231 }
215232
233+ function finalize ( ) : void {
234+ if ( ! shouldLogDiagnostics || didLogSummary ) {
235+ return ;
236+ }
237+
238+ didLogSummary = true ;
239+ console . log (
240+ `[zip-adaptive] summary final_threshold_kib=${ toKiB ( asyncSizeThreshold ) } sync_samples=${ syncSamples } async_samples=${ asyncSamples } retunes=${ retuneCount } below_threshold=${ fallbackCounts . belowThreshold } max_jobs=${ fallbackCounts . maxAsyncJobs } max_async_bytes=${ fallbackCounts . maxAsyncBytes } memory_soft_limit_hits=${ fallbackCounts . memorySoftLimit } ` ,
241+ ) ;
242+ }
243+
216244 function recordSyncCompression ( assetSize : number , durationMs : number ) : void {
217245 syncSamples += 1 ;
218246 syncThroughput = updateAverageThroughput (
@@ -226,12 +254,27 @@ function createAdaptiveZipCompressionController({
226254
227255 function shouldUseAsyncCompression ( assetSize : number ) : boolean {
228256 const rss = getRss ( ) ;
229- return (
230- assetSize >= asyncSizeThreshold &&
231- inflightAsyncJobs < maxAsyncJobs &&
232- inflightAsyncBytes + assetSize <= maxAsyncBytes &&
233- rss + inflightAsyncBytes + assetSize <= memorySoftLimit
234- ) ;
257+ if ( assetSize < asyncSizeThreshold ) {
258+ fallbackCounts . belowThreshold += 1 ;
259+ return false ;
260+ }
261+
262+ if ( inflightAsyncJobs >= maxAsyncJobs ) {
263+ fallbackCounts . maxAsyncJobs += 1 ;
264+ return false ;
265+ }
266+
267+ if ( inflightAsyncBytes + assetSize > maxAsyncBytes ) {
268+ fallbackCounts . maxAsyncBytes += 1 ;
269+ return false ;
270+ }
271+
272+ if ( rss + inflightAsyncBytes + assetSize > memorySoftLimit ) {
273+ fallbackCounts . memorySoftLimit += 1 ;
274+ return false ;
275+ }
276+
277+ return true ;
235278 }
236279
237280 function retuneAsyncThreshold ( ) : void {
@@ -245,17 +288,33 @@ function createAdaptiveZipCompressionController({
245288 inflightAsyncJobs >= maxAsyncJobs ||
246289 inflightAsyncBytes >= maxAsyncBytes * 0.75 ||
247290 getRss ( ) >= memorySoftLimit ;
291+ const previousAsyncSizeThreshold = asyncSizeThreshold ;
292+ let retuneReason : 'async_better' | 'sync_better' | 'under_pressure' | null =
293+ null ;
248294
249295 if ( syncIsClearlyBetter || underPressure ) {
250296 asyncSizeThreshold = Math . min (
251297 MAX_ASYNC_COMPRESSION_SIZE ,
252298 Math . floor ( asyncSizeThreshold * 1.5 ) ,
253299 ) ;
300+ retuneReason = underPressure ? 'under_pressure' : 'sync_better' ;
254301 } else if ( asyncIsClearlyBetter ) {
255302 asyncSizeThreshold = Math . max (
256303 MIN_ASYNC_COMPRESSION_SIZE ,
257304 Math . floor ( asyncSizeThreshold / 1.25 ) ,
258305 ) ;
306+ retuneReason = 'async_better' ;
307+ }
308+
309+ if (
310+ shouldLogDiagnostics &&
311+ retuneReason &&
312+ asyncSizeThreshold !== previousAsyncSizeThreshold
313+ ) {
314+ retuneCount += 1 ;
315+ console . log (
316+ `[zip-adaptive] retune from_kib=${ toKiB ( previousAsyncSizeThreshold ) } to_kib=${ toKiB ( asyncSizeThreshold ) } reason=${ retuneReason } sync_throughput=${ Math . round ( syncThroughput ) } async_throughput=${ Math . round ( asyncThroughput ) } inflight_jobs=${ inflightAsyncJobs } inflight_async_bytes=${ inflightAsyncBytes } ` ,
317+ ) ;
259318 }
260319 }
261320
@@ -272,6 +331,7 @@ function createAdaptiveZipCompressionController({
272331 return {
273332 trackAsyncCompression : true ,
274333 beginAsyncCompression,
334+ finalize,
275335 recordSyncCompression,
276336 shouldUseAsyncCompression,
277337 } ;
@@ -473,3 +533,7 @@ function updateAverageThroughput(
473533 : currentAverage * ( 1 - THROUGHPUT_SMOOTHING_FACTOR ) +
474534 throughput * THROUGHPUT_SMOOTHING_FACTOR ;
475535}
536+
537+ function toKiB ( bytes : number ) : number {
538+ return Math . round ( bytes / KiB ) ;
539+ }
0 commit comments