@divriots/jampack 0.31.1 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config-default.js +6 -0
- package/dist/config-types.d.ts +6 -0
- package/dist/optimize.js +42 -62
- package/dist/optimizers/process-iframe.d.ts +1 -1
- package/dist/optimizers/process-iframe.js +3 -16
- package/dist/optimizers/process-video.d.ts +3 -0
- package/dist/optimizers/process-video.js +29 -0
- package/dist/utils/install-dep.d.ts +1 -0
- package/dist/utils/install-dep.js +15 -0
- package/package.json +1 -1
package/dist/config-default.js
CHANGED
package/dist/config-types.d.ts
CHANGED
package/dist/optimize.js
CHANGED
|
@@ -13,6 +13,7 @@ import { downloadExternalImage } from './optimizers/img-external.js';
|
|
|
13
13
|
import { inlineCriticalCss } from './optimizers/inline-critical-css.js';
|
|
14
14
|
import { prefetch_links_in_viewport } from './optimizers/prefetch-links.js';
|
|
15
15
|
import { processIframe } from './optimizers/process-iframe.js';
|
|
16
|
+
import { processVideo } from './optimizers/process-video.js';
|
|
16
17
|
const UNPIC_DEFAULT_HOST_REGEX = /^https:\/\/n\//g;
|
|
17
18
|
const ABOVE_FOLD_DATA_ATTR = 'data-abovethefold';
|
|
18
19
|
function getIntAttr(img, attr) {
|
|
@@ -33,68 +34,9 @@ async function analyse(state, file) {
|
|
|
33
34
|
return;
|
|
34
35
|
const $ = cheerio.load(html, { sourceCodeLocationInfo: true });
|
|
35
36
|
const theFold = getTheFold($);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
imgsArray.push(imgElement);
|
|
40
|
-
});
|
|
41
|
-
// Process images sequentially
|
|
42
|
-
const spinnerImg = ora({ prefixText: ' ' }).start();
|
|
43
|
-
for (let i = 0; i < imgsArray.length; i++) {
|
|
44
|
-
const imgElement = imgsArray[i];
|
|
45
|
-
spinnerImg.text = kleur.dim(`<img> [${i + 1}/${imgsArray.length}] ${$(imgElement).attr('src')}`);
|
|
46
|
-
const img = $(imgElement);
|
|
47
|
-
const isAboveTheFold = isElementAboveTheFold(img, imgElement, theFold);
|
|
48
|
-
img.removeAttr(ABOVE_FOLD_DATA_ATTR);
|
|
49
|
-
try {
|
|
50
|
-
await processImage(state, file, img, isAboveTheFold);
|
|
51
|
-
}
|
|
52
|
-
catch (e) {
|
|
53
|
-
state.reportIssue(file, {
|
|
54
|
-
type: 'erro',
|
|
55
|
-
msg: e.message ||
|
|
56
|
-
`Unexpected error while processing image: ${JSON.stringify(e)}`,
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// Reset spinner
|
|
61
|
-
spinnerImg.text = kleur.dim(`<img> [${imgsArray.length}/${imgsArray.length}]`);
|
|
62
|
-
// Notify issues
|
|
63
|
-
const issues = state.issues.get(file);
|
|
64
|
-
if (issues) {
|
|
65
|
-
spinnerImg.fail();
|
|
66
|
-
console.log(kleur.red(` ${issues.length} issue${issues.length > 1 ? 's' : ''}`));
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
spinnerImg.succeed();
|
|
70
|
-
}
|
|
71
|
-
const iframes = $('iframe');
|
|
72
|
-
const iframesArray = [];
|
|
73
|
-
iframes.each((index, ifElement) => {
|
|
74
|
-
iframesArray.push(ifElement);
|
|
75
|
-
});
|
|
76
|
-
// Process iframes sequentially
|
|
77
|
-
const spinnerIframe = ora({ prefixText: ' ' }).start();
|
|
78
|
-
for (let i = 0; i < iframesArray.length; i++) {
|
|
79
|
-
const ifElement = iframesArray[i];
|
|
80
|
-
spinnerIframe.text = kleur.dim(`<iframe> [${i + 1}/${iframesArray.length}] ${$(ifElement).attr('src')}`);
|
|
81
|
-
const ifr = $(ifElement);
|
|
82
|
-
const isAboveTheFold = isElementAboveTheFold(ifr, ifElement, theFold);
|
|
83
|
-
ifr.removeAttr(ABOVE_FOLD_DATA_ATTR);
|
|
84
|
-
try {
|
|
85
|
-
await processIframe(state, file, $, ifElement, isAboveTheFold, appendToBody);
|
|
86
|
-
}
|
|
87
|
-
catch (e) {
|
|
88
|
-
state.reportIssue(file, {
|
|
89
|
-
type: 'erro',
|
|
90
|
-
msg: e.message ||
|
|
91
|
-
`Unexpected error while processing image: ${JSON.stringify(e)}`,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
// Reset spinner
|
|
96
|
-
spinnerIframe.text = kleur.dim(`<iframe> [${iframesArray.length}/${iframesArray.length}]`);
|
|
97
|
-
spinnerIframe.succeed();
|
|
37
|
+
await processTag(state, file, $, 'img', 'src', processImage, theFold, appendToBody);
|
|
38
|
+
await processTag(state, file, $, 'iframe', 'src', processIframe, theFold, appendToBody);
|
|
39
|
+
await processTag(state, file, $, 'video', 'src', processVideo, theFold, appendToBody);
|
|
98
40
|
// Remove the fold
|
|
99
41
|
//
|
|
100
42
|
if (theFold) {
|
|
@@ -774,3 +716,41 @@ export async function optimize(state, include, exclude) {
|
|
|
774
716
|
await analyse(state, file);
|
|
775
717
|
}
|
|
776
718
|
}
|
|
719
|
+
async function processTag(state, file, $, tag, attribute_to_log, processor, theFold, appendToBody) {
|
|
720
|
+
const previous_issues = state.issues.get(file);
|
|
721
|
+
const tags = $(tag);
|
|
722
|
+
const tagsArray = [];
|
|
723
|
+
tags.each((index, tagElement) => {
|
|
724
|
+
tagsArray.push(tagElement);
|
|
725
|
+
});
|
|
726
|
+
// Process tags sequentially
|
|
727
|
+
const spinnerImg = ora({ prefixText: ' ' }).start();
|
|
728
|
+
for (let i = 0; i < tagsArray.length; i++) {
|
|
729
|
+
const tagElement = tagsArray[i];
|
|
730
|
+
spinnerImg.text = kleur.dim(`<${tag}> [${i + 1}/${tagsArray.length}] ${$(tagElement).attr(attribute_to_log)}`);
|
|
731
|
+
const el = $(tagElement);
|
|
732
|
+
const isAboveTheFold = isElementAboveTheFold(el, tagElement, theFold);
|
|
733
|
+
el.removeAttr(ABOVE_FOLD_DATA_ATTR);
|
|
734
|
+
try {
|
|
735
|
+
await processor(state, file, el, isAboveTheFold, appendToBody);
|
|
736
|
+
}
|
|
737
|
+
catch (e) {
|
|
738
|
+
state.reportIssue(file, {
|
|
739
|
+
type: 'erro',
|
|
740
|
+
msg: e.message ||
|
|
741
|
+
`Unexpected error while processing ${tag}: ${JSON.stringify(e)}`,
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
// Reset spinner
|
|
746
|
+
spinnerImg.text = kleur.dim(`<${tag}> [${tagsArray.length}/${tagsArray.length}]`);
|
|
747
|
+
// Notify issues
|
|
748
|
+
const issues = state.issues.get(file);
|
|
749
|
+
const newIssues = ((issues === null || issues === void 0 ? void 0 : issues.length) || 0) - ((previous_issues === null || previous_issues === void 0 ? void 0 : previous_issues.length) || 0);
|
|
750
|
+
if (newIssues > 0) {
|
|
751
|
+
spinnerImg.fail();
|
|
752
|
+
}
|
|
753
|
+
else {
|
|
754
|
+
spinnerImg.succeed();
|
|
755
|
+
}
|
|
756
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import * as cheerio from '@divriots/cheerio';
|
|
2
2
|
import type { GlobalState } from '../state.js';
|
|
3
|
-
export declare function processIframe(state: GlobalState, htmlfile: string,
|
|
3
|
+
export declare function processIframe(state: GlobalState, htmlfile: string, iframe: cheerio.Cheerio<cheerio.Element>, isAboveTheFold: boolean, appendToBody: Record<string, string>): Promise<void>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export async function processIframe(state, htmlfile,
|
|
3
|
-
const iframe = $(imgElement);
|
|
1
|
+
import { install_lozad } from '../utils/install-dep.js';
|
|
2
|
+
export async function processIframe(state, htmlfile, iframe, isAboveTheFold, appendToBody) {
|
|
4
3
|
// Reset loading attribute
|
|
5
4
|
iframe.removeAttr('loading');
|
|
6
5
|
const lazyloadOptions = state.options.iframe.lazyload;
|
|
@@ -18,19 +17,7 @@ export async function processIframe(state, htmlfile, $, imgElement, isAboveTheFo
|
|
|
18
17
|
iframe.attr('class', 'jampack-lozad');
|
|
19
18
|
iframe.attr('data-src', src);
|
|
20
19
|
iframe.removeAttr('src');
|
|
21
|
-
await
|
|
22
|
-
source: {
|
|
23
|
-
npm_package_name: 'lozad',
|
|
24
|
-
absolute_path_to_file: '/dist',
|
|
25
|
-
filename: 'lozad.es.js',
|
|
26
|
-
},
|
|
27
|
-
destination: {
|
|
28
|
-
folder_name: 'lozad-1.16',
|
|
29
|
-
code_loader: `import lozad from "./lozad.es.js";
|
|
30
|
-
const observer = lozad('.jampack-lozad', { rootMargin: '100px 0px', threshold: [0.1] });
|
|
31
|
-
observer.observe();`,
|
|
32
|
-
},
|
|
33
|
-
}, appendToBody);
|
|
20
|
+
await install_lozad(state, htmlfile, appendToBody);
|
|
34
21
|
}
|
|
35
22
|
}
|
|
36
23
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import * as cheerio from '@divriots/cheerio';
|
|
2
|
+
import type { GlobalState } from '../state.js';
|
|
3
|
+
export declare function processVideo(state: GlobalState, htmlfile: string, video: cheerio.Cheerio<cheerio.Element>, isAboveTheFold: boolean, appendToBody: Record<string, string>): Promise<void>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { install_lozad } from '../utils/install-dep.js';
|
|
2
|
+
export async function processVideo(state, htmlfile, video, isAboveTheFold, appendToBody) {
|
|
3
|
+
const autoplay = video.attr('autoplay');
|
|
4
|
+
if (!autoplay || autoplay === '0' || autoplay === 'false') {
|
|
5
|
+
// If the video is not autoplay we can postpone loading
|
|
6
|
+
// if there is a poster
|
|
7
|
+
if (video.attr('poster')) {
|
|
8
|
+
video.attr('preload', 'none');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
// TODO create poster for videos without poster
|
|
12
|
+
}
|
|
13
|
+
const lazyloadOptions = state.options.video.autoplay_lazyload;
|
|
14
|
+
if (lazyloadOptions.when === 'never') {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (lazyloadOptions.when === 'always' ||
|
|
18
|
+
(lazyloadOptions.when === 'below-the-fold' && !isAboveTheFold)) {
|
|
19
|
+
if (lazyloadOptions.how === 'js') {
|
|
20
|
+
video.attr('class', 'jampack-lozad');
|
|
21
|
+
const src = video.attr('src');
|
|
22
|
+
if (src) {
|
|
23
|
+
video.attr('data-src', src);
|
|
24
|
+
video.removeAttr('src');
|
|
25
|
+
}
|
|
26
|
+
await install_lozad(state, htmlfile, appendToBody);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -10,3 +10,4 @@ export declare function install_dependency(state: GlobalState, html_file: string
|
|
|
10
10
|
code_loader: string;
|
|
11
11
|
};
|
|
12
12
|
}, appendToBody: Record<string, string>): Promise<void>;
|
|
13
|
+
export declare function install_lozad(state: GlobalState, html_file: string, appendToBody: Record<string, string>): Promise<void>;
|
|
@@ -25,3 +25,18 @@ export async function install_dependency(state, html_file, options, appendToBody
|
|
|
25
25
|
appendToBody[options.source.npm_package_name] = `<script type="module" src="${path.relative(path_html, url_loader)}"></script>`;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
export async function install_lozad(state, html_file, appendToBody) {
|
|
29
|
+
return install_dependency(state, html_file, {
|
|
30
|
+
source: {
|
|
31
|
+
npm_package_name: 'lozad',
|
|
32
|
+
absolute_path_to_file: '/dist',
|
|
33
|
+
filename: 'lozad.es.js',
|
|
34
|
+
},
|
|
35
|
+
destination: {
|
|
36
|
+
folder_name: 'lozad-1.16',
|
|
37
|
+
code_loader: `import lozad from "./lozad.es.js";
|
|
38
|
+
const observer = lozad('.jampack-lozad', { rootMargin: '100px 0px', threshold: [0.1] });
|
|
39
|
+
observer.observe();`,
|
|
40
|
+
},
|
|
41
|
+
}, appendToBody);
|
|
42
|
+
}
|