Optimizing above-the-fold CSS - html

I want to fix the "Eliminate render-blocking JavaScript and CSS in above-the-fold content" requirement for better PageSpeed Insights score but I'm not quite sure what the best approach to this problem is.
How can I best balance the page load for new visitors and returning visitors?
When should I load my CSS asynchronously, when not?
Should I maybe only inline CSS for small screens?
Relevant presentation: Optimizing the Critical Rendering Path
Example
Since inlining lots of CSS leads to slower page loads on subsequent visits, I could serve different versions for recurring visitors based on a cookie. For detecting above-the-fold CSS I could use the bookmarklet from this article: paul.kinlan.me/detecting-critical-above-the-fold-css/
For new visitors:
<!DOCTYPE HTML>
<html>
<head>
<title>New Visitor</title>
<style><!-- insert above the fold css here --></style>
<noscript><link rel="stylesheet" href="style.css"></noscript>
</head>
<body>
<!-- insert content here -->
<script>
// load css
var node = document.createElement('link');
node.rel = 'stylesheet';
node.href = 'style.css';
document.head.appendChild(node);
// set cookie
var exp = new Date();
exp.setTime(exp.getTime() + 3600 * 1000);
document.cookie = 'returning=true; expires=' + exp.toUTCString() + '; path=/';
</script>
</body>
</html>
For returning visitors:
<!DOCTYPE HTML>
<html>
<head>
<title>Returning Visitor</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- content here -->
</body>
</html>
Any problems with this approach?

There is such a thing as over-optimizing. Your example approach adds unneeded complexity. What you should be looking at is a minimal stylesheet for the head section that will make everything above the fold make sense and conform to the design and layout (but not necessarily respect it 100%).
For the rest of the page just load the rest of the CSS at the end of the page and you should be fine. If what matters to you is above the fold, then so does the first CSS you load. Everything else can be delayed.

Related

Is there a way to insert HTML code into a document that is comparable to the simplicity of inserting css/js code?

I know that it is best practice to have separate files for CSS and JS so that this:
<head>
<style>
<!--CSS code -->
<!--CSS code -->
</style>
</head>
<body>
<!--HTML code -->
<!--HTML code -->
<script>
<!--JS code -->
<!--JS code -->
</script>
</body>
becomes this:
<head>
<link rel="stylesheet" type="text/css" href="my-blackjack-file.css">
</head>
<body>
<!--HTML code -->
<!--HTML code -->
<script src="my-javascript-file.js"></script>
</body>
But is there an equally simple way to do this for the html portion of the code for the sake of better organization? I have seen some suggestions online for including html pages, but they seem to be talking about iframes and use some fairly complex (for me) javascript. Is there something more akin to
<body>
<link rel="stylesheet" type="html" href="my-html-file.html">
</body>
in order to separate a long document into several files that run as if they were on the same page?
This is work in progress and may (or may not) be supported in the next version.
Until then, unless you output the HTML through some server-side technology such as JSPs or Velocity, which support templating, you can only use iframes or AJAX as a workaround for including HTML.
Depending on the development environment you can use partial views.
<body>
#Html.RenderPartial("descriptiveNameHere.html");
<script src="my-javascript-file.js"></script>
</body>
Or something to that effect. There is additional syntax of course, but maybe this will put you on the track you're looking for.
Ultimately you will still have an html file with your "HTML Code". But if you're looking to reduce the complexity of a large file by moving chunks into external files, partial views are a way to do so.

CSS Modules Inheritance Image Height 100% Issue

For some reason, my images are being vertically distorted and I can't figure out as to why (See image below).
1
2
3
Long story short what I've done is moved all my single-page-app (SPA) app code/styles and created a server-side rendered codebase. I haven't changed any of the styles or tweaked anything, yet for some reason it's distorting. This is the working styles / code from the SPA app.
4
The only hack that seems to do much of anything is when I take out the
`height:100%;`
on the images, but this has a negative effect with filling out the images which is what I'm wanting.
5
I'm using CSS Modules and have some idea that it could be related to some inheritance issues that I'm unaware of. Thanks in advance, this bug is really been driving me crazy.
I've created a fiddle that represents the working code from the SPA. https://jsfiddle.net/0L0rdk6y/
Fixed this issue by adding
<!DOCTYPE html>
in my render method when returning server side html
Example is
return
<!DOCTYPE html>
<html>
<head>
${renderBaseMeta()}
${helmet.title.toString()}
${helmet.meta.toString()}
<link rel="stylesheet" href="main.css">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
</head>
<body>
<div id="root">${content}</div>
<script>
window.INITIAL_STATE = ${serialize(store.getState())}
</script>
<script src="bundle.js"></script>
</body>
</html>
;

