-
Notifications
You must be signed in to change notification settings - Fork 383
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
Remove empty media queries #1423
Remove empty media queries #1423
Conversation
516a3fc
to
4c8753d
Compare
Thank you for working on this. It's something I saw as needing to be done but I haven't yet actioned on it. Instead of removing the empty You could check if span:before {
content:"@media foo {}"
} This would currently cause the string content to be stripped out. Sure it's an unlikely thing to happen, but it seems better. Please also add unit tests to verify that the empty rules are being removed. |
I can see that my proposal won't work as is because the
The last example is particularly tricky, since it contains the trailing |
63d88c2
to
83e4b59
Compare
…moving content property values
…ltiple media queries including query inside content property
Thank you for the comments! span:before {
content:"@media foo {}"
} Your idea of improving by splitting the stylesheet seems very interesting, it needs profound investigation though, and we are researching it right now. We’ll need some time to finish it, and it’s hard to make a timing forecast at this point. Do you think that our pull request could be approved in its current version? And as soon as we are done with the stylesheet splitting idea we’ll create another pull request for your review. |
Happy to help. Thank you for contributing. What about this example: span:before {
content:"this is a media query: @media foo {}"
} The regex would incorrectly remove it here, wouldn't it? It's true that this is probably very unusual.
I'm pretty familiar with the CSS parser so I'll see if I can improve the splitting logic to make it easier to deal with instead of using regular expression replacements on the entire stylesheet. |
@korobochkin there, I've updated the PHP-CSS-Parser to make sure that the stylesheet strings get split before and after CSS at rules. After doing |
So after running PHP Unit tests in Travis, we get 5 errors. However, if we run tests locally we get 11 errors instead of 5. We tried running PHP unit tests only and added Can you point us in the right direction with those 5 errors? |
@korobochkin sorry for the delay. I flushed the Travis build caches and the tests pass now. The old version of PHP-CSS-Parser was probably in the cache. But the tests are passing on Travis, but you have 5 failing locally? |
…on of removing empty media query mechanism.
@westonruter Thank for the help with Travis tests. However, we have some difficulties with handling the CSS that comes from parsing. The problem is with the inconsistent handling of the rules that contain the The idea behind removing the empty media queries is to first look if there is any CSS inside and only merge them if this is true. Rules that contain Ideally, we'd like to see the beginning of each rule that contains @media screen and (min-width: 900px) {
.foo { color: red; }
@supports (color: red) {
.foo { color: blue }
}
@font-face {
font-family: dashicons;
src: url(../fonts/dashicons.eot);
}
}
@font-face {
font-family: dashicons;
src: url(../fonts/dashicons.eot);
}
@media screen and (min-width: 900px) {
@counter-style foobar {
system: cyclic;
symbols: "•";
suffix: " ";
}
}
@supports not (color: red) {
.foo { color: red; }
@media screen and (min-width: 900px) {
.foo { color: red; }
}
}
@supports (color: red) {
@font-face {
font-family: FooBar;
src: local("FooBar");
}
}
@supports (color: red) {
@media screen and (min-width: 900px) {
@font-face {
font-family: FooBar;
src: local("FooBar");
}
}
}
@supports (color: red) {
@media screen and (min-width: 900px) {
.foo { color: red; }
}
.foo { color: red; }
@keyframes foobar {
from { color: red; }
to { color: blue; }
}
}
@supports (color: red) {
@font-feature-values FooBar {
@bar {
swishy: 1;
flowing: 2;
}
}
} And this is how this CSS was parsed. array (
0 => '',
1 => '@media screen and (min-width: 900px){',
2 => array (...),
3 => '',
4 => '@supports (color: red){',
5 => array (...),
6 => '}', // We'd like to see '}' as a separate element
7 => '@font-face{font-family:dashicons;src:url("../fonts/dashicons.eot")}}', // closing '}' should not be with @font-face
8 => '@font-face{font-family:dashicons;src:url("../fonts/dashicons.eot")}',
9 => '@media screen and (min-width: 900px){}', // empty @media in the single element with closing '}'
10 => '',
11 => '@supports not (color: red){',
12 => array (...),
13 => '',
14 => '@media screen and (min-width: 900px){',
15 => array (...),
16 => '}',
17 => '}',
18 => '',
19 => '@supports (color: red){@font-face{font-family:FooBar;src:local("FooBar")}}',
20 => '',
21 => '@supports (color: red){',
22 => '@media screen and (min-width: 900px){@font-face{font-family:FooBar;src:local("FooBar")}}',
23 => '}',
24 => '',
25 => '@supports (color: red){',
26 => '@media screen and (min-width: 900px){',
27 => array (),
28 => '}',
29 => '',
30 => array (),
31 => '@keyframes foobar{',
32 => 'from{color:red}',
33 => '',
34 => 'to{color:blue}',
35 => '}}', // @supports and @media are closed in the same element
36 => '',
37 => '@supports (color: red){}',
38 => '',
); |
@westonruter We are still thinking how to solve the problem with the tests and we would like to hear your opinion. |
Hi, @westonruter |
Sorry for the delay on my feedback. I'm going to be pressed for time the next few weeks. I'm planning to return to this mid-November. |
@westonruter Hi! I would like to know about the progress of release 1.0 and do you have any news about our pull request? And happy Thanksgiving! |
This is near the top of my list to revisit now after the holidays. The 1.0 release is currently scheduled for December 6th (which has shifted in part due to the WordPress 5.0 release date changes). |
Surprisingly, this ends up saving ~4KB in Twenty Nineteen's styles (8% of 50KB budget). These are the empty rules that get stripped: https://gist.github.com/westonruter/629f4b52e38db0c4b0ffc89e1b4d1b75 |
@korobochkin Please give this a try. Make sure that your |
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.
Ship it!
Thank you for your attention and work on this PR! We tested this updated version of code on few sites and it works as expected. 👍 |
After removal of the irrelevant CSS rules for the page, sometimes there are empty media queries left in the resulting page. In some cases those code bits may result in extra 4-5 KB of extra code that can be safely removed without any harm to page appearance.
For example, this code:
After tree shaking transforms into this:
Since the selector inside this media query does not correspond to any elements on current page, we are left with empty query, that could be safely removed
To implement this we made changes in
includes/sanitizers/class-amp-style-sanitizer.php
.As far as
@media
query is added on lines 2028-2031 we decided to add one more function which removes all empty media queries withpreg_replace()
. This happens after the final$stylesheet
is concatenated from the small parts, but before these stylesheets size is calculated.