Javascript Optimization for IE 11 - javascript

I have a Website which only needs to support IE11
It is a single page application, which has about 200 table rows and each table row has 5 child rows
There is a pulsing function that updates the table as records come in. Table rows are skipped over if no update comes in.
However, when receiving large updates (which should only occasionally happening), the application will hang as it slowly processes the javascript. I've tried to limit the javascript as much as possible, but still have a long running function.
I am a back end developer by nature, and was wondering if anyone had any tips to help support large table ajax updates for IE since IE so poorly handles JS.
Here is the function
function writeTableLines(tempRows){
/* This Function takes care of updating the text and coloring of
required dynamic fields.
All other values are not dynamically written.
*/
for( i in tempRows){
//i is the computer name
tempValues = tempRows[i];
// For Row
selector = "[id='"+i+"']";
// Network Name
network_selector = "[id='"+i+"_network']";
$(network_selector).text(tempValues['network']);
if (tempValues['network_color']){
$(network_selector).addClass(tempValues['network_color']);
$(selector).find('.name').addClass(tempValues['network_color']);
}else{
$(network_selector).removeClass('warning');
$(selector).find('.name').removeClass('warning');
}
// Boot Time
boot_selector = "[id='"+i+"_boot']";
$(boot_selector).text(tempValues['boot']);
if (tempValues['boot_color']){
$(boot_selector).addClass(tempValues['boot_color']);
$(selector).find('.name').addClass(tempValues['boot_color'])
}else{
$(boot_selector).removeClass('issue');
$(selector).find('.name').removeClass('issue');
}
// Last Checked In Timestamp
check_in_selector = "[id='"+i+"_checked_in']";
$(check_in_selector).text(tempValues['checked_in']);
if (tempValues['service_unresponsive']){
$(check_in_selector).addClass('redline');
$(selector).find('.name').addClass('redline');
}else{
$(check_in_selector).removeClass('redline');
$(selector).find('.name').removeClass('redline');
}
util_selector = $(selector).find('td.util').find('a');
$(util_selector).text(tempValues['util'])
if (tempValues['util_class']){
$(util_selector).addClass(tempValues['util_class']);
}else{
$(util_selector).removeClass('redline warning');
}
workgroup_selector = $(selector).find('td.workgroup');
if (($.trim(tempValues['workgroup'])) != $.trim($(workgroup_selector).text())){
if ((tempValues['workgroup'] != selected) && (selected != 'All')){
$(workgroup_selector).addClass('warning');
}else{
$(workgroup_selector).removeClass('warning');
}
}
$(workgroup_selector).text(tempValues['workgroup'])
toggle_links(i, tempRows[i]);
$('#connectionGrid').trigger('updateAll', [false]);
}
}
this function iterates over only received data.
For each row item that was received, update the text of the cell, and add coloring as necessary.
I'm thinking I might just be screwed since its IE, but am open to all suggestions and ideas.
Thanks for reading
Image of the rows - child rows only available when expanded, but still need updates

So In case anyone was wondering.
the last line $('#connectionGrid').trigger('updateAll', [false]); was being executed inside the loop.
As opposed to just once when the loop was finished.
Woops

Related

Google App Script randomly stop executing

I have a script that basically take info from a website for multiple users, and put these info in a google spreadsheet, with one sheet per users.
I have a function that remove values of the firstline, resize every columns, and put back the setValues:
function adjustColumnsAndIgnoreFirstLine(sheet) {
Logger.log('--- Adjust columns ---')
const range = sheet.getRange("1:1")
// save the title line
const datas = range.getValues();
// clear it
range.clearContent();
// format without the title lines
var lastColumn = sheet.getLastColumn()
sheet.autoResizeColumns(1, lastColumn);
// set width to a minimum
for (var i = 1; i < 37; i++) { // fixed number of columns
if (sheet.getColumnWidth(i) < 30) {
sheet.setColumnWidth(i, 30);
}
}
// put back titles
range.setValues(datas);
}
my problem is that the script stop executing in the middle of the function. I still have the "execution please wait" popup, but in the logs, the script stopped like there was no error (execution finished) with this as the last log:
And, on the google spreadsheet:
One thing to note is that the problem doesn't comes from the script itself, as I do not encounter this problem on any of my machines, but my client does. My client ran the script on different navigator (chrome and edge), and had the same problem, but on different users (sometimes it blocks at the before-last user, sometimes at the before-before-last user...)
So I'm kinda lost on this problem...
The problem is actually a timeout. Google app script limit the execution time of a script at ~6 minutes.
There is existing issues for this

Why is this jQuery load()-command repeated?

