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 options #190

Merged
merged 13 commits into from
Jan 11, 2019
Merged

Inline CSS options #190

merged 13 commits into from
Jan 11, 2019

Conversation

willhowlett
Copy link

Hi. We have a requirement to render our css inline in certain situations, and so I had a crack at implementing it with the loadable library. Please do let me know what you think about the approach.

Summary

In order to improve page speed score, or to render AMP SSR pages alongside the main app, it can be a requirement to render css inline.

Test plan

This has been added as an option to the existing chunkExtractor.getStyleTags() and chunkExtractor.getStyleElements() functions via an inline boolean parameter.

Additionally a chunkExtractor.getCssString() function has been added to allow developers further control over how to render css (an example use requirement being passing the css string to a style tag using AMP's amp-custom attribute)

Appropriate tests have been added to ChunkExtractor.test.js

@gregberge
Copy link
Owner

Hello @bigwillch, thanks for your work, you made a great job! I have only one problem: using fs.readFileSync is not good in production, it blocks thread. So we have to use the asynchronous method instead. But if we use it: getStyleTags and getStyleElements would become asynchronous. So my suggestion is to create custom methods for your use-case: getInlineStyleTags, getInlineStyleElements, getCSSString.

Is it possible?

@willhowlett
Copy link
Author

Thanks for the feedback! I'll have a a crack at creating new async methods as suggested

@gregberge
Copy link
Owner

Thanks, let me know when it is done!

@willhowlett
Copy link
Author

@neoziro just a question - would you be opposed to the package providing both sync and async methods so that the developer can choose which method to use in the app?

I'm just thinking that the tradeoff between performance and having to wrap the html output in promises may be something developers would like to be able to choose themselves

@gregberge
Copy link
Owner

@bigwillch yes we could expose the two methods, just add getSyncInlineStyleElements if you want. It costs nearly nothing and it could be useful for users.

@willhowlett
Copy link
Author

@neoziro I've changed the functionality to use fs.readFile as suggested

  • I kept inline as an option of the original methods instead of creating new methods. It's a personal preference to keep related functionality clearly together for the user, but if you'd prefer them to be standalone methods let me know
  • Using the inline: true option now returns a promise (so the dev will need to modify their server side code to wait for the promise to resolve if they wish to use this option)
  • I decided against including a sync option in the end. Everything I read about using fs.readFileSync is that it's a big no-no as you said so I figured it wasn't a good idea to give people an option to do the wrong thing

Thanks again for your feedback so far!

@gregberge
Copy link
Owner

I am not OK to return a different type (especially a promise) when a custom option is passed to the function. I think it is not clear for the user, it can be confusing and it is not type friendly.

Can you please create a different method for each one?

@willhowlett
Copy link
Author

@neoziro no problem :) Have made them separate methods as requested

@MartinGian
Copy link

I'm very interested in this functionality :) I can help testing it on my project let you know if I have any issues.

Copy link
Owner

@gregberge gregberge left a comment

Choose a reason for hiding this comment

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

So finally you decided to no add the sync way? OK for me, it is an anti-pattern for production. Let's wait for issues.

packages/server/src/ChunkExtractor.js Show resolved Hide resolved
packages/server/src/ChunkExtractor.js Show resolved Hide resolved
@gregberge
Copy link
Owner

@bigwillch can you please fix the resolve / reject and I will merge it! Thanks!

@willhowlett
Copy link
Author

@neoziro thanks for flagging! sloppy of me :) Hope it's all ok now 🙏

@gregberge gregberge merged commit 2caf676 into gregberge:master Jan 11, 2019
@gregberge
Copy link
Owner

Thanks for your work @bigwillch!

@willhowlett
Copy link
Author

Great! Thanks for approving

@willhowlett
Copy link
Author

@neoziro has v5.3.0 been published to npm yet? I'm not seeing it when trying to upgrade

@gregberge
Copy link
Owner

gregberge commented Jan 17, 2019

v5.3.0 & v5.4.0 are published. See https://www.npmjs.com/package/@loadable/server.

@willhowlett
Copy link
Author

sorry, I'm dumb. Was trying to upgrade loadable/component instead. doh

@nesbtesh
Copy link

nesbtesh commented Jul 4, 2020

I am going through the code and I can’t find where do you declare which style elements you want inline? I dont want to include the entire apps css inline, just the part above the fold.

@theKashey
Copy link
Collaborator

@nesbtesh - there is no such thing as "above the fold", without prerendering your application into some virtual window first - then you'll know what it above the fold.

You are probably looking for used-styles in stream mode, where styles are inlined before they used, no matter of the "fold".

@nesbtesh
Copy link

nesbtesh commented Jul 5, 2020

@theKashey that worked great, thanks, time to interactivity improved to 1s

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.

5 participants