I am building webpapp with a JS framework (InfernoJS based on ReactJS).
I was wonderring how much important is it to load only usefull CSS.
In JS Framework website (with angularjs, Reactjs...), you have your CSS for all your routes which is loaded but depending on your page you may only need 20% of your CSS rules on the webpage.
For exemple:
You have '/about' with the ComponentA, for the JS Framework website you will load the CSS for ComponentA on the '/home' page as well but in that case that CSS is irrelevant.
I am wonderring if developping code to load only the css of the component display will really improve my performance espacially for SEO.
How the browser handle the unsed CSS?
Is it loaded in the memory waiting to find an element on which it can be applied?
Is It the same for every browser?
Edit:
#Psi partially answer it. I will reformulate it to make it more understandable.
On JS framework base, your page is splited in different components, most of the time, you will have a component Header, Body, Footer.
So if I go on the route '/home' and '/about' the component Header and Footer should be the same but the Body component will change.
So for optimization, I am considering to load the CSS for the Header and Footer component every time. However, the CSS loaded should change depending on the route and if I change the route (the page is not reloaded, It is handled by JS), the other Body component will be loaded but I will have the CSS of the Body component of the precedent route. In fact, generally you have the CSS for all your Body Components for every routes of your website.
So you have a lot of unused CSS rules. So should it be interesting to change the CSS loaded by adding and removing a <link> or I will probably consum to much ressource doing it and the browser have a good enough optimization about it?
To answer your question, there are several layers of thinking you need to go through.
First of all: Of course, every css that is loaded into your page will take the memory it needs to hold it active, because your html-page (although it may be static) possible could be changed dynamically (e.g. $.addClass).
So the browser knows what styles are being used at the moment, but has no way to determine possible future elements, thus being forced to keep every css definition in memory (or paged onto the disk).
The second thing is loading time. Depending on the order your css is being loaded, you may run into the situation where first your page loads and the css is being applied afterwards. This can even be visible to the user, being presented a non-styled page at the beginning and getting it styled later on!
This can be an issue even when loading only the necessary css via #import or <link rel="stylesheet">, so the best way is to provide the css in the html itself (loading it dynamically when rendering the html to the page).
This reduces loading time in two manners:
When loading the css via reference (i.e. #import or <link>), the browser starts opening a new connection (or uses the same connection after your html has been transferred completely) and requests the css linked in your html. So the browser
Loads the html although no css has been loaded yet and displays the html as soon as possble (always)
Needs additional time to establish a new connection or to wait for the html transmission to be finished before it even starts to load the css
If the used css is loaded very late, this can be a matter of seconds!
Although not asked:
For javascript, the exact opposite is desired in most cases: The browser starts executing a script as soon as it is received and pre-compiled. This may lead to unwanted behavior, when the html the script refers to is not loaded yet. So unless you are using a promise to ensure the page has been loaded before executing something, you should place in-line javascript as far as possible to the end of your page.
[edit]
To match your additional question:
It's hard to say. Of course, an optimized css will perform slightly better than an overloaded one in the client, but this makes design much harder as you have to keep track of any changes in any document and adapt your css accordingly. Also it might lead to discrepancies between same classes on different pages (e.g. .headline in page1 looks different to .headline in page2) when you want to update a class.
[edit]
If you generate the stylesheet automatically (dynamically), you may create more overhead by putting effort in the optimization than you save by the reduced stylesheet parsing time.
Related
TLDR; skip to the problem section 👍
Background
We have a very large monolith legacy application. We are in the process of stripping functionality out into a new application.
These two applications have vastly different UI's built in vastly different architectures and technologies. As our users will be navigating freely between the two, currently, we need to unify the UI to some degree so the transition isn't so jarring.
It was decided to have a large CSS override style-sheet that we just load over the top of the legacy application (So we could spend more time focusing on the new app). This sheet, whilst massive, works.
Our legacy app has a root CSS file that is included on every page, regardless of how (some is classic ASP, some uses master pages, some is manually).
The problem
So we decided to use a #import tag in the root style sheet to pull in our re-style override.
Whilst we acknowledge that blocking rendering of the page is a horrible anti pattern we need this behavior to prevent flashing of the old UI, until the override sheet takes over.
We thought that CSS in the head will block rendering of the page until its loaded, however it doesn't appear to be waiting for the imported CSS. Is this expected behavior with regards to imports? Is there any way to make the user agent wait? Any information how how to achieve this would be very appreciated.
Thanks
There is no way to apply another CSS file synchronously to the CSS file it is embedded in. But as you already doing a lot of bodging in this project, here are some suggestions I can make:
(But before that: All of those aren't really good, not to say best-practice, and have definitely some danger to it.)
Hide the GUI in the critical section: Add a CSS rule in the root stylesheet, that hides the GUI, and another in the new stylesheet that overrides it and shows the GUI again.
If you can add something to all HTML pages: Add a loading screen. Something like
<div class="loading-screen" style="display:fixed;top:0;left:0;width:100vw;height:100vh;background-color:white;z-index:1000">Loading...</div>
and hide it again with the new sytylesheet: .loading-screen { display: none; }
All in one: Throw away the idea of using #import and write the content of your new stylesheet in the root stylesheet.
The best practice would probably be to rework the hole site structure or at least rework/remove the old GUI style.
For the sake of page speed I am addressing how the sites css is loaded. Originally the site called several css files on each page. I took the standard approach, combine and minify all css into one file, leverage browser caching and use a CDN. This offers much improvement.
My next step is to separate the global css from the per page css to avoid loading any unused css. My original goal would be to call one minified css file on each page that holds the global css rules, and output the per page css internally in the <head> section of the page.
The global css file will be cacheable by the browser and reusable for each page but does count as render blocking css and an additionally http request.
Would it be better for page speed to output the global styles internally in the <head> section of each page to avoid an additional http request even though it will sacrifice the global styles being reusable browser cached css?
EDIT: I am using PHP and caching the pages, so it is not a question of what is easier to develop, it is only a question about the performance of the output (HTML / CSS).
It's complicated...
Including the styles in the head means they won't be cached and that you're transferring more than needed to render the page. Additionally, external CSS imported via <link>s are pipelined, so that you're not waiting on one to complete before fetching the next. The result, is that usually two 100kb sheets will transfer and indeed render faster than one 200kb file.
Of course, certain network issues like slow DNS can affect results, but generally, with non overloaded CPU and decent bandwidth and low ping times, pipelines increases page speed, especially if one or more pipes are cached.
Putting the rules inline in the <head> could also give gzip more work per page, which would lower bandwidth compared to something that can be shrunk once and cached.
In short, it somewhat depends on users, nets, and code, but without mis-configuring or bad hardware, using a global import should be faster than shipping inline.
One last note: if you just need a small amount of CSS, it's faster to store it inline in the head. For example, i've found that body { opacity: 0; transition: 500ms opacity;} can help hide FOUC better than an external sheet under more conditions, so for such UX optimizations, a little bit of CSS inline is highly warranted.
I am building an app on top of webkit, I need to modify a CSS file (edit a selector), which I can do once the page is loaded using Javascript. In my particular scenario I may load the page many times and I would like to mutate the CSS in the cache (using Javascript, as opposed to hacking webkit). Any ideas?
Without entirely understanding your use case I see at least three cheap and fast methods to override some styles:
use one of the many bookmarklets out there (e.g. this one by Paul Irish) to play around injecting styles or
use a short snippet of javascript ondomready to inject a stylesheet with selectors and styles into the head of the document (similar to the bookmarklet above) or
define a specific enough CSS selector and simply include an inline style element in your document (which I would not suggest)
All three methods are basically the same. Depending on what you have, are able to edit or want to achieve either method may be more suitable.
User stylesheets or extensions like Stylebot for Google Chrome may be another possibility to look into.
Weird stuff like loading referenced stylesheets via javascript's XHR, get the content of the file, modify or inject stuff and reapply the styles to the current document are possible as well but probably not what you're looking for.
We can write CSS as the following types:
Inline CSS
Embedded CSS
External CSS
I would like to know pros and cons of each.
It's all about where in the pipeline you need the CSS as I see it.
1. inline css
Pros: Great for quick fixes/prototyping and simple tests without having to swap back and forth between the .css document and the actual HTML file.
Pros: Many email clients do NOT allow the use of external .css referencing because of possible spam/abuse. Embedding might help.
Cons: Fills up HTML space/takes bandwidth, not resuable accross pages - not even IFRAMES.
2. embedded css
Pros: Same as above regarding prototype, but easier to cut out of the final prototype and put into an external file when templates are done.
Cons: Some email clients do not allow styles in the [head] as the head-tags are removed by most webmail clients.
3. external css
Pros: Easy to maintain and reuse across websites with more than 1 page.
Pros: Cacheable = less bandwidth = faster page rendering after second page load
Pros: External files including .css can be hosted on CDN's and thereby making less requests the the firewall/webserver hosting the HTML pages (if on different hosts).
Pros: Compilable, you could automatically remove all of the unused space from the final build, just as jQuery has a developer version and a compressed version = faster download = faster user experience + less bandwidth use = faster internet! (we like!!!)
Cons: Normally removed from HTML mails = messy HTML layout.
Cons: Makes an extra HTTP request per file = more resources used in the Firewalls/routers.
I hope you could use some of this?
I'm going to submit the opinion that external style sheets are the only way to go.
inline CSS mixes content with presentation and leads to an awful mess.
embedded CSS gets loaded with every page request, changes cannot be shared across pages, and the content cannot be cached.
I have nothing against either method per se, but if planning a new site or application, you should plan for external style sheets.
Inline
Quick, but very dirty
This is (sadly) also the only really sane option for HTML formatted email as other forms often get discarded by various email clients.
Embedded
Doesn't require an extra HTTP request, but doesn't have the benefits of:
Linked
Can be cached, reused between pages, more easily tested with validators.
You want external css. It's the easiest to maintain, external css also simplifies caching. Embedded means that each separate html file will need to have it's own css, meaning bigger file size and lots of headaches when changing the css. Inline css is even harder to maintain.
External css is the way to go.
Where to start!!??
Say you had a site with 3 pages...
You could get away with Inline CSS (i.e. CSS on the page itself, within tags).
If you had a 100 page website...
You wouldn't want to change the CSS on each page individually (or would you?!)...
So including an external CSS sheet would be the nicer way to go.
Inline CSS is generally bad. It's much easier to modify the style of a page when all the styles are located in one central location, which inline CSS doesn't offer. It's easy for quickly prototyping styles, but shouldn't be used in production, especailly since it often leads to duplicating styles.
Embedded CSS centralizes the styles for the page, but it doesn't allow you to share styles across pages without copying the text of the embedded style and pasting it in each unique page on your site.
External CSS is the way to go, it has all of the advantages of embedded CSS but it allows you to share styles accross multiple pages.
Use external CSS when:
you have a lot of css code that will make your file messy if you put it all inline
you want to maintain a standard
look-and-feel across multiple pages
External CSS makes it a lot easier to manage your CSS and is the accepted way of implementing styles.
If the styles are only needed for one file, and you don't foresee that ever changing to apply to other pages, you can put your css at the top of the file (embedded?).
You should generally only use inline CSS if:
It's a one-time formatting for a specific tag
You want to override the default css (set externally or at the top of the file) for a specific tag
To everyone in the here and now, reading after 2015, with projects like Polymer, Browserify, Webpack, Babel, and many other important participants that I'm probably missing, we have been ushered into a new era of writing HTML applications, with regards to how we modularize large applications, distribute changes and compose related presentation, markup and behavior into self-contained units. Let's not even get started with service workers.
So before anyone forms an opinion on what is and isn't feasible, I would recommend that they investigate the current web ecosystem in their time to see if some issues related to maintainability have been gracefully solved.
Pros:
Allows you to control the layout of the entire site with one file.
Changes affect all documents at the same time.
Can eliminate redundant in-line styling (Font, Bold, Color, Images)
Provide multiple views of the same content for different types of users.
Cons:
Older browsers may not be able to understand CSS.
CSS is not supported by every browser equally.
In this case, the pros far outweigh the cons. In fact, if the site is designed in a specific way, older browsers will display the content much better (on average) than if the site were managed with tables.
If you are using a server side language, why not embed CSS and use conditional programming to display it as necessary? For example, say you're using PHP w/ Wordpress and you want some homepage specific CSS; you could use the is_home() function to show your CSS in the head of the document for that page only. Personally, I have my own template system that works like so:
inc.header.php = all the header stuff, and where page specific CSS would go I put:
if(isset($CSS)) echo $CSS;
Then, in a specific page template (say about.php), I would use a heredoc variable for the page specific CSS, above the line which includes the header:
Contents of about.php:
<?php
$CSS = <<< CSS
.about-us-photo-box{
/* CSS code */
}
.about-us-something-else{
/* more CSS code */
}
CSS;
include "inc.header.php"; // this file includes if(isset($CSS)) echo $CSS; where page-specific CSS would go ...
<body>
<!-- about us html -->
include "inc.footer.php";
?>
Is there something I'm missing that makes this approach inferior?
Pros:
1) I can still cache the page using standard caching techniques (is there a caching method that takes advantage of a CSS only external file??).
2) I can use php for special case conditional formatting in specific class declarations if absolutely necessary (PHP doesn't work in a CSS file, unless I'm missing some server directive I could set).
3) All my page specific CSS is extremely well organized in the actual PHP file in which it's being used.
4) It cuts down on HTTP requests to external files.
5) It cuts down on server requests to external files.
Cons:
1) My IDE program (Komodo IDE) can't follow the Heredoc formatting to properly highlight the CSS, which makes it slightly harder to debug syntax errors in the CSS.
2) I really can't see any other con, please enlighten me!
Which is a better option: to store CSS on a separate file or on the same page?
Let's forget the fact that changing the CSS on a file makes it to apply all HTML pages directly. I am using dynamic languages to generate the whole output - so that does not matter.
A few things I can think of:
CSS on a separate file generates less bandwidth load.
CSS on a separate file needs another HTTP request.
On the other hand, if I compress the data transmission with Zlib, the CSS on the same page should not matter in terms of bandwidth, correct? So, I get one less HTTP request?
The main benefit of an external CSS file is that:
It can be used on multiple pages; and
It can be cached so it doesn't need to be loaded on every page.
So, if there is potential for reuse of the dynamically generated CSS between pages or on multiple views of the same page then an external file could add value.
There are several common patterns for dynamically generated CSS.
1. Generating a subset for a page
I've seen this occasionally. A developer decides to limit the amount of CSS per page by only sending what's necessary. I don't imagine this is the case for you but I'm mentioning it for completeness. This is a misguided effort at optimization. It's cheaper to send the whole lot and just cache it effectively.
2. User-selected theme
If the user selects a particular look for your site, that's what I'm talking about. This implies they might select a whole package of CSS and there might be a limited set to choose from. Usually this will be done by having one or more base CSS files and then oen or more theme CSS files. The best solution here is to send the right combination of external CSS files by dynamically generating the page header with the right <link> elements and then caching those files effectively.
3. User-rolled theme
This goes beyond (2) to where the user can select, say, colours, fonts and sizes to the point where you can't package those choices into a single theme bundle but you have to generate a set of CSS for that user. In this case you will probably still have some common CSS. Send that as an external CSS files (again, caching them effectively).
The dynamic content may be best on the page or you may still be able to make use of external files because there is no reason a <link> can't point to a script instead of a static file. For example:
<link rel="stylesheet" href="/css/custom.php?user=bob" type="text/css">
where the query string is generated dynamically by your header from who is logged in. That script will look up the user preferences and generate a dynamic CSS file. This can be cached effectively whereas putting it directly in the HTML file can't be (unless the whole HTML file can be cached effectively).
4. Rules-based CSS generation
I've written a reporting system before that took a lot of rules specified by either the user or a report writer and a custom report and generated a complete HTML page (based on the tables and/or charts they requested in the custom report definition) and styled them according to the rules. This truly was dynamic CSS. Thing is, there is potential for caching here too. The HTML page generates a dynamic link like this:
<link rel="stylesheet" href="/css/report.annual-sales.0001.css" type="text/css">
where 'annual-sales' is the report ID and 0001 is like a version. When the rules change you create a new version and each version for each report can be cached effectively.
Conclusion
So I can't say definitively whether external CSS files are appropriate or not to you but having seen and developed for each of the scenarios above I have a hard time believing that you can't get some form of caching out of your CSS at which point it should be external.
I've written about the issue of effective CSS in Supercharging CSS in PHP but the principles and techniques apply in any language, not just PHP.
You may also want to refer to the related question Multiple javascript/css files: best practices?
There is a method that both Google and Yahoo apply which benefit's from inline CSS. For the very first time visitors for the sake of fast loading, they embed CSS (and even JavaScript) in the HTML, and then in the background download the separate CSS and JS files for the next time.
Steve Souders (Yahoo!) writes the following:
[...] the best solution generally is
to deploy the JavaScript and CSS as
external files. The only exception
I’ve seen where inlining is preferable
is with home pages, such as Yahoo!'s
front page (http://www.yahoo.com) and
My Yahoo! (http://my.yahoo.com). Home
pages that have few (perhaps only one)
page view per session may find that
inlining JavaScript and CSS results in
faster end-user response times.
If you're generating HTML dynamically (say, from templates), embedding CSS allows you the opportunity to also generate the CSS dynamically using the same context (data, program state) as you have when you're producing the HTML, rather than having to set that same context up again on a subsequent request to generate the CSS.
For example, consider a page that uses one of several hundred images for a background, depending on some state that's expensive to compute. You could
List all of the several hundred images in rules in a seperate, static CSS file, then generate a corresponding class name in your dynamic HTML, or
Generate the HTML with a single class name, then on a subsequent request generate CSS with a rule for that name that uses the desired image, or
Do (2), but generate the CSS embedded in the HTML in a single request
(1) avoids redoing the expensive state computation, but takes a larger hit on traffic (more packets to move a much larger CSS file). (2) Does the state calculation twice, but serves up a smaller CSS file. Only (3) does the state calculation once and serves the result in a single HTTP request.
Browsers can cache the CSS files (unless it changes a lot). The bandwidth should not change, because the information is sent, no matter where you put it.
So unless the css quite static, putting it in the page costs less time to get.
I always use mix of both.
site-wide styles are in separate file (minified & gzipped),
any page-specific styles are put in <style> (I've set up my page templates to make it easy to insert bits of CSS in <head> easily at any time).
Yes and no. Use a .css file for most rules; your site should have a consistent look anyway. For rare, special case, or dynamically generated rules you can use inline 'style=""'. Anything that sticks should move into the .css, if only to make transcluding, mash-ups, etc. easier.
Keep it separate. HTML for centent, CSS for style, JavaScript for logic.