-
Notifications
You must be signed in to change notification settings - Fork 9.4k
CSS file is deferred when CSS element has defer attribute in default_head_blocks.xml. #37814
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
base: 2.4-develop
Are you sure you want to change the base?
Conversation
…ement in default_head_blocks.xml.
Hi @nurullah. Thank you for your contribution! Add the comment under your pull request to deploy test or vanilla Magento instance:
❗ Automated tests can be triggered manually with an appropriate comment:
Allowed build names are:
You can find more information about the builds here For more details, review the Code Contributions documentation. |
Seem good fix inmy opinion. Can you able to add some automate test cover new changes |
lib/internal/Magento/Framework/View/Test/Unit/Page/Config/RendererTest.php |
* @return string | ||
*/ | ||
protected function getAssetTemplate($contentType, $attributes) | ||
{ | ||
$attributesString = ''; | ||
foreach ($attributes as $name => $value) { | ||
$attributesString .= ' ' . $name . '="' . $this->escaper->escapeHtml($value) . '"'; |
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.
Should be escapeHtmlAttr
instead of escapeHtml
I think?
And in the case of the onload
one, it should be escapeJs
inside a escapeHtmlAttr
according to the docs:
Case: All JavaScript inside attributes must be escaped by escapeJs before escapeHtmlAttr:
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.
The escapeHtmlAttr
function escapes slash character and it looks like the below;
It's pretty useful for body element attributes but not for head element attributes. Also, before this pull request, the same escapeHtml
function was used for the attribute value.
magento2/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
Lines 332 to 334 in 0a834cc
foreach ($attributes as $name => $value) { | |
$attributesString .= ' ' . $name . '="' . $this->escaper->escapeHtml($value) . '"'; | |
} |
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.
Thanks for the feedback! I know too little about this, would be great if somebody with a little bit of security knowledge could double check this here then.
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.
@nathanjosiah: if you have a little bit of time, do you have some input here?
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.
If the main issue is that escapeHtmlAttr escaped all chars then that is correct behavior even for head.
For example:
<html>
<head>
<style id="foo/bar"></style>
</head>
<body>
Test succeeds if this is green
<script>document.getElementById('foo/bar').innerHTML = 'body { color: green; }';</script>
</body>
</html>
The text would be green.
Here is a small demo that shows this off.
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.
escapeHtmlAttr
is appropriate for all attributes including script attributes. You would only need to combine escapeJs
with escapeHtmlAttr
if there is additional content being injected into the JS. For example from our devdocs
<div
onclick="<?= $escaper->escapeHtmlAttr('handler("' . $escaper->escapeJs($aString) . '", ' . $escaper->escapeJs($aVar) .')') ?>">
My DIV
</div>
As far as I can see, this PR is using the escaper methods correctly.
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.
Looks like this PR is still waiting for your review @hostep. If there are no other problems, can you take this to the next step? Thanks.
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 don't have a lot of expert knowledge on the subject but since somebody forced me to review this (I wasn't able to unassign myself), I approved it anyways.
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.
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.
@sky-hub: and how is that a problem? A browser should be able to decode those without an issue. It's like writing >
or <
in the html source to display >
or <
. In this case /
translates to /
for example. It's redundant and will increase the payload size a bit sure, but it shouldn't break anything.
I added unit test for defer attribute. @magento run Unit Tests |
The requested builds are added to the queue. You should be able to see them here within a few minutes. Please message the #magento-devops slack channel if they don't show in a reasonable amount of time and a representative will look into any issues. |
I opened the unit tests report but I didn't see any error. All 3 reports detail shows RendererTest.php passed the test. But unit tests failed surprisingly. So, I restart the unit test. @magento run Unit Tests |
@magento run all tests |
The requested builds are added to the queue. You should be able to see them here within a few minutes. Please message the #magento-devops slack channel if they don't show in a reasonable amount of time and a representative will look into any issues. |
@magento run all Unit Tests, Functional Tests |
Failed to run the builds. Please try to re-run them later. |
@magento run all Unit Tests, Static Tests |
The requested builds are added to the queue. You should be able to see them here within a few minutes. Please message the #magento-devops slack channel if they don't show in a reasonable amount of time and a representative will look into any issues. |
@magento run all Unit Tests |
Failed to run the builds. Please try to re-run them later. |
@magento run all tests |
The requested builds are added to the queue. You should be able to see them here within a few minutes. Please message the #magento-devops slack channel if they don't show in a reasonable amount of time and a representative will look into any issues. |
@magento run Functional Tests CE, Functional Tests EE, Functional Tests B2B |
The requested builds are added to the queue. You should be able to see them here within a few minutes. Please message the #magento-devops slack channel if they don't show in a reasonable amount of time and a representative will look into any issues. |
@magento run all tests |
The requested builds are added to the queue. You should be able to see them here within a few minutes. Please message the #magento-devops slack channel if they don't show in a reasonable amount of time and a representative will look into any issues. |
Description (*)
While I searching for ways to defer non-critical CSS files, I found that magento2 has a
defer
attribute in the head.xsd file. This means I can write the following code in thedefault_head_blocks.xml
without any errors.But I realized that this
defer
attribute has no effect on the CSS element. Because HTML link element doesn't havedefer
attribute. It only works with the<script>
element. This pull request aims to provide defer feature for CSS files with defer non-critical render-blocking CSS hacky method.Related Pull Requests
Fixed Issues (if relevant)
Manual testing scenarios (*)
default_head_blocks.xml
file and add a CSS element like below;bin/magento cache:flush
)ctrl
+u
combination.Questions or comments
I am not entirely sure that these changes are correct and I don't know if it will affect other code. I tested it on my browser and it works fine. Please review my code and let me know if I made any mistakes.
Contribution checklist (*)