-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
121 lines (103 loc) · 3.74 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
const excludeRoutePatterns = [
/wp-content\//,
/wp-includes\//,
/wp-content\//,
];
const allowList = {
styles: [/block-library\/style\.css/],
scripts: [],
}
const preloadList = {
styles: [],
scripts: [],
images: [],
};
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
});
async function handleRequest(request) {
const bypassTransform = Boolean(request.headers.get('x-bypass-transform'));
const byPassRoute = Boolean(request.headers.get('x-bypass-routes')) ? excludeRoutePatterns.some(pattern => pattern.test(request.url)) : false;
if (!bypassTransform && !byPassRoute) {
const response = await fetch(request);
return new HTMLRewriter()
.on('link[rel=stylesheet]', new StylesheetElementHandler())
.on('script[src]', new ScriptElementHandler())
.on('img', new ImageElementHandler())
.on('header.wp-block-template-part .wp-block-image > img', new ImageLcpElementHandler())
.on('head', new HeadElementHandler())
.transform(response);
}
return fetch(request);
}
class StylesheetElementHandler {
element(linkElement) {
const href = linkElement.getAttribute('href');
const bypass = allowList.styles.some(pattern => pattern.test(href));
if (!bypass) {
linkElement.setAttribute('media', 'print');
linkElement.setAttribute('onload', 'this.media=\'all\'');
} else {
if (!preloadList.styles.includes(href)) {
preloadList.styles.push(href);
}
}
}
}
class ScriptElementHandler {
element(scriptElement) {
const src = scriptElement.getAttribute('src');
const bypass = allowList.scripts.some(pattern => pattern.test(src));
if (!bypass) {
scriptElement.setAttribute('async', '');
} else {
if (!preloadList.scripts.includes(src)) {
preloadList.scripts.push(src);
}
}
}
}
class ImageElementHandler {
element(imageElement) {
imageElement.setAttribute('decoding', 'async');
imageElement.setAttribute('loading', 'lazy');
}
}
class ImageLcpElementHandler {
element(ImageLcpElement) {
const src = ImageLcpElement.getAttribute('src');
const srcset = ImageLcpElement.getAttribute('srcset');
const sizes = ImageLcpElement.getAttribute('sizes');
if (!preloadList.images.some(pattern => pattern.href === src)) {
preloadList.images.push({
'href': src,
'imagesrcset': srcset,
'imagesizes': sizes
});
}
ImageLcpElement.removeAttribute('loading');
ImageLcpElement.setAttribute('fetchpriority', 'high');
}
}
class HeadElementHandler {
element(headElement) {
preloadList.styles.map((href) => {
headElement.prepend(`<link rel="preload" href="${href}" as="style">`, {html: true});
});
preloadList.scripts.map((href) => {
headElement.prepend(`<link rel="preload" href="${href}" as="script">`, {html: true});
});
// Issue: on testing, the LCP image was preloaded on other pages even when its no longer available.
preloadList.images.map((e) => {
const attr = [
e.href ? `href="${e.href}"` : '',
e.imagesrcset ? `imagesrcset="${e.imagesrcset}"` : '',
e.imagesizes ? `imagesrcset="${e.imagesizes}"` : ''
];
const htmlAttr = attr.filter(function (el) {
return el !== '';
}).join(' ');
headElement.prepend(`<link fetchpriority="high" rel="preload" as="image" ${htmlAttr}>`, {html: true});
});
}
}