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

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.

Related

Which has more specificity between hidden attribute in HTML or display property in CSS? And how?

Also what is the best way to hide the elements from the DOM so that the attacker won't be able to change the css property or html attribute in order to access the element. I know we can use React or Angular to develop website and it is easier to hide or display elements. But I want to know in pure HTML & JS what is the best way?
Anyone can just use the browser console and find all elements with for example:
document.querySelectorAll('*');
It does not matter if elements are hidden with CSS.
Even if you encrypt your HTML you will have to decrypt it to show it to the browser. Then the above code still finds all the elements.
Any code you have can be deactivated by setting a breakpoint and rewriting it in-browser using the developer tools.
Even if you replace document.querySelectorAll and all like them with an empty function, developers can still just add jQuery or any DOM querying engine and find your elements that way.
Any code you can use to hide or show elements can just be executed using the browser console if someone spends the time understanding your code.
How else would you debug or test it?
Angular, Vue etc. does remove elements from the DOM but you should never expect this to be a security feature! A hacker can easily set a breakpoint anywhere in your code, inspect API results from the Network panel, go into the components' code to find out what HTML they would be rendering and much more I haven't started to mention.
To implement security you want to only have in the browser what the user needs to see.
There is no way around it.
DOM, stylings, scripts, assets, etc. can always be accessed using developer tools.
As for the question in your question title:
style attribute styles have a higher specificity than CSS from file (or style tags)
CSS from file (or style tags) with !important has higher specificity than styles from the style attribute
style attribute styles with !important have the highest specificty
So !important just overrides specificity if you want to look at it that way. Other than that you should read about CSS Specificity.
Both are same. If you store your value from html hidden or css hide. Anyone can find out them.
So if you are using html , js & css and want to pass value as hidden than disable developer tool and shortkey to open it by this way you can protect your data or else use any encryption method for that.

Effeciency, hidden HTML or JavaScript DOM appending?

I am working on a simple Cordova app with about 4 page types and I am trying to think through which is the better way to handle the inner HTML templates.
Hidden HTML hard coded into the HTML files that is hidden and populated/revealed by my JS.
Using a JS template system and appending and removing from the DOM.
I feel that appending all that to the DOM for a page is inefficient when I could just update the sections that change. But perhaps an append is lightweight enough where I shouldn't worry about it.
There are a number of ways you can do it. In terms of load on the browser. That is hard to say. From your question it is hard to know what is in these pages, what are you displaying, is it live data, static html etc.
When you first plot out an app, if you are from the old class of building multiple page websites, it can be a little concerning as to how well your app/page will run with all those pages crammed in to one, and all that data plus code.
The answer is, amazingly well. If done properly in modern browsers, and for example Ipads the app will run to near native performance.
The options you have are
Map all the pages into one HTML document. Hide each page content using css display:none, flip them into view using css animation, fading or just display:block.
Use a javascript routing library to map urls to blocks of code that deal with each page, this makes mapping out your app much easier, and means that buttons can just link to your pages, like a real website. see http://projects.jga.me/routie/
Building all the page templates into one page can make it hard to code, as the page becomes enormous, consider breaking the inner content of each page into separate files, you can then give each page holder a url and use a small xhr request to load the page on-the fly, once loaded you can cache it into memory or even local-storage, depending on whether you remove it when it is closed or keep it hidden.
In my experience you can put an enormous number or nodes into one page and have very little speed drop, bear in mind if you use something like jquery and do a lot of $(".page > .page1 > .items li") your going to have a slow app.
Tips
Use element ID's everywhere document.getElementById(..) is 100's of times faster in a loop that $(...)
cache elements when you find them, if you need them later store them in a memory cache.
keep for loop inner code to a minimum.
use a decent click touch libary like http://hammerjs.github.io/ and delegate all the events of the body tag or at least on each page.
If you need to touch the server, load data, think dom first, device second server later. A good app is a responsive app, that responds to the user instantly.
I know this has been posted a while ago, but for the sake of the users I am going to add my answer.
I completely agree with MartinWebb but my answer will shed some light on the results of his options. I am currently working on a similar project. Please note that this answer pertains to cordova (previously called phonegap) specifically. My app has about 5 pages with +-20 different components (input's, div's, h1's, p's, etc.). This is what i tried and the result of each:
jQuery was my first option, mainly because it is easy to use and reduces the amount of code required to accomplish a said goal. Result: First time I tried this approach I though I would spice it up with animations and transformations. The result of this was a very unresponsive app. I removed the animation and transformation, however due to the nature of my application I required multiple dynamically added components and jQuery just wasn't up for the task.
Css display:none and visible:hidden was my next option. I used javascript's dom to display certain div's. Result: This works if your not planning on switching many div shortly after one another eg. a simple menu. It quickly became apparent that this wasn't going to work. Also this does not eliminate my need for the dom. Remember document.getElementById('menu').style.display = "none"; is still part of the dom. This as a solution, for me, is poor. There is a reason that var menu= document.createElement('div'); is part of the language. Which brings me to my last option.
Building a page 90% on javascript's dom was my last option. Logically I could not see how 600 lines of code cold trump one .innerHTML or .style.display = "block"; but it did. Result: It was by far the most responsive of all the solutions.
I'm not saying that all webpages should be coded with dom appending, but as I stated previously, for a cordova app of a few pages (<6), with a few components a javascript dom appending approach would be best. It takes longer to code, but you will be rewarded with control and efficiency. I would suggest coding the backbone of your app in html and populating and controlling with javascript's dom.
Best of luck.
The first option, <div>s with display:none; would be more efficient by a small margin, but you can get the best of both worlds by compiling your JavaScript and templates together into a single file using something like browserify or require.js.

