-
-
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
Some small optimizations for stylesheet injection #328
Conversation
@@ -353,7 +353,6 @@ class MiniCssExtractPlugin { | |||
'}', | |||
'var linkTag = document.createElement("link");', | |||
'linkTag.rel = "stylesheet";', | |||
'linkTag.type = "text/css";', |
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.
Why we need remove this? Not sure it is right idea
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.
Removing text/css
good for HTML5, but some browsers (include mobile) still have bad supporting HTML5
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.
Keep compatibility as long as we can. Third-world countries and the corporations there can and usually are locked on older "legacy” devices or browsers
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 default value of the type
attribute has always been text/css
. The only difference in HTML5 was making it pass validation when omitted. There is no functionality change with regard to this behaviour between the two specs.
You can test this yourself - load this webpage in IE6:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>HTML 4 Strict</title>
<link rel="stylesheet" href="style.css">
<!-- make sure style.css exists and and is not empty -->
</head>
<body>
<script>
alert(document.styleSheets.length);
</script>
</body>
</html>
(also worth noting: an argument for specifying type
on <link>
tags implies we should do the same for <script>
, which is universally regarded as unnecessary)
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.
Nicely done
@@ -368,7 +367,7 @@ class MiniCssExtractPlugin { | |||
'linkTag.href = fullhref;', | |||
crossOriginLoading | |||
? Template.asString([ | |||
`if (linkTag.href.indexOf(window.location.origin + '/') !== 0) {`, | |||
`if (linkTag.href.indexOf(location.origin + '/') !== 0) {`, |
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.
Always need window
, you can have scope problem in some rare cases
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.
agreed, don't rely on global scope being there. explicit, no implicit is always my suggestion
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 scope problem are you referring to?
var location = 1
or location=1
in global scope redirect the page, as does window.location=1
- it's exceptionally unlikely the value would be redefined. It could be shadowed, but that's equally true for any variable including window
.
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.
Note that the code already uses document
rather than window.document
.
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.
Fair point... we should side with implicit or explicit conventions throughout
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’ve had scope issues before. Rarely but they do happen. Even if wasted bytes. This plugin gets like 5mil downloads a week. Eventually complaints would roll in. We are talking race conditions.
Stupid question, what if we declared window as a variable, then w.document or w.location? One way to save bytes maybe. Can’t speak if race conditions would come of this never tried
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.
We are talking race conditions.
I don't see a race condition here.
what if we declared window as a variable, then w.document or w.location? One way to save bytes maybe.
If gzip's involved, that uses more bytes than window.document
.
Fwiw I think omitting window
is fine.
@@ -377,8 +376,7 @@ class MiniCssExtractPlugin { | |||
'}', | |||
]) | |||
: '', | |||
'var head = document.getElementsByTagName("head")[0];', | |||
'head.appendChild(linkTag);', | |||
'document.head.appendChild(linkTag);', |
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.
Hm IE9 doesn't support getElementsByTagName
?
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.
@evilebottnawi looks safe to me?
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.
@ScriptedAlchemy for me too, so i asked question why it was changed
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 good point. Though both of them do work with old I.E.
However I’m unsure how widely supported ‘document.head’ is especially in older browsers
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.
document.head
is supported in IE9+.
https://developer.mozilla.org/en-US/docs/Web/API/Document/head#Browser_compatibility
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 Webpack core has also switched over to using document.head
:
webpack/webpack#8467
/cc @developit friendly ping |
Just to clarify my intention with this PR: The code generated here is injected into a large percentage of websites. Each byte saved represents a nontrivial reduction in bundle size across the whole web. |
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.
Good for me, but it is breaking change, some people can use plugin for IE8 and after merge we break their app, we can separate PR on two parts
Do we really need to be this concerned about older browser support if #299 is not included? Any browser that this PR would break is already broken by not having #299. (EDIT: nevermind that as IE does support it; but webpack 2+ cannot bundle ES modules on IE<9 anyway because IE<9 don't have a working |
@Kovensky hm, I forgot that we need to use |
It depends on whether it's still possible to make a bundle that does not invoke |
@Kovensky thanks for information, what do you think should we merge this as patch or major release? |
It looks like it is still possible if your code and entire dependency graph consists exclusively of CommonJS or AMD modules... I find that extremely unlikely. Personally I'm OK with this break as it's overwhelmingly unlikely that it will break bundles that weren't already broken, I'm not sure if this might still affect people. It's not impossible that people might be intentionally using |
What about a feature release? Unless we are really making a heavy impact change? Are we losing compatibility with current PRd changes? Don’t mind major version bump, just throwing the question out there |
Yeah that’s fine then. Lets get this in as a major |
This adds an new `insertInto` option that is optional and backards-compatible. Specifying a CSS selector allows the user to specify a DOM node into which the async-loaded <link> tags should be inserted. Closes webpack-contrib#370, related to webpack-contrib#328,webpack-contrib#331
This adds an new `insertInto` option that is optional and backards-compatible. Specifying a CSS selector allows the user to specify a DOM node into which the async-loaded <link> tags should be inserted. Closes webpack-contrib#370, related to webpack-contrib#328,webpack-contrib#331
This adds an new `insertInto` option that is optional and backards-compatible. Specifying a CSS selector allows the user to specify a DOM node into which the async-loaded <link> tags should be inserted. Closes webpack-contrib#370, related to webpack-contrib#328,webpack-contrib#331
Codecov Report
@@ Coverage Diff @@
## master #328 +/- ##
======================================
Coverage 0.00% 0.00%
======================================
Files 3 3
Lines 284 284
Branches 59 59
======================================
Misses 234 234
Partials 50 50
Continue to review full report at Codecov.
|
People are using webpack 4 for ie8. That's a supported use case. ESM is not supported, by there is a ton of commonjs or amd code that can be used. |
This PR contains a:
Motivation / Use-Case
There are a few cases where the code injected into a bundle could be a bit smaller. I've addressed two really simple ones here - removing the
type
property from<link rel=stylesheet>
, and usingdocument.head
(IE9+) instead ofgetElementsByTagName('head')[0]
.Breaking Changes
This requires IE9+. Not sure if there's a browser support target for mini-css-extract-plugin that makes this prohibitive.