Why DHTML behavior not work in IE8 if document.write is executed in <head>?

We have a 3rd party web application which works on in IE6, but not works in IE8.
The sample code is like below, the "message from .htc" message will popup in IE6, but not popup in IE8.
test.html
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
<script type='text/javascript'>
//if comment the following line, or move this script in <body>,
//then HTC will work in IE8
document.write ("<h1>document.write() in <head></h1> some calendar codes");
</script>
</head>
<body style='behavior:url(test.htc)'>
HTML Components test
</body>
</html>
test.htc
<script type='text/javascript'>
alert ("message from .htc");
</script>
Why this happened? Any compatible documents to explain this?
Solution
As #Quentin said or another expert from http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/c1f546f6-d7e1-4b46-a1c9-8f02eaf1286b said, IE8 probably make rules strictly compared to IE6, and IE8 may treat it as an corrupt HTML document.
So, I decide to to use document.createElement to create elements dynamically instead of document.write, and insert these elements to DOM after some seconds delay. After some tests, it finally worked both in this test.html and real application.
test-ie8-compatible.html
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
<script type='text/javascript'>
function Delay_CreateCalendar()
{
var oContainer = document.createElement ("div");
var oCalendarIFrame = document.createElement ("iframe");
oContainer.appendChild (oCalendarIFrame);
document.body.insertBefore (oContainer);
}
setTimeout (Delay_CreateCalendar, 2000);
</script>
</head>
<body style='behavior:url(test.htc)'>
dhtml HTC 测试
</body>
</html>
Presumably, despite the namespace, you are serving the document as text/html. In HTML the start and end tags for the head and body element are optional. H1 elements are not allowed inside the head.
Thus, when you document.write and H1 inside the end, you trigger the end of the head and the start of the body.
I assume that IE then ignores the start tag for the body element as it would create a second body (which also isn't allowed).

How to redirect one HTML page to another on load

Is it possible to set up a basic HTML page to redirect to another page on load?
Try using:
<meta http-equiv="refresh" content="0; url=http://example.com/" />
Note: Place it in the <head> section.
Additionally for older browsers if you add a quick link in case it doesn't refresh correctly:
<p>Redirect</p>
Will appear as
Redirect
This will still allow you to get to where you're going with an additional click.
I would use both meta, and JavaScript code and would have a link just in case.
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="0; url=http://example.com">
<script type="text/javascript">
window.location.href = "http://example.com"
</script>
<title>Page Redirection</title>
</head>
<body>
<!-- Note: don't tell people to `click` the link, just tell them that it is a link. -->
If you are not redirected automatically, follow this <a href='http://example.com'>link to example</a>.
</body>
</html>
For completeness, I think the best way, if possible, is to use server redirects, so send a 301 status code. This is easy to do via .htaccess files using Apache, or via numerous plugins using WordPress. I am sure there are also plugins for all the major content management systems. Also, cPanel has very easy configuration for 301 redirects if you have that installed on your server.
JavaScript
<script type="text/javascript">
window.location.href = "http://example.com";
</script>
Meta tag
<meta http-equiv="refresh" content="0;url=http://example.com">
I would also add a canonical link to help your SEO people:
<link rel="canonical" href="http://www.example.com/product.php?item=swedish-fish"/>
This is a sum up of every previous answers plus an additional solution using HTTP Refresh Header via .htaccess
HTTP Refresh Header
First of all, you can use .htaccess to set a refresh header like this
Header set Refresh "3"
This is the "static" equivalent of using the header() function in PHP
header("refresh: 3;");
Note that this solution is not supported by every browser.
JavaScript
With an alternate URL:
<script>
setTimeout(function(){location.href="http://example.com/alternate_url.html"} , 3000);
</script>
Without an alternate URL:
<script>
setTimeout("location.reload(true);",timeoutPeriod);
</script>
Using the window object:
<script>
window.location.reload(true);
</script>
Meta Refresh
You can use meta refresh when dependencies on JavaScript and redirect headers are unwanted
With an alternate URL:
<meta http-equiv="Refresh" content="3; url=http://example.com/alternate_url.html">
Without an alternate URL:
<meta http-equiv="Refresh" content="3">
Using <noscript>:
<noscript>
<meta http-equiv="refresh" content="3" />
</noscript>
Optionally
As recommended by Billy Moon, you can provide a refresh link in case something goes wrong:
If you are not redirected automatically: <a href='http://example.com/alternat_url.html'>Click here</a>
Resources
Wikipedia Meta refresh
The Performance Impact of META REFRESH
Refresh (reload) a page once using jQuery?
If you are looking forward to follow modern web standards, you should avoid plain HTML meta redirects. If you can not create server-side code, you should choose JavaScript redirect instead.
To support JavaScript-disabled browsers add a HTML meta redirect line to a noscript element. The noscript nested meta redirect combined with the canonical tag will help your search engine rankings as well.
If you would like to avoid redirect loops, you should use the location.replace() JavaScript function.
A proper client-side URL redirect code looks like this (with an Internet Explorer 8 and lower fix and without delay):
<!-- Pleace this snippet right after opening the head tag to make it work properly -->
<!-- This code is licensed under GNU GPL v3 -->
<!-- You are allowed to freely copy, distribute and use this code, but removing author credit is strictly prohibited -->
<!-- Generated by http://insider.zone/tools/client-side-url-redirect-generator/ -->
<!-- REDIRECTING STARTS -->
<link rel="canonical" href="https://stackoverflow.com/"/>
<noscript>
<meta http-equiv="refresh" content="0; URL=https://stackoverflow.com/">
</noscript>
<!--[if lt IE 9]><script type="text/javascript">var IE_fix=true;</script><![endif]-->
<script type="text/javascript">
var url = "https://stackoverflow.com/";
if(typeof IE_fix != "undefined") // IE8 and lower fix to pass the http referer
{
document.write("redirecting..."); // Don't remove this line or appendChild() will fail because it is called before document.onload to make the redirect as fast as possible. Nobody will see this text, it is only a tech fix.
var referLink = document.createElement("a");
referLink.href = url;
document.body.appendChild(referLink);
referLink.click();
}
else { window.location.replace(url); } // All other browsers
</script>
<!-- Credit goes to http://insider.zone/ -->
<!-- REDIRECTING ENDS -->
The following meta tag, placed between inside the head, will tell the browser to redirect:
<meta http-equiv="Refresh" content="seconds; url=URL">
Replace seconds with the number of seconds to wait before it redirects, and replace URL with the URL you want it to redirect to.
Alternatively, you can redirect with JavaScript. Place this inside of a script tag anywhere on the page:
window.location = "URL"
It would be better to set up a 301 redirect. See the Google's Webmaster Tools article 301 redirects.
You could use a META "redirect":
<meta http-equiv="refresh" content="0; url=http://new.example.com/address" />
or JavaScript redirect (note that not all users have JavaScript enabled so always prepare a backup solution for them)
<script language="javascript">
window.location = "http://new.example.com/address";
</script>
But I'd rather recommend using mod_rewrite, if you have the option.
As soon as the page loads, the init function is fired and the page is redirected:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script>
function init()
{
window.location.href = "www.wherever.com";
}
</script>
</head>
<body onload="init()">
</body>
</html>
Place the following code between the <HEAD> and </HEAD> tags of your HTML code:
<meta HTTP-EQUIV="REFRESH" content="0; url=http://example.com/index.html">
The above HTML redirect code will redirect your visitors to another web page instantly. The content="0; may be changed to the number of seconds you want the browser to wait before redirecting.
Put the following code in the <head> section:
<meta http-equiv="refresh" content="0; url=http://address/">
I found a problem while working with a jQuery Mobile application, where in some cases my Meta header tag wouldn't achieve a redirection properly (jQuery Mobile doesn't read headers automatically for each page so putting JavaScript there is also ineffective unless wrapping it in complexity). I found the easiest solution in this case was to put the JavaScript redirection directly into the body of the document, as follows:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="refresh" content="0;url=myURL" />
</head>
<body>
<p>You are not logged in!</p>
<script language="javascript">
window.location = "myURL";
</script>
</body>
</html>
This seems to work in every case for me.
I use a script which redirects the user from index.html to relative url of Login Page
<html>
<head>
<title>index.html</title>
</head>
<body onload="document.getElementById('lnkhome').click();">
Go to Login Page
</body>
</html>
The simple way which works for all types of pages is just to add a meta tag in the head:
<html>
<head>
...
<meta HTTP-EQUIV="REFRESH" content="seconds; url=your.full.url/path/filename">
...
</head>
<body>
Don't put much content, just some text and an anchor.
Actually, you will be redirected in N seconds (as specified in content attribute).
That's all.
...
</body>
</html>
You can auto redirect by HTTP Status Code 301 or 302.
For PHP:
<?php
Header("HTTP/1.1 301 Moved Permanently");
Header("Location: http://www.redirect-url.com");
?>
You should use JavaScript. Place the following code in your head tags:
<script type="text/javascript">
window.location.assign("http://www.example.com")
</script>
Just use the onload event of the body tag:
<body onload="window.location = 'http://example.com/'">
Razor engine for a 5 second delay:
<meta http-equiv="Refresh"
content="5; url=#Url.Action("Search", "Home", new { id = #Model.UniqueKey }))">
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Redirect to a page</title>
</head>
<body onload="window.location.assign('http://example.com')">
</body>
</html>
Just for good measure:
<?php
header("Location: http://example.com", true, 302);
exit;
?>
Make sure there are no echo's above the script otherwise it will be ignored.
http://php.net/manual/en/function.header.php
As far as I understand them, all the methods I have seen so far for this question seem to add the old location to the history. To redirect the page, but do not have the old location in the history, I use the replace method:
<script>
window.location.replace("http://example.com");
</script>
This is a redirect solution with everything I wanted, but I could not find in a nice clean snippet to cut & paste.
This snippet has a number of advantages:
lets you catch and retain any querystring parameters folks have on their URL
makes the link unique to avoid unwanted caching
lets you inform users of the old and new site names
shows a settable countdown
can be used for deep-link redirects as retains parameters
How to use:
If you migrated an entire site then on the old server stop the original site and create another with this file as the default index.html file in the root folder. Edit the site settings so that any 404 error is redirected to this index.html page. This catches anyone who accesses the old site with a link into a sub-level page etc.
Now go to the opening script tag and edit the oldsite and newSite web addresses, and change the seconds value as needed.
Save and start your website. Job done - time for a coffee.
<!DOCTYPE html>
<html>
<head>
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">
<style>
body { margin: 200px; font: 12pt helvetica; }
</style>
</head>
<body>
</body>
<script type="text/javascript">
// Edit these to suit your needs.
var oldsite = 'http://theoldsitename.com'
var newSite = "https://thenewsitename.com";
var seconds = 20; // countdown delay.
var path = location.pathname;
var srch = location.search;
var uniq = Math.floor((Math.random() * 10000) + 1);
var newPath = newSite + path + (srch === '' ? "?" + uniq : srch + "&" + uniq);
document.write ('<p>As part of hosting improvements, the system has been migrated from ' + oldsite + ' to</p>');
document.write ('<p>' + newSite + '</p>');
document.write ('<p>Please take note of the new website address.</p>');
document.write ('<p>If you are not automatically redirected please click the link above to proceed.</p>');
document.write ('<p id="dvCountDown">You will be redirected after <span id = "lblCount"></span> seconds.</p>');
function DelayRedirect() {
var dvCountDown = document.getElementById("dvCountDown");
var lblCount = document.getElementById("lblCount");
dvCountDown.style.display = "block";
lblCount.innerHTML = seconds;
setInterval(function () {
seconds--;
lblCount.innerHTML = seconds;
if (seconds == 0) {
dvCountDown.style.display = "none";
window.location = newPath;
}
}, 1000);
}
DelayRedirect()
</script>
</html>
You don't need any JavaScript code for this. Write this in the <head> section of the HTML page:
<meta http-equiv="refresh" content="0; url=example.com" />
As soon as the page loads at 0 seconds, you can go to your page.