How to remove jQuery Mobile styling?

I chose jQuery Mobile over other frameworks for its animation capabilities and dynamic pages support.
However, I'm running into troubles with styling. I'd like to keep the basic page style in order to perform page transitions. But I also need to fully customize the look'n feel of headers, listviews, buttons, searchboxes... Dealing with colors only is not enough. I need to handle dimensions, positions, margins, paddings, and so on.
Therefore I struggle with extra divs and classes added by jQuery Mobile in order to override them with CSS. But it is so time-consuming, and it would be way faster to rewrite css from scratch...
Is there a way to load a minimal jQuery Mobile css file ?
Or should I look towards an other mobile framework ? I need to handle page transitions, ajax calls, Cordova compatibility, and of course a fully customizable html/css...
Methods of markup enhancement prevention:
This can be done in few ways, sometimes you will need to combine them to achieve a desired result.
Method 1:
It can do it by adding this attribute:
data-enhance="false"
to the header, content, footer container.
This also needs to be turned in the app loading phase:
$(document).on("mobileinit", function () {
$.mobile.ignoreContentEnabled=true;
});
Initialize it before jquery-mobile.js is initialized (look at the example below).
More about this can be found here:
http://jquerymobile.com/test/docs/pages/page-scripting.html
Example: http://jsfiddle.net/Gajotres/UZwpj/
To recreate a page again use this:
$('#index').live('pagebeforeshow', function (event) {
$.mobile.ignoreContentEnabled = false;
$(this).attr('data-enhance','true');
$(this).trigger("pagecreate")
});
Method 2:
Second option is to do it manually with this line:
data-role="none"
Example: http://jsfiddle.net/Gajotres/LqDke/
Method 3:
Certain HTML elements can be prevented from markup enhancement:
$(document).bind('mobileinit',function(){
$.mobile.keepNative = "select,input"; /* jQuery Mobile 1.4 and higher */
//$.mobile.page.prototype.options.keepNative = "select, input"; /* jQuery Mobile 1.4 and lower */
});
Example: http://jsfiddle.net/Gajotres/gAGtS/
Again initialize it before jquery-mobile.js is initialized (look at the example below).
Read more about it in my other tutorial: jQuery Mobile: Markup Enhancement of dynamically added content
...or just use the official, theme-less version of the CSS built specifically to allow the design of a custom theme while maintaining all of jQuery Mobile functionality.
You don't have to fight with hacks and overrides all the time and you get a lighter CSS.
Win-win.
edit: Also answered here
To be honest i'm fairly disappointed that jQuery mobile didn't provide us with a relatively style-free starting kit, to work merely with what you have said: Ajax, transitions, cordova...
Overriding the generated css classes is absolute madness, but I have done some skunk work and I managed to reduce the uncompressed css file size from a whooping 233kb to merely 27kb, while keeping the important aspects of the css such as transitions, one-page viewing, etc. This way you start almost as you would start with an empty css file.
Perhaps I will upload the file on Github, if there's any demand for it. I wish to do some more testing to see that I didn't leave anything significant behind.
as of jQuery Mobile 1.4.0, the data-enhanced data attribute was added to most of components. Setting this as true attribute will cause jQuery mobile to ignore style enhancement for the component, so you'll have to style the element by your own.
additional information about this in the jQuery Mobile 1.4.0 release notes here
http://jquerymobile.com/upgrade-guide/1.4/
i m nô expert but i would love to share à weird method with you . Actually, it s very hectic task : what you need is to edit the jqm css line by line by deleting the property values just leave them blanks before ; you have just to look after the desired sections of the CSS file to adjust or delete value
Do not forget to attach your link rel of your own CSS at the head of your HTML page
I hope it will work for you

Is there a cross-browser way I can fire an event after printing using javascript?

I need to be able to print a jQuery UI dialog. My solution thus far has led me to create a "Print" button that creates a new <iframe> filled with the contents of the dialog and then prints it.
I'd like to be able to remove the <iframe> as soon as the printing has completed. Is there any way I can do this? I know there is an onAfterPrint event in IE, but I need this to work in all browsers.
Edit: I appreciate the alternative suggestions, however I ran into all kinds of problems trying to use CSS rules to print jQuery dialogs. On pages with a lot of content and multiple dialogs, the structure of the overlay and other elements would cause extra blank pages to be printed. I've tried many combinations of { visibility: hidden; } and { display: none; } but couldn't find a solution.
Have you considered making a special stylesheet with the media="print" attribute? Make this stylesheet hide everything else on the page that you don't want to print and reset any formatting as needed. (For example, reset the positioning on the box from absolute to static)

Hidden divs - reducing latency with style display none + 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.

Categories

Resources