I am building a one page webapp and it's starting to get pretty big. There are several components to the app, each one meticulously styled. On average the app has a DOM element count of 1200+. I have been warned by my YSlow scan that this is too many, and that I should have no more than 700 DOM elements.
I am usually quite strict and efficient with my markup and I doubt I would be able to trim much off. I tend to use a lot of DOM elements to get the styling exactly right and working cross browser.
How can I dramatically cut the number of DOM elements?
Will I have to load more of the content on demand (ajax) instead on all on page load?
Does a large amount of DOM elements have a big impact on performance?
I would love to hear people's experience with this and any solutions you may have...
The number of dom elements would only enter into the picture if you're doing a lot of DOM and/or CSS manipulation on the page via Javascript. Scanning for an ID in a page with 50,000 elements is always going to be slower than a page with only 500. Changing a CSS style which is inherited by most of the page will most likely lead to more redrawing/reflowing than it would on a simpler page, etc...
The only way to cut element count is to simplify the page.
We've built a single page web app. Initially Yslow worried me as we had 2,000+ DOM objects in the page.
After some work we got all the other Yslow items to green. And we ended up living with it(around 1,800 right now) as the app is very fast in various browsers.
But we don't support IE6 and IE7, and it could be different for these browsers.
How can I dramatically cut the number of DOM elements?
By using only those elements that are necessary. If you want an more elaborate advice, post your code.
Will I have to load more of the content on demand (ajax) instead on all on page load?
If you want your page to perform better on start-up, you can do that.
Does a large amount of DOM elements have a big impact on performance?
Not necessarily.
You can render elements on demand when user click a button or can use lazy loading like Twitter.
Related
I am building a mobile web app and thinking of the best approach to manage the app pages (say 'full screen views').
When using jQuery Mobile, the heavily used pages are all kept in the DOM. Some other framework (Backbone/Marionette) users suggest having only one page that is split into regions which update on navigation. Since my pages don't have much to share between themselves (even the header/footer changes) this means that the whole page should be rerendered on navigation if removed before.
By quickly playing around with both approaches, I have noticed that the already cached page from the DOM much quicker than rendering it all again and I didn't feel the performance issues while keeping the pages for longer time.
My question is, what is the best approach from your experiences? If the page content doesn't change much or at all, then maybe I should not remove the views. (I am talking of max 10 mid-weight pages). Cheers
I believe the conventional thing to do (and usually the most performant) is to only render enough content to fill the page. If the content cannot be seen, there is little use having it in the DOM.
However, just because that might be the conventional thing to do doesn't mean that it is the best thing for your app. If you are able to achieve noticeably better performance keeping all your content in the DOM then I do not see that as a bad approach.
You may be experiencing performance issues with the conventional approach because you do not have the experience or know-how to improve that approach yet, but you will learn those tricks eventually and that may be the best time to switch to the conventional approach over your more performant approach.
I am developing a large scale HTML5 app, and I really wonder about this issue. I will have a lot of dialog boxes and tabs that will open by user interaction.
I wonder what is the best practice - writing all the dialog boxes and tabs in the HTML document with display:none to all of them, or create these HTML sections on the fly with JS or jQuery every time the user making the relevant interaction.
What is better in terms of performance, ease of development, readability, etc?
Any help will be appreciated.
I'll try to address this question as good as I can.
1 - As I said in the comments, Avoid inline styling.
First and foremost this is because inline styling voilates DRY.
Having to repeat the same thing over and over again for this is very bad for maintenance and for developing since instead of changing code once you have to change it at ~100 places.
2 - Avoiding inline styling is also good for accessibility, some screen readers and search engine crawlers do indexing work and reading work based on css selectors and thusly using inline styling will force them to either ignore or misintrepret things.
3 - When working as developers it's easy to do inline styling "just for the fun" but what you're actually doing is mixing concerns. HTML is the content and CSS is the design.
Mixing these two usually leads to headaches and making my job as a developer that comes after you a pain in the effin ass since I have no idea what's styled and how.
Now, onto performance.
When you use inline styles, what you're telling the browser is basically "hey, for every page page view apply these styles to all of these elements." Now, this just became really apparent why this is bad.
You have no ability to cache and store your css and basically forces the browser to rerender your styles every time. Using an external CSS file will actually help you speed up your site since the browser caches it.
That was that for the css part.
The javascript you had asked about.
As I said, hide things with css and show with javascript. Now why do you want to do this instead of pulling everything in?
Well, you can do both. If you're only a webbrowser experience then you can do either, it doesn't matter. I myself prefer to have stuff in the DOM because it relates to content and if you're a large app having dozens of dozens of ajax calls will only make it harder for maintenance. I believe if you have to ajax stuff in make sure it counts and is logical and not just for the kicks (I think this applies if only you have jQuery and plain javascript at your disposal).
If you're working with backbone.js, for example, it's based on views and introduces some form of "MVC" into your frontend enabling you to have views with subviews that can pull content in from the server.
Hope that helps a bit with making a decision! :)
I would say it depends on how many tabs your application has and how big these are.
Big content inside the tabs mean that the application will take long to load when started and consume much ram. If this is the case, I suppose to load them as needed.
Small content inside the tabs will load fast, so load everything at once to increase performance when the tabs are clicked.
Don't forget to run some tests on older computers with a slow internet connection to see how your application behaves. Not everyone has the newest and fastest hardware.
One of the pages served by my application is very long (about 8Mb of source HTML, mostly tables). I know this itself is a sign of wrong architecture but there are circumstances that don't allow to change that quickly :(
In almost every browser apart from IE the page is still fine - of course it's slower than an average one but it looks like the time it takes to display is mostly defined by code download speed, and I have no problems with that.
It is very different in IE (7, 8 and 9) though - the page is extremely slow for about 10-15 seconds after downloading with frozen screen effect, then experiences noticeable scrolling lags and "script is running slowly" messages while there is no javascript running on the page. IE9 takes about 800Mb of RAM as well when displaying that page.
When I serve plain text content of that size it is much better, but formatted HTML tables seem to be causing problems. It looks like long DOM is a blocker for IE of any version.
I don't know what answer am I hoping for - obviously a proper solution would be to change the page architecture by breaking it down on server side and serving piece by piece via ajax, but still - is there any kind of say magic pragma or js for IE to stop doing what it does with DOM tree speeding it up?
It would be the best solution to chuck page downloading by client. But you have to be advised that the "table" tag is the most slowest rendering tag in IE (as my experience says). So in the first step I think you should do some modifications on the HTML document. Here are some suggestions:
Clear inline style sheets and use css classes as far as you can. It will help your HTML document to be smaller in size.
use some other expressions instead of using TABLE. using DIV s would be my first recommendation. Simplify your document and the parser can read the codes as easy as you can. So make them easy to read. It causes to write less and again, it helps the document to be much smaller.
remove all the spaces, tabs, new line characters and many other extra contents from the HTML document.
Qualify the content you are presenting to be more useful for the client. As we all now, we can see two lines at most. So all the data on one page is not a good idea, actually useless. Because while user is downloading the document, some data might be updated on the server and the data your user has is not valid anymore.
After all, always remember that every character stores 8 bytes in the memory (no matter it's virtual or not) including all the parsing variables and memory uses by xml parsers and some how hard codes to load the HTML string and make a DOM out of it. The speed to read the document and parsing it is so important as much as the size would be.
Hope it helps you..
Cheers
I have a large amount of XHTML content, that I would like to display in WebKit. Unfortunately, Webkit is running on a mobile platform with fairly slow hardware, so loading a large HTML file all at once is REALLY slow. Therefore I would like to gradually load HTML content. I have split my data in small chunks and am looking for the proper way to feed it into WebKit.
Presumably I would use javascript? What's the right way of doing it through javascript? I'm trying document.body.innerHTML += 'some data'. Which doesn't seem to do very much - possibly because my chunks may not be valid standalone html. I've also tried document.body.innerText += 'some data'. Which doesn't seem to work.
Any suggestions?
This sounds like a perfect candidate for Ajax based "lazy" content loading that starts loading content while the user scrolls down the page. There are several jQuery plugins for this. This is one of them.
You will have to have valid chunks for this in any case, though. Also, I'm not sure how your hardware is going to react to this. If the problem is RAM or hard disk memory, you may encounter the same problems no matter how you load the data. Only if it's the actual connection or the speed at which the page is loaded, will lazy loading make sense.
Load it as needed via ajax. I have a similar circumstance, and as the user scrolls near the end of the page, it loads another 50 entries. Because each entry contains many js events, too many entries degrades performance; so after 200 records, I remove 50 from the other end of the list as the user scrolls.
No need to reinvent the wheel. Use jQuery's ajax method (and the many shorthand variantes out there): http://api.jquery.com/category/ajax/
I'm building a site that makes extensive use of FLIR to allow the use of non-websafe fonts. However, pageloads are an ugly process, as first the HTML text version of each field loads and then (a few hundred milliseconds later) it's replaced by its FLIR image counterpart.
Is there any way to avoid this sort of thing? I've got a client presentation in a few hours and I know it'll raise eyebrows. My situation is sort of related to this question which is in regards to sIFR, not FLIR. Any ideas?
Thanks,
Justin
Try putting the following rules into your stylesheet:
.flir-replaced{text-indent:-5000px;}
.flir-image{display:block;}
You may have to modify your other FLIR-related CSS rules to account for the fact that the generated images are now vertically aligned to the top of their respective parents.
It's been a while since I used FLIR, but I recall there was an internal caching method that would pull from cache on load instead of generate it each time.
http://docs.facelift.mawhorter.net/configuration:settings
Also, you can't have too many on the page at once. I found that between 6-10 were optimal for performance.
Are you on shared hosting? Is your css/js compressed? I found that the initial load was a little slow, but fairly quick after the images had been generated.