Skip to content
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

Inline CSS with Critters Plugin #642

Merged
merged 13 commits into from
Sep 17, 2018
Merged

Inline CSS with Critters Plugin #642

merged 13 commits into from
Sep 17, 2018

Conversation

lukeed
Copy link
Member

@lukeed lukeed commented Sep 8, 2018

What kind of change does this PR introduce?

Feature

Did you add tests for your changes?

No

Summary

Uses Critters to inline critical CSS on the client bundle(s) for production and development.

The default settings are good 👌 but can be changed by end-user thru preact.config.js if/when needed.

Closes #637

Does this PR introduce a breaking change?

No

@prateekbh
Copy link
Member

Quick thing, I'd like the bundle.css to defer loaded since this is inlined anyways. WDYT?

@lukeed
Copy link
Member Author

lukeed commented Sep 9, 2018

Unless I've missed something, both defer and async are <script>-specific attributes... they won't do anything (for now) on other tags.

The default Critters setup uses rel=preload as=style which is as close to defer as you can get me thinks, before bringing in any JS

@prateekbh
Copy link
Member

prateekbh commented Sep 9, 2018

Hmmm, how about we inline what critters give us and put bundle.css as
<line rel='defer-stylesheet' href='...'> and use js to load this later on?

That should make our first-paint super fast

@lukeed
Copy link
Member Author

lukeed commented Sep 9, 2018

I think our first-paint is already super fast with default setting. Don't think we should be doing anything custom/beyond what Critters offers, as that's the point/goal of Critters, no?

Either way, sounds like you may want the { preload: 'swap' } option.

Copy link
Member

@reznord reznord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@prateekbh
Copy link
Member

Oh I just read:

default: Move stylesheet links to the end of the document and insert preload meta tags in their place.

This seems fine, if it is indeed moving it to the end. Please just check that we don't have double preload css tags with --preload

@prateekbh
Copy link
Member

Also, tried this right now and running into: GoogleChromeLabs/critters#5

Copy link
Member

@prateekbh prateekbh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does put duplicate preload tags with --preload for bundle.css. So that should be avoided if this plugin is in by default.

Also I still get the Defer unused CSS lighthouse error, so may be swap is a better option

@prateekbh
Copy link
Member

prateekbh commented Sep 11, 2018

btw there should be an opt-out/opt-in flag for critters because based on your css critters is running into edge cases.

cc: @developit, posted one such on the bug thread in critters

@lukeed
Copy link
Member Author

lukeed commented Sep 12, 2018

Fixed the plugin ordering 👍

There are double link rel=preload tags, but that shouldn't matter? It still only fires off a single request to bundle.*.css & I'm not getting any unused warnings.

screen shot 2018-09-11 at 5 29 40 pm

@lukeed
Copy link
Member Author

lukeed commented Sep 12, 2018

I think I see what you're talking about.

The default mode append a <link rel=stylesheet href="bundle.*.css"/> to the end of the document – is that what you were referring to?

The tag is removed with js and js-lazy, but has no effect on the Lighthouse score w/ our Preact templates since the CSS is so little.

@prateekbh
Copy link
Member

The tag is removed with js and js-lazy, but has no effect on the Lighthouse score w/ our Preact templates since the CSS is so little.

This has affect when the app grows e.g. material.preact.com

preaload: swap works pretty perfect with just a few characters even for bigger sites.

There are double link rel=preload tags, but that shouldn't matter?

Chrome throws a warning for this in console IIRC

@lukeed
Copy link
Member Author

lukeed commented Sep 12, 2018

Gotcha. It warns if unused, but not on double preload tag.

Feel free to change it to swap, I don't have any objections! I'll likely be away from desk for a few hours

@prateekbh
Copy link
Member

How about along with a opt-out flag?

@lukeed
Copy link
Member Author

lukeed commented Sep 12, 2018

Personally I don't like opt-out flags, so I'd be hesitant. I also not sure why you'd need one?

Arguably, if we're making something a default behavior I feel that we should stand behind it 100©

Unlike the esm feature, there's no compatibility or support issues.

@prateekbh
Copy link
Member

Because I feel that it's not very stable, I made like 4-5 changes to the source code in my node_modules before I could get it to work

@prateekbh
Copy link
Member

prateekbh commented Sep 13, 2018

