pagespeed insights Defer unused CSS and ofscreen images - pagespeed

I'v defered all my CSS using
media="none" onload="if(media!='all')media='all'"
and images using yall.min.js
But PageSpeed Insights continues claiming it (and the images are visibles too)
How do I could optimize this?
Thanks, Ari

I'm using JavaScript to asynchronously load external CSS files.
Similar to old solutions where one would put scripts before the closing </body> tag, I'm now introducing data-attributes to create <link> tags, so they're made asynchronous automatically:
HTML
<div data-dom="link" data-href="#asyncCssBundle" data-media="screen"></div>
<div data-dom="link" data-href="#printBundle" data-media="print"></div>
jQuery
/**
* Loads an array object of CSS files in async mode
* stops render blocking CSS loading
* good for fonts and #imports
* #prop {object} asyncLinkTag data representation of a link tag on a div element
*/
function loadCssAsync() {
var arr = [];
$.each($('[data-dom="link"]'), function () {
var el = $(this),
link = $('<link />').prop({
href: el.data('href'),
rel: el.data('rel') || 'stylesheet',
media: el.data('media') || 'screen'
});
arr.push(link);
});
$(document.head).append(arr);
}
$(function(){
loadCssAsync();
});
Additionally I distinguish in SCSS between above the fold CSS and backgrounds, fonts, print, ...
If you really want to put an effort in it, the above the fold CSS can go inline. But I find it rather tricky to pull this off on a larger project. So I'm fine with async loading backgrounds and fonts. However, for fonts it's now clear they're loaded afterwards, similar to a FOUC or call it "Flash of Loading Font". It's good to do some research on a solid substitute font so it doesn't change your layout too much.

Related

CSS to delete elements only for AMP posts