I have gone through many stackoverflow posts and other websites to find a solution to this problem, but none of the solutions i could find either fit my problem or just straight up didn't work.
Im using javascript and jQuery (and some Java for background work) to build a page on a website. The page contains a table with data (the data is handled by Java) and i want to have that table refresh every 10 seconds. That works.
But now i also want to highlight all the cells that have changed values in them. For that, as you see in my code snippet, i just simply turn the background of those cells black. That works too.
My problem is that the color only changes for a split second before changing back to standard white. Using the console and playing around a bit i was able to find out that the table is actually reloaded twice, which to me must mean the load-command is executed twice.
window.setInterval(function () {
if (frozen == false) {
$('table').load(document.URL + ' table');
var elem = document.getElementById("freezebtn"); //This is a button generated by Java Code
elem.style.background = getRandomColor();
var tab = document.getElementsByTagName('table').item(1);
var l = tab.rows.length;
for (var i = 0; i<l; i++) {
var tr = tab.rows[i];
var cll = tr.cells[1];
var check = tr.cells[0];
if(check.innerText === "getAsk") {
var valAsk = cll.innerText;
var ask = Number(valAsk);
if (ask != loadPreviousAsk()) {
console.log("TELEFONMAST!");
cll.style.backgroundColor = "#000000";
}
}
//Do this for every other Updateable Cell
...
}
cachePreviousValues(someValues,thatINeed,To,BeCached);
}
My Question is, what is/could be causing the repeat of the load command (or why won't the cells stay black at all)?
Is there a better way of achieving what im trying to do?
Could my code sample be optimized in any other way?
$.fn.load() is async (by default). To handle any logic regarding loaded data, you can use the complete callback:
$('table').load(document.URL + ' table', function(){/* your logic regarding loaded data here*/);

Javascript -- any way to force a draw of new elements before processing?

I have a javascript function or two that takes a few seconds to process. I want to show an activity indicator so users don't think it's hung. I tried bootstrap animated progress bars and spin.js -- the problem is, I put the code for them before the processing, but the browser doesn't seem to update to show the new elements until after the function has finished. Obviously, an activity indicator that shows up after processing isn't incredibly useful. Is there a way to force the redraw before the processing occurs?
EDIT: here's an example code. This is from an HTA application, hence the pulling of files and such. I know the forced "wait" portion is a bad idea, usually, but in this program, files are opened and closed immediately, this is to prevent a race conflict and I just want to give it a quick 10 retry timeout before it tells them something is wrong. So, the problem is that this.spin() doesn't display its good until after the alert pops up.
Database.prototype.tryDatabase = function(fileName, toEdit, table, keepAlive) {
if (typeof keepAlive === 'undefined') keepAlive = false;
for (timeInd=0; timeInd < 5; timeInd++) {
var complete = this._addToFile(fileName, toEdit, table, keepAlive);
if (complete === false) {
var until = moment().valueOf() + 2000;
this.spin();
while (moment().valueOf() <= until) {;}
}
else break;
}
if (complete === false) window.alert("Database was locked for an extended period, please try again");
else if (!keepAlive) $('#added_to_db_modal').modal('show');
return complete;
}

multiple Javascript run in parallel

I have a quite complex .Net page with an intensive usage of a third party libraries (DevExpress).
My page is composed of several parts:
A "Result Browser" to let user select the content of two widgets:
A Table widget
A Graphic widget
A timer (AspxTimer) to refresh the "Result browser" contents
A time widget which gives time every second
I make an intensive use of CallBacks (AspxCallBack) to minimize the volume of data to transfer from/to the server for the refresh of the browser/table and graphic.
During tests, each element separately is working well but one of the feature of the table is to re-calculate sub totals of the table when user click on a specific button. I have marked the correct subTotal cells (containing the span) during table construction with appropriate properties so I can find them on client side with javascript (<span ... SubTotal='true'>0.0</span>) and have a vector of class (code, number) to store actual numbers do recalculate subTotal from.
. Here is my code:
function recalcSubTotal() {
$('span[SubTotal="true"]').each(function() {
var subSpan = $(this);
var sTrends = subSpan.attr('trendsTotal');
var Trends = sTrends.split('|');
var subTotal = 0.0;
for (var i = 0; i < Trends.length - 1; i++) {
subTotal += Decision[Trends[i]];
}
subSpan.html(subTotal.toFixed(1));
});
}
This works pretty well in an isolated page but when mixing all this stuff in a single page I randomely have NaN (Not a numer) codes returned by this func or wrong totals, click again the action button and it can work correctly. Nothing else but the relative complexity and parallel usage of javascript+callbacks can really explain this behavior. I managed to avoid any parallel Callback (chaining them) but can't do that with client side events or date/time timer. I wonder If there is a general clean way of dealing with client side parallel run (timer+callbacks+user actions).
Thanks for any clue on this topic.
Try to call your function recalcSubTotal() with the methode setTimeout(), like this :
setTimeout(function(){
recalcSubTotal();
}, 0);

Unresponsive javascript notification

I have a situation where I render items from server in GWT grid on FireFox 3.6+. I have approximately 200 items and I load them in loop:
users = myService.getUsers();
for(User user : users){
myPanel.addUser(user); // Pseudocode. Actually i add some labels and text fields...
}
It tooks a long time to change DOM in this loop, so I got "Unresponsive script" notification. But I can not refactor code or make pagination, I need all 200 items on 1 page loaded at once.
Are there any ways to suppress this notification? To notify browser that my script is not hang, but doing something useful?
UPD Ok, here is my code closer. It is a code from big project, and we have many custom components, so, I think, it has no real value.
myService.getUsersDetails(searchCriteria, new MyCallback<List<User>>)
{
#Override
protected void response(List<User> result)
{
gridExpanderPresenter.clear();
int i = 0;
for (User user: result)
{
UserDetailsView detailsView = detailsViewProvider.get();
gridExpanderPresenter.setPresenter(UsersPresenter.this);
gridExpanderPresenter.add(detailsView.asWidget()); //Here is DOM manipulation i mentioned
if (i++ % 2 == 1)
{
detailsView.setOdd(); //Setting style here
}
detailsView.setData(user);
}
}
});
And I think this can help me...
You should add Users before attaching myPanel to the DOM, or if it's already attached and needs to be updated, remove myPanel from the DOM, add all users and reattach myPanel.
What happens when you add 200 users while myPanel is attached is that your browser has to update DOM 200 times which is quite costly (recalculating and repainting the screen).
Several options:
batch your updates using Scheduler.scheduleIncremental; rendering only 10 users or so at a time (don't worry, the Scheduler will run your code as many times as possible in a row before yielding, so it might actually render 50, 100 or 150 users at a time, and then continue 10ms (yes, milliseconds) after)
switch to CellTable; this is a major refactoring, but it'll give you much better performance than anything else you could do based on widgets (Label, TextBox, etc.)

Categories

Resources