@@ -88,6 +88,9 @@ class ConcatSource extends Source {
8888 }
8989 }
9090
91+ /**
92+ * @returns {Buffer } buffer
93+ */
9194 buffer ( ) {
9295 return Buffer . concat ( this . buffers ( ) ) ;
9396 }
@@ -97,12 +100,19 @@ class ConcatSource extends Source {
97100 */
98101 buffers ( ) {
99102 if ( ! this . _isOptimized ) this . _optimize ( ) ;
103+ const children = /** @type {SourceLike[] } */ ( this . _children ) ;
104+ const childCount = children . length ;
100105 /** @type {Buffer[] } */
101106 const buffers = [ ] ;
102- for ( const child of /** @type {SourceLike[] } */ ( this . _children ) ) {
107+ // Indexed loop + manual splat avoids the iterator allocation per
108+ // child and the inner for-of allocation per child.buffers() call.
109+ // Hot path during webpack's emit on deeply-nested ConcatSources.
110+ for ( let ci = 0 ; ci < childCount ; ci ++ ) {
111+ const child = children [ ci ] ;
103112 if ( typeof child . buffers === "function" ) {
104- for ( const buffer of child . buffers ( ) ) {
105- buffers . push ( buffer ) ;
113+ const childBuffers = child . buffers ( ) ;
114+ for ( let bi = 0 , blen = childBuffers . length ; bi < blen ; bi ++ ) {
115+ buffers . push ( childBuffers [ bi ] ) ;
106116 }
107117 } else if ( typeof child . buffer === "function" ) {
108118 buffers . push ( child . buffer ( ) ) ;
@@ -124,18 +134,25 @@ class ConcatSource extends Source {
124134 */
125135 source ( ) {
126136 if ( ! this . _isOptimized ) this . _optimize ( ) ;
137+ const children = /** @type {Source[] } */ ( this . _children ) ;
138+ const childCount = children . length ;
127139 let source = "" ;
128- for ( const child of this . _children ) {
129- source += /** @type { Source } */ ( child ) . source ( ) ;
140+ for ( let ci = 0 ; ci < childCount ; ci ++ ) {
141+ source += children [ ci ] . source ( ) ;
130142 }
131143 return source ;
132144 }
133145
146+ /**
147+ * @returns {number } size
148+ */
134149 size ( ) {
135150 if ( ! this . _isOptimized ) this . _optimize ( ) ;
151+ const children = /** @type {Source[] } */ ( this . _children ) ;
152+ const childCount = children . length ;
136153 let size = 0 ;
137- for ( const child of this . _children ) {
138- size += /** @type { Source } */ ( child ) . size ( ) ;
154+ for ( let ci = 0 ; ci < childCount ; ci ++ ) {
155+ size += children [ ci ] . size ( ) ;
139156 }
140157 return size ;
141158 }
@@ -308,10 +325,11 @@ class ConcatSource extends Source {
308325 */
309326 updateHash ( hash ) {
310327 if ( ! this . _isOptimized ) this . _optimize ( ) ;
328+ const children = /** @type {Source[] } */ ( this . _children ) ;
329+ const childCount = children . length ;
311330 hash . update ( "ConcatSource" ) ;
312- for ( const item of this . _children ) {
313- /** @type {Source } */
314- ( item ) . updateHash ( hash ) ;
331+ for ( let ci = 0 ; ci < childCount ; ci ++ ) {
332+ children [ ci ] . updateHash ( hash ) ;
315333 }
316334 }
317335
0 commit comments