Hidden divs - reducing latency with style display none + javascript - javascript

I commonly use hidden divs on my pages until they need to be unhidden with javascript. I used to do the initial hiding with javascript too, but now moved away to hiding them with css to guarantee that the hiding takes place (js disabled in the browser). Also there was a latency issue with js hiding (waiting for the js to load).
My problem is that with css, there's still some latency, and so I end up including the style with the markup like below, and I kind of hate doing it, makes me feel like I'm doing something wrong..
<div style="display:none;">
content
</div>
How often do you guys do this? and is there a way I can get the css or js to somehow load BEFORE the rest of the markup?
Thanks in advance

Include the css in an inline style block at the top of the page:
<style>
.hidden: { display: none; }
</style>
Then annotate your div with the needed class:
<div class="hidden"> ... </div>
The upshot of this approach is that to show the element, you don't need to set display to block, you can just add/remove the class from the element with JavaScript. This works out better because not every element needs display=block (tables and inline elements have different display modes).
Despite what another poster said, it's not bad practice. You should separate your CSS into presentational and functional markup - functional one controls such logical things as whether or not something gets shown, presentational one just determines how to show it. There is no issue putting functional CSS inline to avoid the page jumping around.

I may get hammered for this, but in a lot of apps, when I want to avoid this latency I use inline script tags immediately after the content, like this:
<div id="hidden-div">
content
</div>
<script type="text/javascript">
$('#hidden-div').hide();
</script>
Or if you're not using jQuery:
<div id="hidden-div">
content
</div>
<script type="text/javascript">
document.getElementById('hidden-div').style.display = 'none';
</script>
At first this seems clunky; however, there are a couple of reasons why I take this approach:
The hiding is immediate (no waiting
for the entire DOM to load)
People with JavaScript disabled will
still see the content, whereas if we
hide it with CSS there is no way for
non-JS users to make it visible
again.
Hope this helps!

I would suggest moving your display:none rule to the top of the stylesheet so it's the first or first of a few parsed, though to be honest it would really depend on how many http requests/media resources you have.
You could try throwing the js before the end body tag and making sure the css is at the top, and the css stylesheet that hides those elements is the very first one linked.

Depends on the browser. Opera, WebKit and Konqueror load CSS and JavaScript in parallel (all CSS is loaded before being applied, however).
display:none is the best solution, but you can use inline-css (like in your description) which is directly loaded with the page, if you want to be extra cautious, its bad practice though.

Related

Performance gain from CSS display:none or $.remove()?

I'm developing a Firefox WebExtension for a foreign website. It has many scripts and ads that I want to remove. I have two files in my extension, a CSS and a JS file. In CSS file, I hide these elements:
/* Hide some parts before removing them */
aside,
#site-footer,
.ads,
iframe,
script {
display: none
}
And in JS file I remove them with jQuery:
// List of selectors to remove
var removeList = [
'aside',
'#site-footer',
'.ads',
'iframe',
'script'
];
// Remove them
$(removeList.join(",")).remove();
I realised that hiding elements using CSS is much faster than jQuery.remove() function. My question is that, do I really need removing these elements after hiding with CSS? Can there be any performance when I remove them from DOM? I mean, for example, do iframes still use CPU after display:none? If so I should continue using JS code. Otherwise what potential gains can offer this extra removal?
Property display:none only hiding your element but not deleting from DOM. And all your iframes will still use CPU after this, because CSS controls only how element shows on screen.
After some research, I decided to use both display:none and $.remove(). After hiding, maybe the browser doesn't create the visual data form scratch but it makes all the rest. For example:
<iframe src="https://www.youtube.com/embed/X18mUlDddCc?autoplay=1" style="display: none;"></iframe>
Music plays on the page using Firefox v53. It does load all the HTML/JS/CSS files. So the perfomance gain of the display:none is really questionable in this case. I also need to remove the element.
Although it's slow to remove elements from DOM, it's still the best option for me. Maybe not for the static data but for elements like iframe, .ads (they usually contain iframes) it's a must. Still, I can try to use pure JS instead of jQuery for a little more.

A way to make JavaScript style changes happen before css is loaded

