@@ -13,24 +13,9 @@ type postProcessOptions = {
13
13
type renderOptions = {
14
14
getFontDefinition ?: ( url : string ) => string
15
15
}
16
-
17
- type PostProcessData = {
18
- preloads : {
19
- images : Array < string >
20
- }
21
- }
22
-
23
16
interface PostProcessMiddleware {
24
- inspect : (
25
- originalDom : HTMLElement ,
26
- data : PostProcessData ,
27
- options : renderOptions
28
- ) => void
29
- mutate : (
30
- markup : string ,
31
- data : PostProcessData ,
32
- options : renderOptions
33
- ) => Promise < string >
17
+ inspect : ( originalDom : HTMLElement , options : renderOptions ) => any
18
+ mutate : ( markup : string , data : any , options : renderOptions ) => Promise < string >
34
19
}
35
20
36
21
type middlewareSignature = {
@@ -58,18 +43,13 @@ async function processHTML(
58
43
if ( ! middlewareRegistry [ 0 ] ) {
59
44
return html
60
45
}
61
- const postProcessData : PostProcessData = {
62
- preloads : {
63
- images : [ ] ,
64
- } ,
65
- }
66
46
const root : HTMLElement = parse ( html )
67
47
let document = html
68
48
// Calls the middleware, with some instrumentation and logging
69
49
async function callMiddleWare ( middleware : PostProcessMiddleware ) {
70
50
// let timer = Date.now()
71
- middleware . inspect ( root , postProcessData , data )
72
- document = await middleware . mutate ( document , postProcessData , data )
51
+ const inspectData = middleware . inspect ( root , data )
52
+ document = await middleware . mutate ( document , inspectData , data )
73
53
// timer = Date.now() - timer
74
54
// if (timer > MIDDLEWARE_TIME_BUDGET) {
75
55
// TODO: Identify a correct upper limit for the postprocess step
@@ -89,15 +69,11 @@ async function processHTML(
89
69
}
90
70
91
71
class FontOptimizerMiddleware implements PostProcessMiddleware {
92
- fontDefinitions : ( string | undefined ) [ ] [ ] = [ ]
93
- inspect (
94
- originalDom : HTMLElement ,
95
- _data : PostProcessData ,
96
- options : renderOptions
97
- ) {
72
+ inspect ( originalDom : HTMLElement , options : renderOptions ) {
98
73
if ( ! options . getFontDefinition ) {
99
74
return
100
75
}
76
+ const fontDefinitions : ( string | undefined ) [ ] [ ] = [ ]
101
77
// collecting all the requested font definitions
102
78
originalDom
103
79
. querySelectorAll ( 'link' )
@@ -115,30 +91,35 @@ class FontOptimizerMiddleware implements PostProcessMiddleware {
115
91
const nonce = element . getAttribute ( 'nonce' )
116
92
117
93
if ( url ) {
118
- this . fontDefinitions . push ( [ url , nonce ] )
94
+ fontDefinitions . push ( [ url , nonce ] )
119
95
}
120
96
} )
97
+
98
+ return fontDefinitions
121
99
}
122
100
mutate = async (
123
101
markup : string ,
124
- _data : PostProcessData ,
102
+ fontDefinitions : string [ ] [ ] ,
125
103
options : renderOptions
126
104
) => {
127
105
let result = markup
128
106
if ( ! options . getFontDefinition ) {
129
107
return markup
130
108
}
131
- for ( const key in this . fontDefinitions ) {
132
- const [ url , nonce ] = this . fontDefinitions [ key ]
109
+
110
+ fontDefinitions . forEach ( ( fontDef ) => {
111
+ const [ url , nonce ] = fontDef
133
112
const fallBackLinkTag = `<link rel="stylesheet" href="${ url } "/>`
134
113
if (
135
114
result . indexOf ( `<style data-href="${ url } ">` ) > - 1 ||
136
115
result . indexOf ( fallBackLinkTag ) > - 1
137
116
) {
138
117
// The font is already optimized and probably the response is cached
139
- continue
118
+ return
140
119
}
141
- const fontContent = options . getFontDefinition ( url as string )
120
+ const fontContent = options . getFontDefinition
121
+ ? options . getFontDefinition ( url as string )
122
+ : null
142
123
if ( ! fontContent ) {
143
124
/**
144
125
* In case of unreachable font definitions, fallback to default link tag.
@@ -151,13 +132,15 @@ class FontOptimizerMiddleware implements PostProcessMiddleware {
151
132
`<style data-href="${ url } "${ nonceStr } >${ fontContent } </style></head>`
152
133
)
153
134
}
154
- }
135
+ } )
136
+
155
137
return result
156
138
}
157
139
}
158
140
159
141
class ImageOptimizerMiddleware implements PostProcessMiddleware {
160
- inspect ( originalDom : HTMLElement , _data : PostProcessData ) {
142
+ inspect ( originalDom : HTMLElement ) {
143
+ const imgPreloads = [ ]
161
144
const imgElements = originalDom . querySelectorAll ( 'img' )
162
145
let eligibleImages : Array < HTMLElement > = [ ]
163
146
for ( let i = 0 ; i < imgElements . length ; i ++ ) {
@@ -169,18 +152,18 @@ class ImageOptimizerMiddleware implements PostProcessMiddleware {
169
152
}
170
153
}
171
154
172
- _data . preloads . images = [ ]
173
-
174
155
for ( const imgEl of eligibleImages ) {
175
156
const src = imgEl . getAttribute ( 'src' )
176
157
if ( src ) {
177
- _data . preloads . images . push ( src )
158
+ imgPreloads . push ( src )
178
159
}
179
160
}
161
+
162
+ return imgPreloads
180
163
}
181
- mutate = async ( markup : string , _data : PostProcessData ) => {
164
+ mutate = async ( markup : string , imgPreloads : string [ ] ) => {
182
165
let result = markup
183
- let imagePreloadTags = _data . preloads . images
166
+ let imagePreloadTags = imgPreloads
184
167
. filter ( ( imgHref ) => ! preloadTagAlreadyExists ( markup , imgHref ) )
185
168
. reduce (
186
169
( acc , imgHref ) =>
0 commit comments