@@ -418,15 +418,37 @@ class Post {
418418 toString : true
419419 } , options ) ;
420420 } ) . then ( content => {
421+ // This function restores swig tags in `content` and render them.
422+ if ( disableNunjucks ) {
423+ // If rendering is disabled, do nothing.
424+ return cacheObj . restoreAllSwigTags ( content ) ;
425+ }
426+ // We'd like to render tags concurrently, so we split `content`
427+ // by top-level HTML nodes that have swig tags into `split_content` array
428+ // (nodes that don't have swig tags don't need to be split).
429+ // Then we render items in `split_content` asynchronously.
421430 const doc = parse5 . parseFragment ( content ) ;
422- // Indepedently render the tags in each top-level node
423- // asynchronously. This can significantly speed up rendering of slow tags
424- const results = doc . childNodes . map ( async node => {
425- // Replace cache data with real contents
426- const content = cacheObj . restoreAllSwigTags ( parse5 . serializeOuter ( node ) ) ;
427- // If disabled, return content after replacing the placeholders
428- if ( disableNunjucks ) return content ;
429- // Render with Nunjucks
431+ const split_content = [ ] ;
432+ let current = [ ] ; // Current list of nodes to be added to split_content.
433+ doc . childNodes . forEach ( node => {
434+ const html = parse5 . serializeOuter ( node ) ;
435+ const restored = cacheObj . restoreAllSwigTags ( html ) ;
436+ current . push ( restored ) ;
437+ if ( html !== restored ) {
438+ // Once we encouner a node that has swig tags, merge
439+ // all content we've seen so far and add to `split_content`.
440+ // We don't simply add every node to `split_content`, because
441+ // most nodes don't have swig tags and calling `tag.render` for
442+ // all of them has significant overhead.
443+ split_content . push ( current . join ( '' ) ) ;
444+ current = [ ] ;
445+ }
446+ } ) ;
447+ if ( current . length ) {
448+ split_content . push ( current . join ( '' ) ) ;
449+ }
450+ // Render the tags in each top-level node asynchronously.
451+ const results = split_content . map ( async content => {
430452 return await tag . render ( content , data ) ;
431453 } ) ;
432454 return Promise . all ( results ) . then ( x => x . join ( '' ) ) ;
0 commit comments