So on my websites I need to make sure that everything still works even when JavaScript is being blocked, which means that things that I want to hide until someone clicks on something have to be shown with CSS and then hidden with JS, which makes it look glitchy when the page is loading because the JS files are always loaded after the CSS stylesheets.
Is there a way for JS style changes to happen before CSS is loaded? Like, stop the CSS from loading with JS, make the necessary changes, and then continue loading the other files, maybe?
If you really want to load your css-file after some code of your javascript:
1. Don't specify a href attribute of you css:
<link rel="stylesheet" href="" type="text/css" media="screen" id="my-style">
Add this in your code (may be the last line of your javascript):
$('#my-style').attr('href','style.css');
And your css-file will be loaded only after that line of javascript
Try adding a .js-enabled class to HTML the tag with an inline script at the top of the head tag. You can then have CSS hide the scripted stuff for you while the rest of the scripts load.
Updated answer (see comment below):
If JS is blocked, you need to either choose to detect this and serve content based on that, meaning backend code, or make use of another strategy such as <noscript>.
Original answer:
which means that things that I want to hide until someone clicks on something have to be shown with CSS and then hidden with JS,
I would always start with display:none or visibility:hidden (see elsewhere for difference between the two) in the css, and use the JS to reveal the element.
There are several ways to solve your problem. What you need to know is the difference between blocking and non-blocking content. Every script and css (media=screen) is immediately invoked. So if you put some css in there in your head, and append something with JavaScript later on, you indeed might seen it shortly in a 'non javascript' way.
To combat this you could have the objects initial state represent the html/css as if the JavaScript has been loaded. (Most ideally you would have serverside rendering, but for simpler sites thing isn't always needed). The downside of this method is that if you have an JavaScript error which prevents further execution, you have a broken state. And if you also neglect the few people that have JS disabled, you're save and rendering looks fine again. Furthermore! You can improve on your sites performance by loading the scripts asynchronously.
If you want a different approach, you can add a className to your html eg <html class="noscript">. Then when all your JavaScript has been loaded, you remove the className. This way you only have one redraw, and it looks progressive. There is a downside to this approach though, since bad performance becomes increasingly visible (since the first time your browser rendered and the time the JavaScript is done could take a while). So ussually this method is not preferred (though looks better than the first for non-js/js disabled browsers).

Blanket stop CSS from cascading to a certain element not using iframe

I have an entire page that will be PHP included onto an already established website. The website will include my site after the <body> tag on their own site. I do not have access to the <head> section of the page. I am including my <link> and <script> tags in my page (so after the <body> of the parent page). I can change the title dynamically with javascript after the fact.
However, the CSS from the parent page is causing some interference with some of my elements that aren't explicitly styled. I would like a blanket way to stop CSS from cascading to my own elements without using an iframe. Is there a CSS reset that will work? How about a javascript solution? Would HTML5 scoped styles fix this issue eventually?
I can't give you a good answer. The closest I can think of is to take one of the CSS Reset scripts and apply them to your root <div>.
It's still a long list of things you're cancelling but at least it's maintained by someone else...
You can try by wrapping content and appending CSS rules only to wrapped content, for example.
CSS
#wrapper1 .className{/* RULES */}
#wrapper1 div{/* RULES */}
#wrapper2 .className{/* OTHER RULES */}
#wrapper2 div{/* OTHER RULES */}
HTML
<div id="wrapper1">content 1</div>
<div id="wrapper2">content 2</div><!-- CONTENT YOU APPEND LATER -->
Another solution, not the best1 is maybe to use jQuery and replace all class-es or ID-s in body when content is changed, here again you should define CSS before.
There is one thing I must note, in my experience appending HTML as pure text (like innerHtml='html') get right CSS rules in Google Chrome and Mozilla, but on IE you need to use proper JS and append content differently to get those CSS rules used. By different I mean like creating element should really be creating new element with JS function.. that was before I am not sure anymore if this thing is changed.

Show incorrect html on page that doesn't influence the rest of the page

I have got some detail content pages on my site where I don't have the complete control over the html content that is displayed in a certain div. Now when the content of the external resource contains invalid html, like having no ending my navigation in the right-bar is also italic. I don't want to use iframes, like ebay, and there is probably other ways to fix this. Hope on an answer.
<html>
<body>
<div id="page">
<div id="content">[content of external resource]</div>
<div id="right-bar">[My navigation]</div>
</div>
</body>
</html>
A simplified structure of my page is above.
I hate to tell people to use Tables when they aren't necessary, but in this case, I feel that it could solve your problem.
The issue that you are facing is one of the browsers well-formed html check, so, you could have some browsers that work as you hope, and others that work the way that bothers you, as each rendering engine is going to perform it's own well-formed html check flavor.
If you wrap it inside a td, then I don't think that it will be able to bleed styling the way that you are seeing. Just a thought. The reason that a td container is going to help more than the div container that you are currently using is the following: Since you are wrapping their stuff in a div, and they are most likely wrapping their own stuff in divs, the browser doesn't know where the mistake is at. It doesn't know where the missing div tag should be inserted. So essentially, div in div in div creates problems for the well-formed html check, as it is not sure which of the tag you forgot. However, div in div in td, that is more distinct. If the td open and closes, then it knows that the missing tags belong to a smaller group of possible elements. In other words, you are making it easier on the well-formed check to do it's job by wrapping it inside different tag types.
This makes sense to me. I hope that I have explained it ok.
I think that there is no other way than using iframes. If you don't use an iframe to host the external content means that the external content will be included in the DOM structure of your page, so unless you parse all the external content code to check all the possible things that should affect your page (and this could be a madness), you will never be sure that your page will be safe from collateral effects coming from the external code.
And even using iframes, you should parse anyway the external content to look for script tags, to prevent any undesired javascript code been executing inside your page.

JavaScript and CSS order

I have an HTML file which is linked to CSS file and also to JavaScript file.
Is JavaScript executed first and then the CSS is applied, or vice versa ?
Is there any way to change the order ?
Thanks !
It's generally considered a good idea to import your scripts as late as possible, and your stylesheets as early as possible. If possible, in fact, you should stick all your script imports at the very end of the <body>. I find that problematic when there are components pulled into the page that want to be able to drop little script blocks that reference jQuery (for example).
If your stylesheets are first, that helps make sure the browser applies styles before showing anything to the user. Conversely, by including scripts last, you defer that potentially slow script processing until after the point where the user gets to see something on the screen.
The JavaScript gets executed when the <script> element is parsed. Some of the JS might set up event handlers to run some JS when events happen.
CSS is applied to the live DOM. Changes to the DOM get CSS applied automatically. Changes to CSS apply to the whole DOM automatically.
Yahoo's research into speeding-up page loading times should be very helpful, and they explain things much clearer than I can.
http://developer.yahoo.com/performance/rules.html

Categories

Resources