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? - cross-browser

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.

Related

Firefox won't block rendering of HTML when CSS links in head

I am having a problem that has persisted for a while. Everything I have read about Firefox specifies that if you include the <link> tags in the <head>, it will block rendering of the page until those resources have been loaded. To test, I set a breakpoint in the server-side resource rendering request, to ensure the CSS never loads.
In Chrome, Safari, and IE, the page remains blank or does not refresh until I resume the process and the CSS loads. This results in a blank screen, and then a properly styled page.
In Firefox, the raw HTML (with huge inline SVGs) shows on the page until I allow the CSS request to finish. This results in a flash of unstyled content (FOUC).
Here is a basic example of the markup
<!DOCTYPE html>
<html lang="en-us">
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<link rel="stylesheet" href="https://cdn.example.com/res/css/core.css?v=1a2b3c4d5e6f7890">
<link rel="stylesheet" href="https://cdn.example.com/res/css/site.css?v=1a2b3c4d5e6f7890">
<!-- meta tags, ads, etc -->
<title>My Page Title</title>
</head>
<body>
<header>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 125 24" class="site-logo">...</svg>
</header>
<!-- page content -->
<script type="text/javascript" src="https://cdn.example.com/res/js/site.js?v=1a2b3c4d5e6f7890">...</script>
</body>
</html>
I have a workaround for this issue, inlining <body style="display:none"> and then with core.css including body { display: block !important } in order to simulate the effect I expect for blocked rendering.
Am I missing something critical? Could there be another setting interfering with this behavior? I don't see this happening on other sites, and it goes against the behavior I would expect.
I'm seeing the same thing.
Based on a tip here, I placed a non-empty script tag (with just one space, <script> </script>) after the <link> in the header, and that seems to block rendering as expected.

How to load external JS libraries for the whole project

How do you load an external library so that it is available all over the project?Say for example I have the below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Starter Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="../public/css/bootstrap.css" rel="stylesheet">
<!-- Font Awesome core CSS -->
<link href="../public/css/font-awesome.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="../public/css/style.css" rel="stylesheet">
</head>
<body>
<p>This is a test</p>
<!-- Bootstrap core JavaScript-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
<script src="../jsLib/bootstrap.js"></script>
</body>
</html>
So this includes the jQuery, Bootstrap, font-awesome and my personal stylesheet as you can see.
Question: What if someone goes to another page in my site for instance: /profileSettings.html
Will I have to load all the libraries again?
Sorry if this is a simple question but I am completely new to front-end development.
Thanks in advance
As your code grows in size, you'll start using more sophisticated frameworks that may use something along the line of an MVC setup. Some of these frameworks allow you to define multiple "views"(think of them as HTML files for now) that are called from a single HTML file(say the index file).
For those aware of AngularJS, i'm referring to writing Angular UI views and the <ui-view> tag.
This will allow you to have your dependencies in a single file, and the other pages just load from this page.
More importantly.
I'm surprised noone has mentioned the use of require-js or other loaders.
It's particularly useful in cases where you have multiple JS dependencies, and multiple controllers in javascript.
Definitely check out loaders such as require-js
Each page is completely independant of every other page.
If you want a script to run on any given page, it has to be explicitly loaded into that page.
Yes. U have to include the required lib in each file if it is normal file without any framework.
You have to include the scriipt in every page because even thought it is a website, every page works seperately from another. All you need is a <script></script> tag.
Yes, if you look each page as separate page. You need to include it in every page.
But if you have a master page, then we can inherit the same from master page so, no need to add the Codes/Script again.
A cool option.
Load one JavaScript file (JS File) for every page. Then load all the JS File using that JS File as you like.
Example
var Device = {
Device_Type: 'Desktop',
//Scripts to be loaded in master page
Common_Scripts: [
'/SiteAssets/Bar.js',
],
//CSS to be loaded in master page
Common_CSS: [
'/SiteAssets/nav.css',
],
//to get device type
Get_Device_Type: function () {
var Getdevice = detect.parse(navigator.userAgent);
if (Getdevice.device.type != null) {
Device.Device_Type = Getdevice.device.type;
Device.Process_Device_Files(Device.Device_Type);
Device.Process_Common_Files();
Device.Process_Common_Scripts();
} else {
console.log("Detected Device type :" + Device.Device_Type)
}
},
//to load device based css files
Process_Device_Files: function (File_Type) {
File_Type = File_Type.toLowerCase();
$('head').append(
'<link rel="stylesheet" title="' + File_Type + '" href="announcement.css">'
);
},
//To load css files to be loaded in master page
Process_Common_Files: function () {
_.each(Device.Common_CSS, function (eachfile) {
Common.appendfile("css", eachfile);
});
},
//To remove previously loaded device files
Remove_Device_Files: function () {
$('link[title="tab"]').remove();
$('link[title="Mobile"]').remove();
$('link[title="desktop"]').remove();
},
//To load scripts to be loaded in master page
Process_Common_Scripts: function () {
_.each(Device.Common_Scripts, function (eachfile) {
Common.appendfile("script", eachfile);
});
},
}
$(document).ready(function () {
console.log('Render device based files')
Device.Remove_Device_Files();
Device.Get_Device_Type();
});
Usage
(Copy the Above code after Example until usage and paste it into a notepad and save it as device.js. Then include to the page. Then add the necessary JS to this codes. Sample files are already in the codes)
// Dependencies
https://github.com/darcyclarke/Detect.js?files=1

