-
Notifications
You must be signed in to change notification settings - Fork 417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add ignored and excluded classes to critical CSS extraction in collect
#1102
Conversation
🦋 Changeset detectedLatest commit: c56fd5f The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good to me.
Could you please run pnpm changeset
and describe your changes?
collect
collect
5b4ac2a
to
cedc548
Compare
@Anber added! Thanks for the review 🙂 |
packages/server/src/collect.ts
Outdated
// eslint-disable-next-line no-plusplus | ||
removedNodesFromOther++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can avoid disabling eslint here like this:
// eslint-disable-next-line no-plusplus | |
removedNodesFromOther++; | |
removedNodesFromOther += 1; |
packages/server/src/collect.ts
Outdated
const animations = new Set(); | ||
const other = postcss.root(); | ||
const critical = postcss.root(); | ||
const stylesheet = postcss.parse(css); | ||
const htmlClassesRegExp = extractClassesFromHtml(html); | ||
const htmlClassesRegExp = extractClassesFromHtml(html, ignoredClasses); | ||
const excludedClassesRegExp = new RegExp(excludedClasses.join('|'), 'gm'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a good idea to escape the excludedClasses array for special regex characters.
packages/server/src/collect.ts
Outdated
@@ -22,48 +25,68 @@ const extractClassesFromHtml = (html: string): RegExp => { | |||
/\\|\^|\$|\{|\}|\[|\]|\(|\)|\.|\*|\+|\?|\|/g, | |||
'\\$&' | |||
); | |||
htmlClasses.push(className); | |||
if (className !== '' && !ignoredClasses.includes(className)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is run in a couple of loops, it might not be a bad idea to convert ignoredClasses
to a Set outside of the loops for performance.
cedc548
to
34b48be
Compare
@lencioni I think I addressed your comments, mind taking another look? |
packages/server/src/collect.ts
Outdated
function escapeRegex(string: string) { | ||
return string.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about the regex here. Did you write this by hand or pull it from somewhere?
It might be worth borrowing lodash's implementation. https://github.com/lodash/lodash/blob/4.17.11/lodash.js#L14259-L14279
Here's their regex, which looks a little bit different than the one in this PR: https://github.com/lodash/lodash/blob/4.17.11/lodash.js#L152
Their code comment points to https://262.ecma-international.org/7.0/#sec-patterns as the data source for this list of characters (though that inline link didn't work for me maybe it is supposed to be this one? https://262.ecma-international.org/7.0/#sec-regular-expressions-patterns)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you consider also not using regex to do the string matching, and just doing string searching? (ie, indexOf
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not quite following what the string searching would look like? Won't we still have to call string.replace
to sanitize it?
re: the regex, I pulled it from somewhere, but happy to replace it with the one from lodash.
packages/server/src/collect.ts
Outdated
html: string, | ||
css: string, | ||
ignoredClasses: string[] = [], | ||
excludedClasses: string[] = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be an object of options, if we were to add more? ie
collect(
html: string,
css: string,
{ ignoredClasses, excludedClass }: { ignoredClasses?: string[], excludedClasses?: string[] }
)
packages/server/src/collect.ts
Outdated
html: string, | ||
css: string, | ||
ignoredClasses: string[] = [], | ||
excludedClasses: string[] = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For naming, to me, ignored
and excluded
are synonyms, so I have a hard time remembering which one is doing which. Is there some other name I'm not thinking of that would help clarify what these do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree the naming for this is tricky. What do you think about ignoredClasses
and blockedClasses
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's about this thread? Are you going to change names or I can merge this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay, I changed the param names and this should be good to go now!
34b48be
to
c56fd5f
Compare
Motivation
Our codebase uses the postcss-rtlcss package to add
.dir-ltr
,.dir-rtl
, or.dir
prefixes to our CSS selectors, so that most of them are in the following format:Since our HTML contains the
dir-ltr
class, when we use Linaria'scollect
function, a lot of unnecessary selectors are added to the critical CSS even thoughotherClassname
is not present.Also, we have media queries in this format:
We want to specifically exclude the RTL selector when the direction is LTR and vice versa.
Summary
This PR proposes to add an opt-in
ignoredClasses
parameter tocollect
so that we can ignoredir-ltr
,dir-rtl
, anddir
from the regex used to determine critical CSS styles when it is present in the HTML.Also, the
excludedClasses
parameter will allowdir-rtl
to be excluded, so that even ifotherClassname
is in the HTML, the.dir-rtl.otherClassname
selector will not be critical.Test plan
Tested with unit tests for the new parameters to the
collect
function.