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.
Related
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!
Where is the best place to put Jquery code (or separate Jquery file)? Will pages load faster if I put it in the footer?
Put Scripts at the Bottom
The problem caused by scripts is that
they block parallel downloads. The
HTTP/1.1 specification suggests that
browsers download no more than two
components in parallel per hostname.
If you serve your images from multiple
hostnames, you can get more than two
downloads to occur in parallel. While
a script is downloading, however, the
browser won't start any other
downloads, even on different
hostnames. In some situations it's not
easy to move scripts to the bottom.
If, for example, the script uses
document.write to insert part of the
page's content, it can't be moved
lower in the page. There might also be
scoping issues. In many cases, there
are ways to workaround these
situations.
An alternative suggestion that often
comes up is to use deferred scripts.
The DEFER attribute indicates that the
script does not contain
document.write, and is a clue to
browsers that they can continue
rendering. Unfortunately, Firefox
doesn't support the DEFER attribute.
In Internet Explorer, the script may
be deferred, but not as much as
desired. If a script can be deferred,
it can also be moved to the bottom of
the page. That will make your web
pages load faster.
EDIT: Firefox does support the DEFER attribute since version 3.6.
Sources:
http://www.w3schools.com/tags/att_script_defer.asp or better:
http://caniuse.com/#feat=script-defer
All scripts should be loaded last
In just about every case, it's best to place all your script references at the end of the page, just before </body>.
If you are unable to do so due to templating issues and whatnot, decorate your script tags with the defer attribute so that the browser knows to download your scripts after the HTML has been downloaded:
<script src="my.js" type="text/javascript" defer="defer"></script>
Edge cases
There are some edge cases, however, where you may experience page flickering or other artifacts during page load which can usually be solved by simply placing your jQuery script references in the <head> tag without the defer attribute. These cases include jQuery UI and other addons such as jCarousel or Treeview which modify the DOM as part of their functionality.
Further caveats
There are some libraries that must be loaded before the DOM or CSS, such as polyfills. Modernizr is one such library that must be placed in the head tag.
Only load jQuery itself in the head, via CDN of course.
Why? In some scenarios you might include a partial template (e.g. ajax login form snippet) with embedded jQuery dependent code; if jQuery is loaded at page bottom, you get a "$ is not defined" error, nice.
There are ways to workaround this of course (such as not embedding any JS and appending to a load-at-bottom js bundle), but why lose the freedom of lazily loaded js, of being able to place jQuery dependent code anywhere you please? Javascript engine doesn't care where the code lives in the DOM so long as dependencies (like jQuery being loaded) are satisfied.
For your common/shared js files, yes, place them before </body>, but for the exceptions, where it really just makes sense application maintenance-wise to stick a jQuery dependent snippet or file reference right there at that point in the html, do so.
There is no performance hit loading jquery in the head; what browser on the planet does not already have jQuery CDN file in cache?
Much ado about nothing, stick jQuery in the head and let your js freedom reign.
Nimbuz provides a very good explanation of the issue involved, but I think the final answer depends on your page: what's more important for the user to have sooner - scripts or images?
There are some pages that don't make sense without the images, but only have minor, non-essential scripting. In that case it makes sense to put scripts at the bottom, so the user can see the images sooner and start making sense of the page. Other pages rely on scripting to work. In that case it's better to have a working page without images than a non-working page with images, so it makes sense to put scripts at the top.
Another thing to consider is that scripts are typically smaller than images. Of course, this is a generalisation and you have to see whether it applies to your page. If it does then that, to me, is an argument for putting them first as a rule of thumb (ie. unless there's a good reason to do otherwise), because they won't delay images as much as images would delay the scripts. Finally, it's just much easier to have script at the top, because you don't have to worry about whether they're loaded yet when you need to use them.
In summary, I tend to put scripts at the top by default and only consider whether it's worthwhile moving them to the bottom after the page is complete. It's an optimisation - and I don't want to do it prematurely.
Most jquery code executes on document ready, which doesn't happen until the end of the page anyway. Furthermore, page rendering can be delayed by javascript parsing/execution, so it's best practice to put all javascript at the bottom of the page.
Standard practice is to put all of your scripts at the bottom of the page, but I use ASP.NET MVC with a number of jQuery plugins, and I find that it all works better if I put my jQuery scripts in the <head> section of the master page.
In my case, there are artifacts that occur when the page is loaded, if the scripts are at the bottom of the page. I'm using the jQuery TreeView plugin, and if the scripts are not loaded at the beginning, the tree will render without the necessary CSS classes imposed on it by the plugin. So you get this funny-looking mess when the page first loads, followed by the proper rendering of the TreeView. Very bad looking. Putting the jQuery plugins in the <head> section of the master page eliminates this problem.
Although almost all web sites still place Jquery and other javascript on header :D , even check stackoverflow.com .
I also suggest you to put on before end tag of body. You can check loading time after placing on either places. Script tag will pause your webpage to load further.
and after placing javascript on footer, you may get unusual looks of your webpage until it loads javascript, so place css on your header section.
For me jQuery is a little bit special. Maybe an exception to the norm. There are so many other scripts that rely on it, so its quite important that it loads early so the other scripts that come later will work as intended. As someone else pointed out even this page loads jQuery in the head section.
Just before </body> is the best place according to Yahoo Developer Network's Best Practices for Speeding Up Your Web Site this link, it makes sense.
The best thing to do is to test by yourself.
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.
If I have an HTML page that includes some JavaScript, for example:
<script type="text/javascript" src="http://example.com/code.js" async></script>
And I want to add some CSS, which of the following 2 options is faster, performance-wise?
Option 1
(More "Network Heavy")
Including the CSS in a separate inline tag, for example:
<link rel="stylesheet" type="text/css" href="http://www.example.com/style.css">
OR
Option 2
(More "JavaScript Execution Heavy", since it requires DOM manipulation) injecting the CSS into the DOM from inside the included JavaScript file, for example (taken from: https://stackoverflow.com/a/707580/1785003]1):
var css = document.createElement("style");
var css = "text/css";
css.innerHTML = "strong { color: red }";
document.body.appendChild(css);
The 2nd option removes a network request from the page, but requires DOM manipulation, which might be costly in Mobile Device browsers.
So which is better?
I do not believe there is much of a difference between a mobile device and regular browser in the way they load and cache pages so I would treat them the same.
Having CSS in your JavaScript is going to be a maintenance nightmare. Probably not worth any tiny (if any) optimisation gain. As Pekka pointed out after initial load it will cached.
You will be better off targeting other performance optimisations first. Like Minify CSS and javascripts, CSS sprites etc . Use a tool such as yslow to help show where performance optimisations can be made.
Also most browsers can make at least 4 concurrent request to the same host so that the CSS and Javascript , HTML can all be downloaded at the same time. See here
Answering from Performance POV:
Using CSS is a better option.
Reason
Performance is not just measured in network bandwidth consumption. JS blocks the rendering of the page till they're completely downloaded.
(Note: html 5 now suports
<script type="text/javascript" src="http://example.com/code.js" async></script>
which frees loading of rest of your markup in parallel.)
Once css is fetched for first time, then it is neither downloaded nor executed (vs javascript). This is delight for returning users.
Solution
Use the external css and keep it at the top of your semantics (in <head> section, preferably).
Use external js and keep it at the bottom of the page (near the </body> tag)
Background:
Have worked with Yahoo! and adhered to their Best Frontend practices.
Put Stylesheets at the Top
Put Scripts at the Bottom
The CSS file will definently render faster, once it's downloaded and processed, since browser are optimised for this. Applying via JS means that you need to wait for the document to load, then seek elements, apply styling, and then allow the browser to do its magic.
In my experience, adding a CSS file for anything more than dynamic behavior by far outweights any "speed" decrease due to maintainability (how easy it is to change something) and because you can actually restyle your page without editing the code part, which can break things (if for instance you change the JS generating the styles and forget a quote, you break the page, and lose all JS for that page).
The only situation where styling via JS is ok for non-dynamic behavior, is when its a few lines all in all, and even then I'm cautious.
On a website, I'm experiencing a "flash" of white that occurs between page loads. It looks bad because I'm using a background image and when the page loads, the background images flash before it comes onto the screen (take a look for yourself). This issues occurs in chrome and IE but not in firefox.
The site has a way of preloading stuff. Every element on the page is in a div wrapper #website which is initially at display:none, and every image is in a div wrapper #website-images which is also hidden. Then the site (using a jquery plugin) checks to see if all the images in #website-images are done loading, once they are a cookie is set to remember that this user has loaded the images already so it won't go through the preloading process once they go to another page or reload the current one, then a call to $("#website").show() is made to display the webpage.
So what could be causing this flickering between the page loads? Is it my way of preloading images? I've added different doctypes, and changed meta information but NOTHING has worked. I'm really lost here, does anyone have any ideas or insights?
This is happening because the DOMLoaded event is fired enough milliseconds before the page actually renders.
In a nutshell, this means you have to optimise your website's speed. This doesn't mean to make it download faster, but it means to download in the correct order, in a non-blocking way.
Step one: Your markup
1)
It seems there is a lot you can do to optimise your markup. Firstly, the order of stylesheets and JavaScripts can be optimised. To ensure CSS files are downloaded asynchronously, you always have to include external CSS before external JavaScript files. style.css is downloaded after some/all of your JavaScript calls.
There is 1 script block found in the head between an external CSS file and another resource. To allow parallel downloading, move the inline script before the external CSS file, or after the next resource.
2)
Your main JavaScript file is inline within your markup. Not only does this block the page download until the script has finished downloading, but having it before your content is probably causing (or adding to) the white flash.
Loading your script asynchronously in the head is my preferred method. You will then have to trigger your script when the DOM has finished loading, or you can achieve the same result by placing the script at the bottom of the body tag.
Step two: Harness the browser's capabilities
1) Looking at the http headers, there are 28 items being served as separate HTTP calls, that are not being cached on the browser (including the html pages, jpg images, stylesheets and JavaScript files).
These items are explicitly non-cacheable, and this can be easily fixed by editing your webserver's configuration.
2) Enable gzip compression. Most web browsers (yes, even IE) supports gzip decompression, and most (if not all) web servers support compressing using gzip. You could even go overkill and look into SPDY, which is an alternative lighter HTTP protocol (supported in Chrome and Firefox).
Step three: Content serving
There are around 30 individual items being served from your domain. Firstly, consider how you could reduce this number of requests. 30 HTTP requests per page view is a lot. You can combat this using the following methods:
1) Paralleled downloads across multiple hostnames. Browsers currently limit the number of concurrent connections to a single domain. Serving your images from a separate domain (for example, img.bigtim.ca) can allow them to be served in parallel to other content.
2) Combine multiple items into one. Many items that are downloaded are purely style content, such as the logo, menu elements, etc. These can be combined into a single image (downloaded only once), and split using CSS. This is called CSS spriting. Stack Overflow does this: look here.
3) If you cannot reduce the amount of items needing downloading, you could reduce the load on your server (and in turn, the client's browser) by serving static content from a cookieless domain. Stack Overflow does this with all their static content such as images, stylesheets and scripts.
Step four: Optimise your own code
There's only so much that HTTP and browser technology can do to help your website's speed. This last step is down to you.
1) Is there any reason you choose to host jquery yourself? Jquery's download page shows multiple CDNs where you can point to for speedy, cached script downloading.
2) There are currently over 20 unused CSS rules within your stylesheets (that's 36% of your entire CSS file). Have a re-think of what is really needed.
3) The main chunk of JavaScript (at the top of your body tag) seems to be a hack to attempt to speed things up, but is probably not helping anything.
A cookie is being set to specify whether or not the page has faded in yet. Not only are you using JavaScript to perform a transition which can happily be performed by CSS, but more than half of the script is used to define the functionality for reading and writing the cookie.
Seeing things like this: $("body").css ("background-image", "url('images/background.png')"); and $("#website").show (); usually gets me ranting about "separation of concerns", but this answer is long enough now so hopefully you can see that it is bad practice to mix style and functionality in the same code.
Addendum: Looking at the code, there is no need for jquery at all to
perform what you are doing. But then again, there is no need to
perform what you are doing, so you could probably do better without any
JavaScript at all.
Move your javascript to the end of the html just before closing the body tags. Sometimes it helps.
I know this is old thread but here is a hack I tried and works.
The idea is not to display anything while CSS is loaded completely.
in html file:
<body style="display:none">
in your CSS, the last line:
body{display:block !important}
CSS is render-blocking.
Divide you CSS into 2 parts -
Critical CSS
Non-Critical CSS
Make Critical CSS load with the page. It should come embedded within the head tag.
Make Non-critical CSS lazy load via ajax.
This will result in serious performance optimization in your webpage leading to less white-screen time.
Also, you can consider loading your Javascript in async/defer way.