Adding and removing stylesheets with webpack - javascript

I'm interested in using WebPack for my SPA (I haven't used it before), which will have several pages, each with their own bundle of JS, CSS and HTML.
Firstly, is there a way to remove stylesheets that aren't being used using webpack? From a look at the documentation, it seems that there isn't. For example, say I have a #wrapper div that needs to have a width: auto for most pages, but a width: 100% for a certain page that needs to be full screen. If my modules just require() their stylesheets, then they will all keep being added to the HTML, and the last one to be loaded will have control over the width, whereas I want just the current page's stylesheet to be loaded. Is there any way to remove stylesheets using webpack? Or is there a better solution to this problem?
In addition, does webpack have a callback for stylesheets? If I need to run some code only when the css has loaded (I mean the onload callback has fired, not just when the tag is added to the html), is there a proper way of doing it?

Related

CSS Generic vs Page Specific loading

I need some advice on CSS placements for the sake of website load times
I read that it's best to have 'critical CSS' in the head and the rest can be placed in their respective page's body via the tag.
Is it good practice if I loaded all the CSS or at least the 'Generic' styles that many pages share while I kept page specific styles in a tag in the page's body?
One side question, some of my pages use jQuery, should I only load that at the bottom of those pages or leave it in the template head?
I tried both and the site loads just fine, but I know under the hood results may vary. I'm not sure how to even check. I tried websites that test a website's load performance and I got mixed results. So I'm not sure how to optimize my website's performance.
Usually all CSS files are called in the head, one thing you can do to improve performance is to modularize, let's say that you have the global styles in one file called global.css and it contains your font specs, global components used in all pages such as navbar, footer, layouts, etc... And in another file you can only put the styles regarding your specified page such as contact section that's another page called contact.css and there you can have overrides to global file and specific styles that you only use in this page.
This way you can serve less heavy files regarding the page that user's requiring.
Regarding you jQuery question I suggest that don't load jQuery library if you're not using it, it's useless. Only load it in the pages that you're using the library. Hope it helps!

Does CSS-in-JS not prevent browser from CSS caching?

I am looking for best practices to style React app with Server-Side Rendering.
I see different options like using preprocessors like SASS or putting stylings inside JS code like JSS, styled-components etc.
Playing around JSS, I see that it puts stylings to head section inside HTML. I just use the following example to see the behavior:
https://github.com/cssinjs/examples/tree/gh-pages/react-ssr
Wouldn't it prevent browsers from caching CSS to put it inside head section and hence increase successive page loading time? Is there any way to put styling to an external file with JSS so that browser can cache it?
What you see in that example is Critical CSS. It is only CSS that is used specifically on that view, it is not supposed to be cached, it is faster than loading an external resource in a blocking way and pay with latency.
Critical CSS is an actual performance optimisation here.

Pagespeed rating low - What am I missing?

I am trying to write a webpage with a 100% rating from Google PageSpeed, not an easy task let me tell you! So far, I have the caching enabled, header compression enabled, compressed all my png images, and I am attempting to async my CSS for above the fold content. The last bit is where I am running into issues. Here's the current layout of the page in a codepen:
https://codepen.io/ftbcoders/pen/MPVbNY
I have defined my stylesheets in the footer with media="none", I have set a pre-load animation and loader using inline CSS so you see a loader, called an onLoad event on the body to change the media type of the CSS files from none to all when the document is loaded, and yet I am getting:
Optimization
Low
56 / 100
Eliminate render-blocking JavaScript and CSS in above-the-fold content
Your page has 3 blocking CSS resources. This causes a delay in rendering your page.
None of the above-the-fold content on your page could be rendered without waiting
for the following resources to load. Try to defer or asynchronously load blocking
resources, or inline the critical portions of those resources directly in the HTML.
Optimize CSS Delivery of the following:
https://www.example.com/stylesheet/style.css
https://www.example.com/stylesheet/open.sans.css
https://www.example.com/stylesheet/font.awesome.css
Why are they blocking loading? They are set for media of none so it should load the CSS files but not try and display them until the body onLoad event has fired, AND they're in the very end of my file... what am I missing here? It's loading awesome in practice but the ranking is what I am wanting to maximize here. Any tips? Am I missing something? Thanks.
Each CSS file contains styles with information how each your HTML tag looks like in the end => it's not possible to render page without that information => browser has to download, parse that information in order to show the page => it's render-blocking asset.
There are multiple ways to solve that, and I'll show one of them. Relatively simple.
You may include contents of those CSS files in your HTML file. That will solve issue.
In your HTML instead of a link to .css file
<link ... href="style.css">
put contents of those file
<style>
contents of your style.css here
</style>
Ideally that should be done programmatically.
It can be applied in production if those css files are not that big and/or you don't have a lot of returning visitors.

