A new W3C spec for preloading and async loading of CSS/JS has been created. It is currently in FF, Chrome and in Edge it is under consideration.

http://caniuse.com/#feat=link-rel-preconnect
https://developers.google.com/web/updates/2016/03/link-rel-preload

Filament Group who maintain loadCSS has implemented this. Their github explains the situation; https://github.com/filamentgroup/loadCSS

Referencing CSS stylesheets with link[rel=stylesheet] or @import causes browsers to delay page rendering while a stylesheet loads. When loading stylesheets that are not critical to the initial rendering of a page, this blocking behavior is undesirable. The new
standard enables us to load stylesheets asynchronously, without blocking rendering, and loadCSS provides a JavaScript polyfill for that feature to allow it to work across browsers, as well as providing its own JavaScript method for loading stylesheets.

Implementing this feature should be straightforward and allow CSS/JS to be loaded async while taking advantage of browser heuristics.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dalyr95 created an issue. See original summary.

mikeytown2’s picture

Version: 7.x-1.x-dev » 7.x-2.x-dev

This has been the preferred way that AdvAgg has used the library for some time now. I'm a little confused as to what this issue is about now.

dalyr95’s picture

Version: 7.x-2.x-dev » 7.x-1.x-dev

LoadCSS has new functionality, specifically supporting link preload. So the end result of the page would look like this;

<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="path/to/mystylesheet.css"></noscript>
<script>
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
(function(){ ... }());
/*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */
(function(){ ... }());
</script>

As far as I can see, Advagg only uses the original loadCSS implementation. The W3C spec for link preload is quite new.

EDIT: Ah I can see it here; http://cgit.drupalcode.org/advagg/tree/advagg.module#n2077
https://www.drupal.org/node/2660710

I looked through issues and commits and couldn't see any reference to it. What version was it released in?

mikeytown2’s picture

7.x-2.18 if I'm reading the git logs correctly.

mikeytown2’s picture

Version: 7.x-1.x-dev » 7.x-2.x-dev
Component: General CSS/JS » Modifier
Category: Feature request » Support request
Priority: Major » Normal
dalyr95’s picture

FileSize
373.55 KB
328.17 KB

Thanks, we moved to 2.17 shortly after it came out, so missed preload :(
I've upgraded to 2.25 and noticed a bug in preload headers.

When you enable preload headers, Chrome sends the following warning <link rel=preload> has an unsupported `type` value

So on http://cgit.drupalcode.org/advagg/tree/advagg.module#n2182 (added here https://www.drupal.org/files/issues/advagg-2744377-14-preload.patch ) I removed type (only testing fonts atm) and that removed the warning and implemented the correct behavior.

I've attached two screenshots of the waterfall, you'll see in "correct.png" the first entry is the Document, then the fonts, the Initiator is "Other" which is preloading. This is the correct behavior.

The existing implementation with gives the console warning, you'll see in "current.png" the Document is loading, but then the fonts come in when they would normally be loaded in the CSS and the "Initiator" is "Index (Parser)" which is CSS loading the fonts, therefore header hints are not working.

Also Advagg is adding all font declarations to the headers, if a browser doesn't support woff2, it won't support header preload. Considering some boilerplates use up to 5 fonts for backwards compatibility, that's a lot of bloat, should only add woff2 fonts.
http://caniuse.com/#feat=woff2
http://caniuse.com/#search=preload

EDIT: It looks like Advagg follows the spec, I'm going to check Chromium bug reports and see why Chrome seems to be implementing it this way.
https://www.w3.org/TR/preload/#developer,-server,-and-proxy-initiated-fe...

mikeytown2’s picture

Title: loadCSS now supports link preload » preload link
Status: Active » Needs review
FileSize
396 bytes

Yeah I built it following the spec. Good point about preload browsers supporting woff2; this patch should address it, if not there's another set of font extensions in advagg.advagg.inc line 304. I could add in a variable to make advagg conform to chrome; so it can be turned on/off.

dalyr95’s picture

Nice one about Woff2. I've filled a bug with Chromium, but the checkbox would be a good option for the meantime, maybe the tooltip links to the issue? So people will know when its fixed?

https://bugs.chromium.org/p/chromium/issues/detail?id=740568&q=header%20...

dalyr95’s picture

Also looking at the inline CSS, it appears be be a standard CSS link with extra attributes.

<link type="text/css" rel="preload" href="/sites/XXX/files/advagg_css/css__5igzPLowZVxMfS0O0h-tWDpZBZd_3ugRwX4H6iMbsWA__w7fw8QdMDA63TP5TLLzO-_R5mw4WBxV4lBeHK8Cpbxk__BNq-Qdp7UBMg9AhsW3OcIgcKuEiiR33GTuGl_Z9ScAM.css" media="all" as="style" onload="this.rel=&#039;stylesheet&#039;" />

From spec
<link rel="preload" href="/style/other.css" as="style">

From loadCSS

<link rel="preload" href="path/to/mystylesheet.css" as="style">
<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">
dalyr95’s picture

There's an update from Chromium https://bugs.chromium.org/p/chromium/issues/detail?id=740568&q=header%20...

The spec is using single quotes as opposed to double quotes!!

dalyr95’s picture

Tested this, type is present in headers and Chrome doesn't complain. Fonts are loaded in as expected.

  • mikeytown2 committed a446e90 on 7.x-2.x
    Issue #2893060 by dalyr95, mikeytown2: preload link
    
mikeytown2’s picture

Status: Needs review » Fixed

#7 and #11 have been committed! Thanks for you're help!

dalyr95’s picture

No worries, when I was reading about the preload headers I came across this. https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-7...

Preloaded fonts without crossorigin will double fetch! Ensure you’re adding a crossorigin attribute when fetching fonts using preload otherwise they will be double downloaded. They’re requested using anonymous mode CORS. This advice applies even if fonts are on the same origin as the page. This is applicable to other anonymous fetches too (e.g XHR by default).

https://github.com/w3c/preload/issues/32
https://github.com/jolantis/altair/commit/4846ace11df79cdc77c49eb5a41601...

If requesting fonts, it looks like crossorigin should always be present otherwise the font will be downloaded twice.

mikeytown2’s picture

Status: Fixed » Active

This advice applies even if fonts are on the same origin as the page

Good to know. Crossorigin is only added for external fonts; looks like it needs to happen for all fonts.

mikeytown2’s picture

Status: Active » Needs review
FileSize
608 bytes
mikeytown2’s picture

Ignore last patch; deleted the wrong code block.

  • mikeytown2 committed c196aae on 7.x-2.x
    Issue #2893060 by mikeytown2, dalyr95: preload link
    
mikeytown2’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.