Embedding an HTML page keeps redirecting me?

I'm attempting to write a simple html doc to automatically refresh every 5 seconds. However, I want to embed a web page into this. I've tried embed tags, object tags, and iframe tags. However, each time the page refreshes I am automatically redirected to the page that I am trying to embed. My current code version is here:
<html>
<head>
<title>MEETME REFRESHER</title>
<script>
window.setInterval("reloadIFrame();", 30000);
function reloadIFrame()
{
document.frames["meetframe"].location.reload();
}
</script>
</head>
<body>
<iframe src="http://www.meetme.com/apps/home" name="meetframe"></iframe>
</body>
</html>
Am I using incorrect tags or is there something obvious that I'm missing here?
I have been on about 10 sites similar to W3Schools, however to no avail. Could it be an issue localized to Chrome? I remember doing something similar to this back in school, though using Internet Explorer. Any help or input is much appreciated!
Try this. Using sandbox attribute of an iframe. Source and more information here.
<html>
<head>
<title>MEETME REFRESHER</title>
<script>
window.setInterval("reloadIFrame();", 3000);
function reloadIFrame()
{
var fr=document.getElementById('meetframe');
if(fr!=null) document.getElementById("container").removeChild(fr);
var iframehtml="<iframe sandbox='allow-same-origin allow-scripts allow-popups allow-forms' src='http://www.meetme.com/apps/home' id='meetframe'></iframe>";
document.getElementById("container").innerHTML=iframehtml;
}
</script>
</head>
<body>
<div id = "container">
<iframe sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="http://www.meetme.com/apps/home" name = "meetframe" id="meetframe"></iframe>
</div>
</body>
</html>

Optimizing above-the-fold CSS

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.

highslide: can I get multiple popups of the same html content?

I'm building a course site for my students, with different 'chapters' accessed from different links. I would like to be able to have two or more popups of the same page so I can view different parts of the same chapter side by side. Is this possible in highslide (I don't think it is...). Any solution, using highslide or not, would be appreciated!
Here's a jsfiddle demo that lets you open multiple HTML popups. In this case, both links are opening the same page of stuff, but that's just to keep the demo setup simple - normally you would have each link opening a different iframed page, but for your specific requirement, I guess you'd be opening the same page twice, just like this demo. Open the first link, then drag it by the header to one side, and open the second link.
http://jsfiddle.net/MisterNeutron/Qk6U6/1/
The code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo by MisterNeutron</title>
<script type='text/javascript' src="http://highslide.com/highslide/highslide-full.js"></script>
<link rel="stylesheet" href="http://highslide.com/highslide/highslide.css">
<script type='text/javascript'>
hs.graphicsDir = 'http://highslide.com/highslide/graphics/';
hs.outlineType = 'rounded-white';
hs.wrapperClassName = 'draggable-header';
</script>
</head>
<body>
<div>
<a id="thumb1" href="http://highslide.com/examples/includes/include-short.htm" onclick="return hs.htmlExpand(this, { objectType: 'iframe' } )">First iframe</a>
<br><br>
<a id="thumb2" href="http://highslide.com/examples/includes/include-short.htm" onclick="return hs.htmlExpand(this, { objectType: 'iframe' } )">Second iframe</a>
</div>
</body>
</html>
I have used Dreamweavers menues to do give my site a dropdown list that I can then edit. Perhaps "open in new window" when you click the link will work. I have found that most clicks will default to open in the same window.