Skip to content

Commit

Permalink
avoid parsing of duplicate inline stylesheets see:
Browse files Browse the repository at this point in the history
  • Loading branch information
gildas-lormeau committed Aug 19, 2024
1 parent 6be7fe6 commit 1ffbe62
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 70 deletions.
24 changes: 21 additions & 3 deletions core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,20 @@ class Processor {
}

async resolveStylesheetsURLs() {
const scriptContents = [];
this.options.inlineStylesheets = new Map();
this.options.inlineStylesheetsRefs = new Map();
this.doc.querySelectorAll("style").forEach(element => {
if (element.textContent) {
const indexContent = scriptContents.indexOf(element.textContent);
if (indexContent == -1) {
this.options.inlineStylesheets.set(scriptContents.length, element);
scriptContents.push(element.textContent);
} else {
this.options.inlineStylesheetsRefs.set(element, indexContent);
}
}
});
await Promise.all(Array.from(this.doc.querySelectorAll("style, link[rel*=stylesheet]")).map(async element => {
const options = Object.assign({}, this.options, { charset: this.charset });
let mediaText;
Expand Down Expand Up @@ -1364,9 +1378,11 @@ class Processor {
}

async processStylesheets() {
await Promise.all([...this.stylesheets].map(([, stylesheetInfo]) =>
this.processorHelper.processStylesheet(stylesheetInfo.stylesheet.children, this.baseURI, this.options, this.resources, this.batchRequest)
));
await Promise.all([...this.stylesheets].map(async ([, stylesheetInfo]) => {
if (stylesheetInfo.stylesheet) {
await this.processorHelper.processStylesheet(stylesheetInfo.stylesheet.children, this.baseURI, this.options, this.resources, this.batchRequest);
}
}));
}

async processStyleAttributes() {
Expand Down Expand Up @@ -1457,6 +1473,8 @@ class Processor {

replaceStylesheets() {
this.processorHelper.replaceStylesheets(this.doc, this.stylesheets, this.options, this.resources);
delete this.options.inlineStylesheetsRefs;
delete this.options.inlineStylesheets;
}

replaceStyleAttributes() {
Expand Down
40 changes: 22 additions & 18 deletions core/lib/processor-helper-common.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,31 +402,35 @@ class ProcessorHelperCommon {
const stats = { rules: { processed: 0, discarded: 0 }, fonts: { processed: 0, discarded: 0 } };
let sheetIndex = 0;
stylesheets.forEach(stylesheetInfo => {
const cssRules = stylesheetInfo.stylesheet.children;
if (cssRules) {
stats.rules.processed += cssRules.size;
stats.rules.discarded += cssRules.size;
if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL) {
const mediaFontsDetails = this.createFontsDetailsInfo();
fontsDetails.medias.set("media-" + sheetIndex + "-" + stylesheetInfo.mediaText, mediaFontsDetails);
this.getFontsDetails(doc, cssRules, sheetIndex, mediaFontsDetails);
} else {
this.getFontsDetails(doc, cssRules, sheetIndex, fontsDetails);
if (stylesheetInfo.stylesheet) {
const cssRules = stylesheetInfo.stylesheet.children;
if (cssRules) {
stats.rules.processed += cssRules.size;
stats.rules.discarded += cssRules.size;
if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL) {
const mediaFontsDetails = this.createFontsDetailsInfo();
fontsDetails.medias.set("media-" + sheetIndex + "-" + stylesheetInfo.mediaText, mediaFontsDetails);
this.getFontsDetails(doc, cssRules, sheetIndex, mediaFontsDetails);
} else {
this.getFontsDetails(doc, cssRules, sheetIndex, fontsDetails);
}
}
}
sheetIndex++;
});
processFontDetails(fontsDetails);
await Promise.all([...stylesheets].map(async ([, stylesheetInfo], sheetIndex) => {
const cssRules = stylesheetInfo.stylesheet.children;
const media = stylesheetInfo.mediaText;
if (cssRules) {
if (media && media != MEDIA_ALL) {
await this.processFontFaceRules(cssRules, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + media), fonts, fontTests, stats);
} else {
await this.processFontFaceRules(cssRules, sheetIndex, fontsDetails, fonts, fontTests, stats);
if (stylesheetInfo.stylesheet) {
const cssRules = stylesheetInfo.stylesheet.children;
const media = stylesheetInfo.mediaText;
if (cssRules) {
if (media && media != MEDIA_ALL) {
await this.processFontFaceRules(cssRules, sheetIndex, fontsDetails.medias.get("media-" + sheetIndex + "-" + media), fonts, fontTests, stats);
} else {
await this.processFontFaceRules(cssRules, sheetIndex, fontsDetails, fonts, fontTests, stats);
}
stats.rules.discarded -= cssRules.size;
}
stats.rules.discarded -= cssRules.size;
}
}));
return stats;
Expand Down
42 changes: 25 additions & 17 deletions core/lib/processor-helper-inline.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,25 +83,27 @@ function getProcessorHelperClass(utilInstance) {
async resolveStylesheetElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement) {
let stylesheet;
stylesheets.set(element, stylesheetInfo);
if (!options.blockStylesheets) {
if (element.tagName.toUpperCase() == "LINK") {
stylesheet = await this.resolveLinkStylesheetURLs(element.href, baseURI, options, workStyleElement);
} else {
stylesheet = cssTree.parse(element.textContent, { context: "stylesheet", parseCustomProperty: true });
const importFound = await this.resolveImportURLs(stylesheet, baseURI, options, workStyleElement);
if (importFound) {
stylesheet = cssTree.parse(cssTree.generate(stylesheet), { context: "stylesheet", parseCustomProperty: true });
if (!options.inlineStylesheetsRefs.has(element)) {
if (!options.blockStylesheets) {
if (element.tagName.toUpperCase() == "LINK") {
stylesheet = await this.resolveLinkStylesheetURLs(element.href, baseURI, options, workStyleElement);
} else {
stylesheet = cssTree.parse(element.textContent, { context: "stylesheet", parseCustomProperty: true });
const importFound = await this.resolveImportURLs(stylesheet, baseURI, options, workStyleElement);
if (importFound) {
stylesheet = cssTree.parse(cssTree.generate(stylesheet), { context: "stylesheet", parseCustomProperty: true });
}
}
}
}
if (stylesheet && stylesheet.children) {
if (options.compressCSS) {
this.removeSingleLineCssComments(stylesheet);
if (stylesheet && stylesheet.children) {
if (options.compressCSS) {
this.removeSingleLineCssComments(stylesheet);
}
this.replacePseudoClassDefined(stylesheet);
stylesheetInfo.stylesheet = stylesheet;
} else {
stylesheets.delete(element);
}
this.replacePseudoClassDefined(stylesheet);
stylesheetInfo.stylesheet = stylesheet;
} else {
stylesheets.delete(element);
}
}

Expand All @@ -110,7 +112,13 @@ function getProcessorHelperClass(utilInstance) {
const stylesheetInfo = stylesheets.get(styleElement);
if (stylesheetInfo) {
stylesheets.delete(styleElement);
styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
const styleSheetRefIndex = options.inlineStylesheetsRefs.get(styleElement);
if (styleSheetRefIndex === undefined) {
styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
} else {
const styleElementRef = options.inlineStylesheets.get(styleSheetRefIndex);
styleElement.textContent = styleElementRef.textContent;
}
if (stylesheetInfo.mediaText) {
styleElement.media = stylesheetInfo.mediaText;
}
Expand Down
34 changes: 21 additions & 13 deletions core/lib/processor-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,21 @@ function getProcessorHelperClass(utilInstance) {
}

async resolveStylesheetElement(element, stylesheetInfo, stylesheets, baseURI, options, workStyleElement, resources) {
if (!options.blockStylesheets) {
stylesheets.set({ element }, stylesheetInfo);
if (element.tagName.toUpperCase() == "LINK") {
await this.resolveLinkStylesheetURLs(stylesheetInfo, element, element.href, baseURI, options, workStyleElement, resources, stylesheets);
} else {
stylesheetInfo.stylesheet = cssTree.parse(element.textContent, { context: "stylesheet", parseCustomProperty: true });
await this.resolveImportURLs(stylesheetInfo, baseURI, options, workStyleElement, resources, stylesheets);
}
} else {
if (element.tagName.toUpperCase() == "LINK") {
element.href = util.EMPTY_RESOURCE;
if (!options.inlineStylesheetsRefs.has(element)) {
if (!options.blockStylesheets) {
stylesheets.set({ element }, stylesheetInfo);
if (element.tagName.toUpperCase() == "LINK") {
await this.resolveLinkStylesheetURLs(stylesheetInfo, element, element.href, baseURI, options, workStyleElement, resources, stylesheets);
} else {
stylesheetInfo.stylesheet = cssTree.parse(element.textContent, { context: "stylesheet", parseCustomProperty: true });
await this.resolveImportURLs(stylesheetInfo, baseURI, options, workStyleElement, resources, stylesheets);
}
} else {
element.textContent = "";
if (element.tagName.toUpperCase() == "LINK") {
element.href = util.EMPTY_RESOURCE;
} else {
element.textContent = "";
}
}
}
}
Expand All @@ -112,7 +114,13 @@ function getProcessorHelperClass(utilInstance) {
resources.stylesheets.set(resources.stylesheets.size, { name, stylesheet: stylesheetInfo.stylesheet });
} else {
const styleElement = key.element;
styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
const styleSheetRefIndex = options.inlineStylesheetsRefs.get(styleElement);
if (styleSheetRefIndex === undefined) {
styleElement.textContent = this.generateStylesheetContent(stylesheetInfo.stylesheet, options);
} else {
const styleElementRef = options.inlineStylesheets.get(styleSheetRefIndex);
styleElement.textContent = styleElementRef.textContent;
}
}
}
}
Expand Down
24 changes: 14 additions & 10 deletions modules/css-fonts-minifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ function process(doc, stylesheets, styles, options) {
let docContent = "";
doc.body.appendChild(workStyleElement);
stylesheets.forEach(stylesheetInfo => {
const cssRules = stylesheetInfo.stylesheet.children;
if (cssRules) {
stats.processed += cssRules.size;
stats.discarded += cssRules.size;
getFontsInfo(cssRules, fontsInfo, options);
docContent = getRulesTextContent(doc, cssRules, workStyleElement, docContent);
if (stylesheetInfo.stylesheet) {
const cssRules = stylesheetInfo.stylesheet.children;
if (cssRules) {
stats.processed += cssRules.size;
stats.discarded += cssRules.size;
getFontsInfo(cssRules, fontsInfo, options);
docContent = getRulesTextContent(doc, cssRules, workStyleElement, docContent);
}
}
});
styles.forEach(declarations => {
Expand Down Expand Up @@ -102,10 +104,12 @@ function process(doc, stylesheets, styles, options) {
}
const docChars = Array.from(new Set(docContent)).map(char => char.charCodeAt(0)).sort((value1, value2) => value1 - value2);
stylesheets.forEach(stylesheetInfo => {
const cssRules = stylesheetInfo.stylesheet.children;
if (cssRules) {
filterUnusedFonts(cssRules, fontsInfo.declared, unusedFonts, filteredUsedFonts, docChars);
stats.rules.discarded -= cssRules.size;
if (stylesheetInfo.stylesheet) {
const cssRules = stylesheetInfo.stylesheet.children;
if (cssRules) {
filterUnusedFonts(cssRules, fontsInfo.declared, unusedFonts, filteredUsedFonts, docChars);
stats.rules.discarded -= cssRules.size;
}
}
});
return stats;
Expand Down
2 changes: 1 addition & 1 deletion modules/css-matched-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class MatchedRules {
const workStyleElement = doc.createElement("span");
doc.body.appendChild(workStyleElement);
stylesheets.forEach((stylesheetInfo, key) => {
if (!stylesheetInfo.scoped && !key.urlNode) {
if (!stylesheetInfo.scoped && stylesheetInfo.stylesheet && !key.urlNode) {
const cssRules = stylesheetInfo.stylesheet.children;
if (cssRules) {
if (stylesheetInfo.mediaText && stylesheetInfo.mediaText != MEDIA_ALL) {
Expand Down
16 changes: 9 additions & 7 deletions modules/css-medias-alt-minifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ export {
function process(stylesheets) {
const stats = { processed: 0, discarded: 0 };
stylesheets.forEach((stylesheetInfo, key) => {
if (matchesMediaType(stylesheetInfo.mediaText || MEDIA_ALL) && stylesheetInfo.stylesheet.children) {
const removedRules = processRules(stylesheetInfo.stylesheet.children, stats);
removedRules.forEach(({ cssRules, cssRule }) => cssRules.remove(cssRule));
} else {
stylesheets.delete(key);
if (key.element) {
key.element.remove();
if (stylesheetInfo.stylesheet) {
if (matchesMediaType(stylesheetInfo.mediaText || MEDIA_ALL) && stylesheetInfo.stylesheet.children) {
const removedRules = processRules(stylesheetInfo.stylesheet.children, stats);
removedRules.forEach(({ cssRules, cssRule }) => cssRules.remove(cssRule));
} else {
stylesheets.delete(key);
if (key.element) {
key.element.remove();
}
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion modules/css-rules-minifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function process(stylesheets, styles, mediaAllInfo) {
const stats = { processed: 0, discarded: 0 };
let sheetIndex = 0;
stylesheets.forEach((stylesheetInfo, key) => {
if (!stylesheetInfo.scoped && !key.urlNode) {
if (!stylesheetInfo.scoped && stylesheetInfo.stylesheet && !key.urlNode) {
const cssRules = stylesheetInfo.stylesheet.children;
if (cssRules) {
stats.processed += cssRules.size;
Expand Down

0 comments on commit 1ffbe62

Please sign in to comment.