Bootstrap v4 .modal("show") slow execution - javascript

I've noticed that bootstrap's modals take time to show as the page's content becomes more significant.
It takes less than 100ms to show when the page is empty, but takes proportionally more time as the amount of content in the page becomes more significant.
I do not understand this correlation. Can anybody explain this behavior and suggest a workaround to make the modals appearance faster independently of the page's size ?
EDIT: You can reproduce the behavior by going i.e here and execute the command
console.time("modalTime"); $("#exampleModal").modal("show"); console.timeEnd("modalTime");
in console, to see how much time it takes. Then add more content to the page by manipulating the DOM and re-execute the command.
My results: modalTime : 70 ms on the original page. modalTime : 1208 ms after making the content of the page 10x larger.

Ok, I am able to reproduce a delay if I add 50.000 lines of text to the document:
https://plnkr.co/edit/hvRAn3wg91GBCPxK2gwb?p=preview
The problem with a huge DOM like this is, that any manipulation will take long.
It might be a problem of jQuery, but I doubt.
To prove that the delay has nothing to do with the Modal, I am painting the button to red when clicking it - even this simple action takes as long as opening the modal window.
jQuery(document).ready(function() {
for (var i = 0; i < 50000; i++) {
$( "#content" ).append( "This is just some test. This is just some test. This is just some test. This is just some test. This is just some test. This is just some test. This is just some test. This is just some test. This is just some test. <br/>" );
}
$("#btnToggleMoadal").click(function(e) {
$("#exampleModal").modal("show");
$(this).css({backgroundColor:"red"});
});
});
Edit: I have also tested jQuery's onClick vs onClick out of the DOM - but there is no difference. https://plnkr.co/edit/483Sk2FGXk9lT8dLZIdo?p=info
Edit: I have to correct my answer. It's definitely the Bootstrap Modal which causes the performance issue. I think the problem is somewhere around _adjustDialog() in modal.js.
I recommend to open an issue at https://github.com/twbs/bootstrap/issues and show the Plunker example.

Related

jQuery bring DIV infront without reseting iframe

Point
The code I have here is from my "operating system" I'm trying to create inside a browser by putting iframes in AppWindows with PHP code as the backend or the (main program process).
Now in every GUI system you have the ability to move windows, stack one on top of each others and such, but I'm not able to do efficiently in HTML using jQuery & jQuery-UI.
I'm using draggable() and some tricks I've found on StackOverflow to be able to bring the div AppWindow on top.
The problem
The code for bringing the **AppWindow** on top works fine but the problem is the iframe inside that window gets reset, because what this code is doing is that it stacks the current div as the first div above all the others inside the parent container.
If you notice the AppWindow 1 iframe blinks when you click on that window, I don't want that.
Code (jQuery)
$(function() {
// Don't know what I'm doing with iframe here...
$('.AppWindow iframe').click(function(){
$(this).parent().child.parent().append(this);
});
$('.AppWindow').click(function(){
$(this).parent().append($(this));
});
$('.AppWindow').draggable({handle:".DragHandle"});
});
Conclusion
If there is a way of preventing this from happening feel free to write an answer below. If you have a better way such as "JavaScript OS UI Framework" or something like that you're even more free to write below.I want something like **os.js** or **windows93.net** type of thing. All I need is a working taskbar, working window and a way to easily embed a PHP page inside that window that will mimic the work of the application.
I don't think it's possible. Take a look at here.
But
why do you reorder windows by change their positions in the dom in the first place? You could simply work with z-index. A basic example where you just set an active class of the targeted frame.
$(function() {
$('.AppWindow').draggable({
handle:".DragHandle",
drag: function(event, ui){
updateActiveWindow(event.target);
}
});
$('.AppWindow').on('click', function(){
updateActiveWindow(this);
});
function updateActiveWindow(el) {
$('.AppWindow').removeClass('active');
$(el).addClass('active');
}
});
with following css changes
.AppWindow.ui-draggable-dragging,
.AppWindow.active {
z-index: 1;
}
Edit: optimized the js a bit so that the window turns active once you start dragging.

Multiple clicks slows down the application performance

