16
16
17
17
import { escapeHTMLAttribute , escapeHTML } from '@isomorphic/stringUtils' ;
18
18
import type { FrameSnapshot , NodeNameAttributesChildNodesSnapshot , NodeSnapshot , RenderedFrameSnapshot , ResourceSnapshot , SubtreeReferenceSnapshot } from '@trace/snapshot' ;
19
+ import type { LRUCache } from './lruCache' ;
19
20
20
21
function isNodeNameAttributesChildNodesSnapshot ( n : NodeSnapshot ) : n is NodeNameAttributesChildNodesSnapshot {
21
22
return Array . isArray ( n ) && typeof n [ 0 ] === 'string' ;
@@ -25,43 +26,17 @@ function isSubtreeReferenceSnapshot(n: NodeSnapshot): n is SubtreeReferenceSnaps
25
26
return Array . isArray ( n ) && Array . isArray ( n [ 0 ] ) ;
26
27
}
27
28
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
-
56
29
export class SnapshotRenderer {
30
+ private _htmlCache : LRUCache < SnapshotRenderer , string > ;
57
31
private _snapshots : FrameSnapshot [ ] ;
58
32
private _index : number ;
59
33
readonly snapshotName : string | undefined ;
60
34
private _resources : ResourceSnapshot [ ] ;
61
35
private _snapshot : FrameSnapshot ;
62
36
private _callId : string ;
63
37
64
- constructor ( resources : ResourceSnapshot [ ] , snapshots : FrameSnapshot [ ] , index : number ) {
38
+ constructor ( htmlCache : LRUCache < SnapshotRenderer , string > , resources : ResourceSnapshot [ ] , snapshots : FrameSnapshot [ ] , index : number ) {
39
+ this . _htmlCache = htmlCache ;
65
40
this . _resources = resources ;
66
41
this . _snapshots = snapshots ;
67
42
this . _index = index ;
@@ -151,16 +126,15 @@ export class SnapshotRenderer {
151
126
} ;
152
127
153
128
const snapshot = this . _snapshot ;
154
- const html = lruCache ( this , ( ) => {
129
+ const html = this . _htmlCache . getOrCompute ( this , ( ) => {
155
130
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.
159
131
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.
161
134
'<style>*,*::before,*::after { visibility: hidden }</style>' ,
162
135
`<script>${ snapshotScript ( this . _callId , this . snapshotName ) } </script>`
163
- ] . join ( '' ) + html ;
136
+ ] . join ( '' ) + result . join ( '' ) ;
137
+ return { value : html , size : html . length } ;
164
138
} ) ;
165
139
166
140
return { html, pageId : snapshot . pageId , frameId : snapshot . frameId , index : this . _index } ;
0 commit comments