set css image from current folder using jquery script page

I have an external Javascript page located under ../Scripts/CBox/ folder from parent.
There is an image located in the same folder. I want to set background-image for a control using Jquery from there. When I use this code, It sets the background-image path as localhost:7905/ddl_arrow.png where localhost:7905 is my asp.net development server.
function createAutoCBox(boxCtrl) {
$(boxCtrl).css('background-image', 'url("ddl_arrow.png")');
$(boxCtrl).css('background-repeat', 'no-repeat');
$(boxCtrl).css('background-position-x', '99%');
$(boxCtrl).css('background-position-y', '-2px');
$(boxCtrl).mousemove(jqAutoCompleteMouseMove);
$(boxCtrl).keyup(jqAutoCompleteKeyUp);
$(boxCtrl).mousedown(jqAutoCompleteMouseDown);
}
There is no way to "get current script's path on the server", since JS is done on the client-side. So there is no easy way to do what you are thinking of.
There are only ways to work around this, and all of them are based on the same principle: organise your files properly - each resource should be an URL. Think about it: if you cannot reliable tell where ddl_arrow.png is stored, neither can the browser.
I think the best solution is to put all images inside an [img] folder from the server root. This means you can reference images this way: url(/img/ddl_arrow.png). No matter which JS, which CSS or HTML file needs the images, make sure they always reference the images with a preceding slash. Of course, this applies not only for images, but all other assets/resources - fonts, videos, audio, and even the HTML, CSS, JS files themselves. Basically every file that your server serves should be referenced this way.
There are other hacks involving nasty, messy stuff like using server-side scripts to print the location of the JS file that is being fetched right into the JS file, but I'd recommend to stay far away from these methods.
You'd be better off doing this:
CSS
.my-background {
background-image: url("ddl_arrow.png");
background-repeat: no-repeat;
background-position-x: 99%;
background-position-y: -2px;
}
JQuery
$(boxCtrl).addClass('my-background');
CSS will always understand paths from itself to the image folder, so if your structure was:
/images
/css
the background-image path would be:
../images/ddl_arrow.png
Going up one level with the .. then into the sibling directory images to get the file. You can put this anywhere and it will work.
Worth noting that using css for the styles rather than adding them in JQuery is easier to re-use (just add .my-background to the HTML where you need it). It also makes things a bit nicer to maintain as there isn't style info in your functional files - the you of the future (or your team-mates) will thank you for it.
And, background-position-x / background-position-y are not standard and so cannot be relied on everywhere background-position: x-value y-value is better for now.
Try:
$(boxCtrl).css('background-image', 'url("./Scripts/CBox/folder/ddl_arrow.png")');

Is the webpack style loader meant to load all css? Or just application specific css?

I'm trying to make my front-end design process more modular, and am exploring webpack. It supports a style loader, which allows you import a css file and inject it in the document like so:
require("style/url!file!./file.css");
// => add a <link rel="stylesheet"> to file.css to document
However, my main focus is on websites and not webapps1, so it feels weird to add the css through javascript. But I might just be old fashioned, so I'm wondering: is the loader meant to be used for all css, or is it only meant to load small, conditional parts of css?
And if it can be used for loading all css, would there be any penalties when using a webpack generated bundle.js to inject the css as opposed to directly linking a css file in the html? Besides it obviously breaking if javascript isn't enabled?
1: The difference being that I have very little dynamic content, javascript plays only a minor role in these websites, and that I'm not routing with javascript but have static .html files for pages
Where possible, include CSS with the HTML itself. Modern browsers will begin fetching the CSS as the page is parsing, sometimes before the JavaScript has even begun to download. You're going to get an improvement in page rendering speed doing major pieces outside of a loader.
Additionally, if you stick to a major "core" style, you can benefit from caching, which will again load faster than JavaScript can.
http://csswizardry.com/2013/01/front-end-performance-for-web-designers-and-front-end-developers/
In your example, I've done it by splitting it into multiple pieces and using loaders & bundlers for the specific elements I've got loaded in the page. The application look & feel, branding, etc is loaded from markup, and the behavior that controls my specific UI (say, layout for a particular form) is done with a bundler or packer.

Categories

Resources