I have a webpage with a lot of checkboxes that I turn into pushbuttons with jQueryUI button() call. This slows the rendering of the page down to a crawl. Is it possible to speed this up?
I do the call in document.ready with selector
$("#containingdiv input[type='checkbox']).button()
I am building a control for a bracket cup. And i am showing the brackts for all agegroups, that is the reason for so many checkboxes. The ones marked in red boxes ar checkboxes and the other ones is normal buttons. There are up to 30 agegroups so i need to show alot of them.
Looks like i should build the ui myself instead of using the pushbuttons from jqueryui. When i profile i chrome it looks like it is building all the nodes that uses all the time.
Try the following trick. Instead of converting them all at once, convert first hundred (or how many user immidiately sees on the screen), and delay the rest with setTimeout(). This releases the UI thread almost immidiately, therefore browser can do other things like rendering and processing events. Initialization actually becomes longer, but the page is never frozen.
Something like:
var checkboxes_left = $("#containingdiv input[type='checkbox']");
convertRest();
// Convert the first 100 checkboxes, then schedule converting the rest
function convertRest() {
checkboxes_left.slice(0, 100).button();
checkboxes_left = checkboxes_left.slice(100);
if (checkboxes_left.length > 0) {
window.setTimeout(convertRest, 50);
}
}
Related
I'm using ui-grid 3.2.1.
Trying for a long time now to find an event that notifies me when rows are rendered in the DOM.
I looked a lot in SO, and in their issues in Github.
My test to see if rows are rendered is basically $('.ui-grid-row').length > 0.
I tried rowsRendered event, modifyRows(data), all sorts of $timeout(0) in almost every spot I could, nothing worked, all callbacks are called when the above jQuery still doesn't have results.
As a last resort I found a very inefficient solution - I $watch the .html() changes of .ui-grid-contents-wrapper, which contains the .ui-grid-row elements, and when I find one, I turn off the watcher and call the callback. It's bad but it works.
Note - The rows/columns somtimes contain inner directives which may take some time to render. I don't think it should influence rowsRendered() event.
Please, can anybody help with this?
No support from ui-grid team sadly.
EDIT:
plunkr that show there are no .ui-grid-row in DOM when rowsRendered() is called:
https://plnkr.co/edit/8clwC5hkwhAEjvoLZ6vO?p=preview
Try
var rows= gridApi.core.getAllVisibleRows(gridApi.grid);
inside rowsRendered function.
I need help in hiding/unhiding neighboring spans. I'm building a series of FAQs using an accordion structure. I need to have each question truncated by default, but when clicked, the question must then appear in full. Finally, when the open FAQ (or another one) is clicked, the question should return to its truncated form.
My markup is of this form - where I have placed a truncated version of the question in one span and the untruncated version in a neighboring span:
> <div class="accord"><h4><span class="shortver">What steps do I need to
> take to ...</span><span class="longver hide">What steps do I need to
> take to install a constructed wetland?</span></h4><div
> class="faqcontent">Answer goes here</div>...</div>
The following function controls the FAQ:
function fnSetUpPageFAQAccordion(){
$(".accord > div").hide();
$(".accord > h4").click(function(){
$(this).find('span.shortver').addClass("hide").next('span.longver').removeClass('hide');
$(this).toggleClass("close").siblings("h4.close").removeClass("close");
$(this).next("div").slideToggle("1500").siblings("div:visible").slideUp("1000");return;
}); };
This code closes the truncated version of the question and opens the full version when the FAQ is clicked. What I can't figure out is how to reverse that sequence when the FAQ is clicked again (or another FAQ on the page is clicked).
Any suggestions - perhaps there is a better approach altogether?
Thanks/Bruce
Here's a slightly different approach, and a solution.
I think you could simplify this. Instead of having 1 span with the short version and 1 with the long version, put the beginning of the explanation in the first (let's call it class="questionStart")and the rest of it in the second (class="questionEnd"). That way you can leave the beginning always visible and only worry about toggling the class on the second. This is simpler but you'd need to remove the '...' which may not be worth it for the readability loss.
To address your issue of hiding the element when clicking something else, try adding an onClick event that first adds the hide class to all of the "questionEnd" spans, then toggles it on for just the one you've clicked on. I haven't tried it but I think you could make that work pretty easily either with your original approach or with mine.
I have a large XPage with about 170 fields on it. I have tooltips for a fair number of the fields. The tooltip does a lookup into a help DB and returns the related text. They work fine but they significantly slow down the load process because of the number of times the lookup is performed. I put a dBar.info statement in the JS that loads the text and in one load the document and put it into edit mode it would appear to have fired that one tooltip lookup 6 times. If it does that for every one of the tooltips then clearly that is the reason for the slow performance of the XPage. I did it both with the DynamicContent set to both true and false with similar results. I'm tempted to just remove the tool tips but that kind of defeats the purpose.
Is there a way to limit the tooltip to only fire the lookup when called? Like something linked to the MouseOver event. It seems to me the tooltip in the extension Library works OK if there are only a few fields requiring inline help but does not scale well.
Just as a test I removed all the tooltips from the XPage and while the loading is slow it is probably acceptable, but the tooltips slow it to the point of unacceptability.
Bill,
This is an excellent use case for an ApplicationScope bean. Create a bean that implements Map and uses an internal HashMap as cache. Let's call it tooltip. In your tooltip you define the label as EL e.g. tooltip['Manager']. XPages will call the get function. In it you check the internal HashMap if you have the value, otherwise you look it up. So lookup happens once only.
You could instead of looking up on demand opt for loading when initialized. Using a view navigator that should be very fast. Since it would be an Application scope only loaded once.
Makes sense?
You can use view.isRenderingPhase() to minimise the lookups during a partial refresh. With the tooltip you can also change the showDelay property so the tooltip has a delay before showing. This is a good thing to do for a view, so it doesn't try to load each tooltip as the mouse moves down the page. dynamicContent="true" may also mean it's not loaded with the page, but only when called - I haven't checked this so I'm not certain.
Im using the jQuery Mobile Filtered List:
http://jquerymobile.com/demos/1.0.1/docs/lists/lists-search.html
On my PC it works fine but on my iPhone 3GS its quite slow. There is about a half second delay between entering a letter and the list being filtered. I have 150 items to filter, from some googeling it seems this should be handled fine. So am I just being unrealistic with the speed of response id like or is something likely wrong?
The filter will find the characters even if the word doesn't start with them. So entering 'ar' would find 'Paris'. This isn't necessary for my application, im happy for items to only be returned if they start with the letter that the filter starts with. Can this feature be turned off and would I likely see a noticeable performance benefit if I did so?
I haven't yet found a workaround to the filter search bar being slow, however, if you remove all anchor tags and roles from your UL LI list, this will remove hundreds of bindings that slow down the page load and transitions. You then have to add a function:
// should be defined in your body onload method, or pageinit
$("li").on("click", function(event) {
// determine your URI here you want to load
// ...
$.mobile.changePage(uri);
}; // if list dividers exist, add code to ignore them, or get page load error.
Update: As per the docs, if you add the following to mobileinit, the search substring applies to the beginning of the words being searched:
$.mobile.listview.prototype.options.filterCallback = function( text, searchValue ) {
return text.toLowerCase().substring( 0, searchValue.length ) !== searchValue;
};
Note: This still doesn't speed up the search bar entirely. Hitting backspace is especially slow because of the instant search and DOM update. I don't see an API hook to fix this (yet?)...it may require library modification.
Aside: stackoverflow's code validator is overly picky, so I left out details, like the explicit mobileinit code...
Update: If you get to using CSS3 transitions and have problems, consider the following...
If you encounter rendering artifacts on iOS due to the tiled rendering engine of the GPU not vsync-ing after the transition, the following may help:
<style type="text/css">
html, body { -webkit-transform: translateZ(0); }
</style>
My conclusion is that jQuery Mobile is just plain slow. Ive rebuilt an exact copy of my site with just jQuery and the performance is much better. Maybe its because its a young framework but my very subjective experience is that its not production ready if you need optimal performance.
I have a page that has to render a huge set of query results - most of them with very, very small images. It is already paginated, so that won't solve my problem.
The query executes fine - it's very zippy, returns in about .0004 seconds, paginates itself out to the View - all is well in the land of Oz.
However there is some big trouble in that ASP.NET MVC dumps the page when it is ready, not as it is loaded. Is there any way around this?
I tried using jQuery to lace through div layers and draw partial views - this alleviated some of the problem, but it still just 'hangs' on the page until the whole thing is ready to be drawn.
I was looking around and found a few suggestions about using Response.Write - but I couldn't uncover anything relevant to my case. Any ideas? The structure is as follows...
PartialView
- Category
- IEnumerable<Models.Images> (List)
PartialView
- Page
- IEnumerable<Models.Images> (List) (Paginated View)
View
- Gallery
-- Index
--- Categories (Ajax Loaded on Demand, not on View render.)
---- ViewPage (No specific model passed)
The problem is clearly the images, I've tested it several times. If I remove the tags from the code, it renders quickly with just any data I tell it to. Each image is around 4 kb in size - so compressing them isn't likely.
Any help would be greatly appreciated.
There are a couple of things that you can do.
First, make sure the results themselves are not inside tables. IE (and perhaps other browsers) have to wait until the table has been fully loaded before rendering to the browser.
Secondly, there is a command called Response.Flush which will push the buffered output to the client. You can call this repeatedly. You may want to call it for every 10 items or so, for example. If you can incorporate this into your code it should do the trick for you.
About how many images are being loaded in a given request? As I'm sure you're aware the issue is less the size of the files and more the quantity of them- it takes longer to move a bunch of small files than an equally sized large file.
One thing to consider would be to send the page down with a specific sized set of results already populated and then use JavaScript (and perhaps scroll events) to dynamically load the rest. Ideally you should try to minimize the size of the initial request so that the page doesn't block user interaction for long; after that initial loading period you could then start pulling in the rest of the results.