@lukeed @developit should we be concerned about the fact that even after using preload(swap), latest lighthouse still complains about unused for the link tag and even the inlined css is being reported as extra css supplied

e.g. https://www.webpagetest.org/lighthouse.php?test=180913_MG_dc5a8260f5c19115230143e77c18527d&run=1

@prateekbh
Copy link
Member

Also, another use case of opt-out flag/question: if I use a case in July aren't they better at giving me my critical css rather than critters?

@lukeed
Copy link
Member Author

lukeed commented Sep 14, 2018

If it's not stable, then:

a) we shouldn't include it
b) we should fix it so that it's stable; or
c) enable the feature with a flag, not disable with flag

@prateekbh
Copy link
Member

a) we shouldn't include it

We should as it'll give us great perf boost for whomsoever it works

b) we should fix it so that it's stable; or

I'll wrap my finding in a PR to critters, but have no ETA on this.

c) enable the feature with a flag, not disable with flag

Agreed, do you wanna do this?

@lukeed
Copy link
Member Author

lukeed commented Sep 14, 2018

Oops, sorry, I meant that those were three possible choices; not to do all three 😅

I'd be totally stoked with inline-css as a default feature, but we need to be confident in it. If we're not, then it either can't be a default behavior or shouldn't be there at all

@prateekbh
Copy link
Member

+1, does an opt in flag sound like a decent approach now?

@ForsakenHarmony
Copy link
Member

ForsakenHarmony commented Sep 14, 2018

We could do it like the esm stuff

Opt in now and if we solve all the problems we can make it the default

@prateekbh
Copy link
Member

added a flag, and conditional preload of css if critters is used

@@ -31,7 +31,8 @@ prog
.option('--analyze', 'Launch interactive Analyzer to inspect production bundle(s)')
.option('--prerenderUrls', 'Path to pre-rendered routes config', 'prerender-urls.json')
.option('-c, --config', 'Path to custom CLI config', 'preact.config.js')
.option('--esm', '[EXPERIMENTAL] Builds ES-2015 bundles for your code.', false)
.option('--esm', 'Builds ES-2015 bundles for your code.', false)
.option('--critical-css', 'Adds critical cssto the prerendered markup.', true)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this --inline or --inline-css, but maybe that's just me /shrug

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah that sounds better

@@ -10,8 +10,9 @@
<% if (htmlWebpackPlugin.options.manifest.theme_color) { %>
<meta name="theme-color" content="<%= htmlWebpackPlugin.options.manifest.theme_color %>">
<% } %>
<% const filesRegexp = options.criticalCss ? /\.(js)$/ : /\.(css|js)$/;%>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand – we'd still want to preload some CSS, especially the routes' chunks.

@lukeed
Copy link
Member Author

lukeed commented Sep 15, 2018

@prateekbh FYI - failing tests are now actually relevant to your changes

@prateekbh
Copy link
Member

It passes now but it shouldn't, I haven't fixed the preload tests don't know why they are passing

@prateekbh
Copy link
Member

fixed everything, good to merge. plz review

@prateekbh prateekbh dismissed their stale review September 16, 2018 19:41

Dismissing my own review as I added commits

Copy link
Member Author

@lukeed lukeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't approve since I initiated the PR 😆 Looks good!

@prateekbh
Copy link
Member

now @developit also has a commit 😆

@developit
Copy link
Member

Critters issue should be fixed in 1.2.0.

@prateekbh
Copy link
Member

@ForsakenHarmony can you review this one :)

@@ -10,8 +10,9 @@
<% if (htmlWebpackPlugin.options.manifest.theme_color) { %>
<meta name="theme-color" content="<%= htmlWebpackPlugin.options.manifest.theme_color %>">
<% } %>
<% const filesRegexp = htmlWebpackPlugin.options.inlineCss ? /\.(chunk\.\w{5}\.css|js)$/ : /\.(css|js)$/;%>
Copy link
Member

@reznord reznord Sep 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template.html is already complicated and this adds more to it 🙈.

@developit any plans on making it similar to what CRA does?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I can take a look at this in next iteration, but not for this PR

Copy link
Member

@ForsakenHarmony ForsakenHarmony left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@hassanbazzi hassanbazzi merged commit 53153f1 into next Sep 17, 2018
@lukeed lukeed deleted the feat/critters branch September 17, 2018 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants