1616
1717import { escapeHTMLAttribute , escapeHTML } from '@isomorphic/stringUtils' ;
1818import type { FrameSnapshot , NodeNameAttributesChildNodesSnapshot , NodeSnapshot , RenderedFrameSnapshot , ResourceSnapshot , SubtreeReferenceSnapshot } from '@trace/snapshot' ;
19+ import type { LRUCache } from './lruCache' ;
1920
2021function isNodeNameAttributesChildNodesSnapshot ( n : NodeSnapshot ) : n is NodeNameAttributesChildNodesSnapshot {
2122 return Array . isArray ( n ) && typeof n [ 0 ] === 'string' ;
@@ -25,43 +26,17 @@ function isSubtreeReferenceSnapshot(n: NodeSnapshot): n is SubtreeReferenceSnaps
2526 return Array . isArray ( n ) && Array . isArray ( n [ 0 ] ) ;
2627}
2728
28- let cacheSize = 0 ;
29- const cache = new Map < SnapshotRenderer , string > ( ) ;
30- const CACHE_SIZE = 300_000_000 ; // 300mb
31-
32- function lruCache ( key : SnapshotRenderer , compute : ( ) => string ) : string {
33- if ( cache . has ( key ) ) {
34- const value = cache . get ( key ) ! ;
35- // reinserting makes this the least recently used entry
36- cache . delete ( key ) ;
37- cache . set ( key , value ) ;
38- return value ;
39- }
40-
41-
42- const result = compute ( ) ;
43-
44- while ( cache . size && cacheSize + result . length > CACHE_SIZE ) {
45- const [ firstKey , firstValue ] = cache . entries ( ) . next ( ) . value ;
46- cacheSize -= firstValue . length ;
47- cache . delete ( firstKey ) ;
48- }
49-
50- cache . set ( key , result ) ;
51- cacheSize += result . length ;
52-
53- return result ;
54- }
55-
5629export class SnapshotRenderer {
30+ private _htmlCache : LRUCache < SnapshotRenderer , string > ;
5731 private _snapshots : FrameSnapshot [ ] ;
5832 private _index : number ;
5933 readonly snapshotName : string | undefined ;
6034 private _resources : ResourceSnapshot [ ] ;
6135 private _snapshot : FrameSnapshot ;
6236 private _callId : string ;
6337
64- constructor ( resources : ResourceSnapshot [ ] , snapshots : FrameSnapshot [ ] , index : number ) {
38+ constructor ( htmlCache : LRUCache < SnapshotRenderer , string > , resources : ResourceSnapshot [ ] , snapshots : FrameSnapshot [ ] , index : number ) {
39+ this . _htmlCache = htmlCache ;
6540 this . _resources = resources ;
6641 this . _snapshots = snapshots ;
6742 this . _index = index ;
@@ -151,16 +126,15 @@ export class SnapshotRenderer {
151126 } ;
152127
153128 const snapshot = this . _snapshot ;
154- const html = lruCache ( this , ( ) => {
129+ const html = this . _htmlCache . getOrCompute ( this , ( ) => {
155130 visit ( snapshot . html , this . _index , undefined , undefined ) ;
156-
157- const html = result . join ( '' ) ;
158- // Hide the document in order to prevent flickering. We will unhide once script has processed shadow.
159131 const prefix = snapshot . doctype ? `<!DOCTYPE ${ snapshot . doctype } >` : '' ;
160- return prefix + [
132+ const html = prefix + [
133+ // Hide the document in order to prevent flickering. We will unhide once script has processed shadow.
161134 '<style>*,*::before,*::after { visibility: hidden }</style>' ,
162135 `<script>${ snapshotScript ( this . _callId , this . snapshotName ) } </script>`
163- ] . join ( '' ) + html ;
136+ ] . join ( '' ) + result . join ( '' ) ;
137+ return { value : html , size : html . length } ;
164138 } ) ;
165139
166140 return { html, pageId : snapshot . pageId , frameId : snapshot . frameId , index : this . _index } ;
0 commit comments