What CSS can I use to delete elements only for AMP posts on the website? AMP is an open-source framework, which reduces page size and eliminates javascript, so that website loading times could are less than 1 second.
I know how to hide an element is with display: none .
But I don't know how to implement that only on AMP posts.
This is the class of elements I want to remove only from the AMP post: lwptoc_toggle_label .
Class: lwptoc_toggle_label .
I have written the CSS .lwptoc_toggle_label {display: none} so that the element is removed, but the problem is I don't know how to apply that CSS only to AMP posts.
Can I use this: #media screen and (max-width:480px) {.lwptoc_toggle_label {display: none!important}} ?
Does anyone have an answer?
CSS is an adjective-like language, it is not functional.
JavaScript is the event-driven verb-like language. You need to put script elements inside of the head element if you plan to code professionally or you can just dump it at the bottom of the body element if you don't care about professionalism.
<script defer="true" type="application/javascript">
//<![CDATA[
// Put JavaScript code here, like the code below.
//]]>
</script>
Use Examples
You can then use the unique id attribute to reference an element you want to delete or use other methods of selecting an element. That reference becomes a parameter when calling the element_del function.
element_del('test12');//Instead of document.getElementById('test12')
element_del(document.getElementById('test15'));
element_del(document.getElementsByTagName('div')[4]);
Function
This is the function we use for an entire web platform. We don't use frameworks or libraries because you don't get paid for maintaining poor code.
function element_del(id)
{
if (typeof id=='string' && document.getElementById((id) && document.getElementById((id).parentNode.removeChild)
{
document.getElementById((id).parentNode.removeChild(document.getElementById((id));
}
else if (typeof id=='object' && typeof id.parentNode=='object')
{
id.parentNode.removeChild(id);
}
}

Detect style sheet load

What are good ways to detect whether a style sheet has loaded using vanilla JavaScript? I understand they do not have the same load event that images and scripts fire.
Loading as packed into a .js file (like with WebPack 'loaders') is not an option.
2022 update: All major browsers have now supported onload= on <link rel=stylesheet> tags for years, so that would be the obvious way to detect when CSS has loaded. Not also that external stylesheets in the head are blocking during page load, but can be added later with JS to make them asynchronous. It’s that scenario in which my question is relevant.
Test page: https://alanhogan.com/files/async-css/head-async-test-with-js.html
<link> elements have load and error events, but they are garanteed only for Chrome, Firefox and Opera. If you don't need to support IE or Safari, I think this is just enough:
<link rel="stylesheet" href="some_style.css" onload="anounceReady()">
EDIT: Just tested with IE11 and IE8, onload is supported but onerror isn't. I have no Mac at hand so I don't know how Safari handles them.
If you are going to support browsers don't have load event for <link> elements, or very old Chrome/Firefox, there is a commonly used easy dirty but working solution. Add a piece of probing rule set at the end of your CSS file, and detect the computed style of a certain probing element (usually invisible) via JavaScript.
HTML:
<div id="probe"></div>
CSS:
#probe {
position: absolute;
z-index: -1000;
}
JavaScript:
var probeStyle = getComputedStyle(document.getElementById('probe'));
probeStyle.zIndex; // expect "-1000" after CSS is loaded
Something like this:
function checkSheetLoaded (urlSpec) {
var ss = document.styleSheets;
for (var ii = 0, max = ss.length; ii < max; ii++) {
if (ss[ii].href.indexOf(urlSpec) >=0)
return true;
}
return false;
}
checkSheetLoaded('foo/bar.css');
Basically iterates over the stylesheet collection looking for a string match.

Pattern for organizing and loading CSS in Angular.js

In my Angular application I want to load the css files in a modular way - each module has it's own css file. This way I can add, remove or move modules easily.
The best way I found so far to do it is by creating a service:
angular.module('cssLoadingService', []).factory("CssLoadingService", function () {
return {
loadCss: function (url) {
if (document.createStyleSheet) { //IE
document.createStyleSheet(url);
} else {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = url;
document.getElementsByTagName("head")[0].appendChild(link);
}
}
};
});
Each controller loads it's template css.
Although I inject the path (by another service), still it feels like I'm breaking the seperation between the logic and the view.
It there any other elegant way (that doesn't includes packing the css files into one huge file)?
If your target is HTML5 browser, and assuming that you have a view per module, you can use scoped stylesheets in your views to accomplish this. If you wish to use a css file, you can use #import syntax to load the css file into the <style> tag. Here is a HTML of a view:
<div>
<style scoped>#import url('main.css')</style>
<h1>This is Main and should be Gray</h1>
</div>
Check out this plunker. It worked for me in the latest version of Chrome (27.x) and Firefox (21.x) under Mac OS X.
Please note that many recommend against the use #import for performance reasons. In fact, you can see that there is slight delay between loading of the page and style being applied.

Tool to find CSS styles available in a webpage

Say I'm embedding a bit of HTML code in an existing website. I'd like to know what CSS classes are already available. Currently I could do this as follows:
View the source for the page
Search for links that include .css files
Browse the contents of those until I find a useful class
That's tedious, and not exhaustive.
What's a better way?
EDIT You can also do this in Chrome:
Inspect Element
Select "Resources" tab
Navigate to Frames/../Stylesheets
View contents of individual stylesheets
I guess what I'm looking for is a higher level, interpreted view of the CSS styles available: not simply the contents of the CSS files. So if one style was defined identically in multiple places, I'd only want to see it twice. If two different styles applied to the same element, I'd want to see the two side by side.
Let's assume I can't do this by embedding code.
Press F12 in Chrome and select a magnifying glass.
In IE it's Also F12 and then select a little arrow.
Firefox has a similar feature or you can download Firebug which is great for web developers.
I think Web Developer plugin for firefox might be help you. You can add it from here.
The W3 CSS validator tool http://jigsaw.w3.org/css-validator/ will show all available css styles available to a webpage you specify, underneath a list of faulty styles.
copy this code immediately before the closing tag of the page's body :
I got code from here: http://snipplr.com/view/6488/
Tested in Chrome
//CODE
<div id="allclasses" style="text-align:left">
</div>
<script type="text/javascript">
var allTags = document.body.getElementsByTagName('*');
var classNames = {};
for (var tg = 0; tg< allTags.length; tg++) {
var tag = allTags[tg];
if (tag.className) {
var classes = tag.className.split(" ");
for (var cn = 0; cn < classes.length; cn++){
var cName = classes[cn];
if (! classNames[cName])
{
classNames[cName] = true;
}
}
}
}
var classList = [];
for (var name in classNames)
classList.push(name+'<br />');
document.getElementById('allclasses').innerHTML = classList.sort();
</script>

Correct way to include CSS after <head>

Apparently adding <link rel="stylesheet" ... in the document body is considered a bad practice by W3C standards. The same for adding <style> blocks in the body...
So are there any standard-compliant solutions to add CSS outside of the <head> tag? Like at the end of the document.
If you only want to include your CSS styles on a specific events, there's nothing stopping you from doing so at the head:
var linkElement = document.createElement("link");
linkElement.rel = "stylesheet";
linkElement.href = "path/to/file.css"; //Replace here
document.head.appendChild(linkElement);
This has the added benefit of adding your stylesheet in an async way, which doesn't block the browser from downloading anything else.
One way to solve that issue is to load the CSS with .get() and, appending it to the head tag only when needed:
JQUERY
var css = "foobar.css";
var callback = function() {
alert("CSS is now included");
// your jquery plugin for a navigation menu or what ever...
};
$.get(css, function(data){
$("<style type=\"text/css\">" + data + "</style>").appendTo(document.head);
callback();
});
The callback function is useful to allow script code that depends on the CSS file to be properly formatted, to run only after the CSS as been added!
Only HTML5 allows it with the scoped attribute, but make sure you declare the DOCTYPE correctly.
<style type="text/css" scoped>
.textbox {
color: pink
}
</style>
I think this standard gets largely ignored by most once you start doing things like server side programming or DHTML.
For static HTML files, you definitely can/should follow the rule of only including CSS within the HEAD tag but for conditional output and interactivity it can sometimes simplify things to have conditional styling as well. Consider that in the end, this convolutes the resulting document. Even though browsers may render it just fine, if you yourself were to look at the source, it's just plain easier to read if all the styles defining the layout/display were within the HEAD. There are, of course, a number of other examples and reasons as to why it's bad practice.
The HTML standard exists apart from things like server side scripting and DHTML i.e. it's not the HTML/SSS/JavaScript standard.
If you are talking about an external css sheet, then the correct way is as follows:
<link href="....link to your style...." rel="stylesheet">
If you want to include an inline css, then you just need to do as follows:
<style>
....Your style here...
</style>

Resources