How to preload JavaScript and CSS files in the background, to have them ready in the browser cache when the user goes to the main page?

I want to preload a JS file and a CSS file from the landing page to optimize the main site load, after the conversion in the landing. I was looking for information about this and finally tried to get this done using:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'jsUrl');
xhr.send('');
xhr = new XMLHttpRequest();
xhr.open('GET', 'cssUrl');
xhr.send('');
With Firefox this great, but with Chrome it seems that the XHR calls are cached in a different cache than the css and js files.
We don´t use JQuery, the landing page must be lightweight (less load, more conversion rate).
Do you have any recommendation of another way to solve the original problem? (preload components)
Do you know how to make Chrome cache these requests?
This is a tested solution in a high volume site that works.
First, to avoid a competition between the landing page resources and the preloaded resources for the bandwith you could delay the load with javascript:
var prevOnLoad=window.onload;
function onLoadPreloadComponents() {
if(prevOnLoad) {
try{
prevOnLoad();
}catch(err){
}
}
preloadSiteComponents();
}
window.onload=onLoadPreloadComponents;
This is not the way I solved this because in my use case a flash event (using the Flash to JS brigde) signals when the landing was finally loaded. But the previous code must works as well. When the load page event is fired by the browser this function will execute previous onLoad code and the preloading.
I put an empty div cointainer where the iframe will be loaded.
<div id="mainSiteComponentsContainer" style="display: none;">
</div>
And the function code is:
function preloadSiteComponents() {
try{
document.getElementById('mainSiteComponentsContainer')
.innerHTML=
"<iframe src=\"http://www-components.renxo-cdn.net/preload-site-components-data-url-scheme-version-1.2.84-css-1.0.53.html\" frameborder=\"no\" height=\"0px\" width=\"0px\"></iframe>";
}catch(err) {
}
}
As you could see, the link url to iframe is dynamic, it changes between differents plataform versions (different deployments) to avoid unwanted browser cache with a new deployments.
The HTML that will be in the iframe could be something like this (for example):
<html class=" gecko win js" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="noindex,nofollow" name="robots">
<script src="http://www-components.renxo-cdn.net/scripts/lib-1.2.84.js" type="text/javascript">
<link href="http://www-components.renxo-cdn.net/styles/skin-data-url-scheme-1.0.53.css" media="all" type="text/css" rel="stylesheet">
</head>
<body> </body>
</html>
Here you could see the links to the components that I want to preload.
Finally, the div cointainer will have the iframe. After the onLoad event:
<div id="mainSiteComponentsContainer" style="display: none;">
<iframe width="0px" height="0px" frameborder="no" src="http://www-components.renxo-cdn.net/preload-site-components-data-url-scheme-version-1.2.84-css-1.0.53.html">
<html class=" gecko win js" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="noindex,nofollow" name="robots">
<script src="http://www-components.renxo-cdn.net/scripts/lib-1.2.84.js" type="text/javascript">
<link href="http://www-components.renxo-cdn.net/styles/skin-data-url-scheme-1.0.53.css" media="all" type="text/css" rel="stylesheet">
</head>
<body> </body>
</html>
</iframe>
</div>
You could see the working solution here.
Use Firebug to see the delayed load of this components.
Random thought:
Maybe you could include a hidden IFrame in your landing page which loads a page that does nothing but include your javascript and CSS files. If you trigger the loading of that IFrame in your javascript then it shouldn't block the landing page's loading or rendering, yet the script and css files would be loaded by the browser in the same way that it would for any other page.
Haven't tried this but adding this to the BOTTOM of your landing HTML should work:
<!-- Preload -->
<img src="/path/to/preload.js" style="display:none">
<img src="/path/to/preload.css" style="display:none">
The browser doesn't actually care that the resources aren't images it should fetch and cache them anyway. Browser typically load resources in page order so you wont delay other elements and with display:none you probably won't block rendering either.
Downside is you won't preload images defined in the CSS or #imports unless you preload them manually.