Before I explain the problem, I want to describe short what I am trying to achieve
I have made 5 diagrams and one NavigationList. The NavigationList consists of pure HTML that displays a list of table1, table2, table3, table4 and table5 (JavaScript files). The user will click on a specific row inside the list, then the table the user wants to view will be displayed, and he can only view one diagram once a time.
For instance: I the user wants too view diagram1, then he must click on diagram1. Later he wants to view diagram2, then diagram1 will be closed because he have clicked on diagram2.
The problem:
If the user clicks multiple times on the same list name (for instance diagram1), then each click will slow down the diagram, very strange. So if the user clicks 10 times, the diagram will slow down 10 times more. Why is this happening and how can I solve this problem?**
This is table2.js, I believe that $(document).ready(function() has something to do with why the diagram slows down after each click.
(function table2(){
$(document).ready(function() {
// table2 code content is taken away to save space in this file on stackoverflow...
});
}());
This is the part where I call the diagrams by using JQuery event with if statement.
$('[data-row]').on('click', function() {
var row = $(this).attr('data-row');
$('.active').removeClass('active');
$('#table' + row).addClass('active');
if(row == 1){
$.getScript("table1.js", function(){});
table1();
} else if (row == 2) {
$.getScript("table2.js", function(){});
table2();
} else if (row == 3) {
$.getScript("table3.js", function(){});
table3();
} else if (row == 4) {
$.getScript("table4.js", function(){});
table4();
}else if (row == 5) {
$.getScript("table5.js", function(){});
table5();
} else {
}
});
This is a statistic result that shows why the performance is so slow, as you can see; each table is receiving data samples. After multiple clicks the performance is high drops down from 40 fps to 6.5 fps, strange??
Click here to view the slow performance statistics
because each click you doing ajax request so if you click 10 times you making 10 requests plus calling table12(); functions which can be heavy.. you need to change your code to check if diagram is visible if yes dont do another request
You probably have a memory leak. Make sure you clean up global variables properly and DOM nodes properly. Your browser should have developer tools which should allow you to see memory usage.
I'm also a bit worried by this code:
$.getScript("SensorTables/ExhaustTemperature.js", function(){});
table1();
.getScript() is an asynchronous function, so table1() will be executed before the browser has loaded the script.
The correct code is probably:
$.getScript("table1.js", function(){});
since the function table1 is defined in such a way that it's executed right away. That means your code logs an error in the JavaScript console when you click the first time. When you click a second time, the function is called twice (once when jQuery fetches the script from the server and again from your code).
$(document).ready(); isn't necessary inside of (function table1(){}()); - when this code is executed, the DOM is ready. Maybe the code is there because other pages use the script as well. My recommendation would be to move that into the places where you need it.
Lastly, if you give the function a name, then the browser keeps it around. That may eat a lot of memory, depending on how complex the code is. If you want to keep the code around, this should be much faster:
if(table1) {
table1();
} else {
$.getScript("table1.js");
}
since it loads the script only once.
If you want to load the script again every time the user clicks and save memory:
$.getScript("table1.js");
and change the script to
(function (){
// table2 code content is taken away to save space in this file on stackoverflow...
}());
(i.e. remove the name of the function). The browser will then execute it once and forget as much as it can about it.

Javascript/jQuery Load function, text selection

I have a console on my website which shows a log file, and i've set it up so it refreshes every 500 ms.
jQuery(document).bind("ready", function() {
$("#console").animate({ scrollTop: $(document).height() }, 1000);
function doStuff() {
$( "#console" ).load("console/getlog.php");
$('#console').scrollTop($('#console')[0].scrollHeight);
}
setInterval(doStuff, 500);
});
that works fine, but the problem arrives when i try to select some text in the console. Every time it updates, my selection is cancelled
what can i do to solve this?
Instead of using $( "#console" ).load("console/getlog.php"); to update your console, consider using $( "#console" ).append();. This should prevent the whole thing from reloading and removing your selection.
You can do something like append(getLog()); where getLog() is a function that returns the content of the log. Append can be used with hard coded content (text/html) or the results from a function.
More information on .append() here
Also here - jQuery API doc
Like MelanciaUK suggested, pause the doStuff() when the console is in focus.
You may detect that focus via mouseover/mouseout (so the console stops updating when you hover it), or on mousedown/mouseup, which isn't that usable since you have hardly time to press Cmd + C to save your selection.
Some dirty example: http://jsfiddle.net/ZEW5s/ (updated with pause after mouseup: http://jsfiddle.net/ZEW5s/1/)
tymeJV suggestion to use setTimeout instead of setInterval is a good one, though.
The only way i can think of solving it is by making the delay long so you got time to select the text.
Not much of an answer, but I can't comment, so here it goes.
There are some methods for accessing and manipulating the selection, although they depend on the browser if I remember correctly. Check this out:
https://developer.mozilla.org/en-US/docs/Web/API/Selection
I'd recommend changing the doStuff() to save the current selection, and try to apply it after the loading.

Page reload doesn't reset jQuery / CSS styles

I'm designing an HTML page which has one button. The user clicks the button and a simple jQuery script animates that div away, revealing lower page content. You can see it here.
I've noticed that it looks/works fine the first time, but if I refresh the page with the browser button, it doesn't fully reset. The initial container is only half on the page. If I enter the URL again and load the page, it resets as expected.
NOTE: This only happens if you scroll down a bit after clicking the initial button... which seems weird.
I had no idea that there was any difference between these two operations, but there clearly is. What is the difference and how can I fix this problem from happening?
Here's my jQuery code, in case it's relevant:
$(document).ready(function(){
var faqs = $("#FAQ");
$("#learnmore").click(
function(){
$("#home").animate({top:'-=1066px'},600);
$("#more").animate({top:'-=1066px'}, 600, function() {$("#background").hide();} );
$("body").css('overflow-y', 'scroll');
//$("#home").slideUp();
console.log("jquery loaded");
}
);
});
It happens because it is cached by the browser.
If you styles are regularly modiefied, then as easy fix is to attach a unique id on the end of the reference, like
<link href="style.css?time=168768234928" ..../>
What it does, it makes the browser think it is a new request everytime it loads.
It happens because browser trying to scroll to the same position, what was before page reload. To check it, try press button and don't scroll to bottom of page and then reload page.
Okey, the reason is clear.
Now we need solution. Try this:
#more {display:none}
in your css. And then use
$("#more").show().animate(...
in your $("#learnmore").click() function. I hope this will solve the problem.

rules for "prevent this page from creating additional dialogs"

I try to understand Firefox's behavior regarding the added "prevent this page from creating additional dialogs" on dialog boxes.
Using jquery, if I add the following listeners :
//html
<input class="testInput" />
//javascript
$('.testInput')
.click(function(){ alert('clicked') })
.keyup(function(){ alert('keyup') })
When clicking on the input, the alert box appears normally, until the
~13th time.
When hitting a key, on the other hand, the second message box already
appears with the message "prevent this page from creating additional
dialogs". Actually, there seems to be some tiemout, and if I wait
like 2 seconds between two keystrokes, the message disappears.
From my informal tests, 2. actually applies whenever the alert box is not called from within a onclick callback (e.g : keyup callback, displaying an alert box in answer to an ajax action...)
I am using Firefox 9.0.1 under Ubuntu, as far as I know I haven't tweaked firefox's settings regarding these thresholds.
I imagine it happens with any recent version of any browser.
I am using the jQuery library, but I don't think it is relevant here.
My question is :
What are the exact rules which make this warning appear in a dialog box ?
[Edit]
Using Chromium/Ubuntu (version 17.0.963.26), the threshold seems to be only the delay between two dialog boxes.
You can test this from jsfiddle here (thx Rory McCrossan)
The exact rule(s): A timed interval between the dialog boxes popping up.
The value used to determine this is set in SUCCESSIVE_DIALOG_TIME_LIMIT
Check out line 2614 in the link below the snippet:
nsGlobalWindow::DialogOpenAttempted()
TimeDuration dialogDuration(TimeStamp::Now() - topWindow->mLastDialogQuitTime);
if (dialogDuration.ToSeconds() < Preferences::GetInt("dom.successive_dialog_time_limit",SUCCESSIVE_DIALOG_TIME_LIMIT)){topWindow->mDialogAbuseCount++;return (topWindow->GetPopupControlState() > openAllowed || topWindow->mDialogAbuseCount > MAX_DIALOG_COUNT);}topWindow->mDialogAbuseCount = 0; return false;}
Link to source
You can kick around the Firefox source if you like. Note that different browsers will have different rules.
The relevant code for Firefox is in nsGlobalWindow.cpp and nsGlobalWindow.h (the links below are to line numbers, and so will slowly rot as the source changes). It appears to be controlled by the constants MAX_DIALOG_COUNT (10) in nsGlobalWindow.h and SUCCESSIVE_DIALOG_TIME_LIMIT (3, units are seconds). nsGlobalWindow.cpp keeps a count (mDialogAbuseCount). Apparently, the dialogDuration function either increments or clears mDialogAbuseCount depending on whether the dialog has been open longer than the SUCCESSIVE_DIALOG_TIME_LIMIT. The AreDialogsBlocked function uses the mDialogAbuseCount (in part) to decide whether they're blocked.
So in short: If you're repeatedly opening pop-ups and then closing them within three seconds, after 10 or so you'll trigger something.

Categories

Resources