Poor Performance in Loading content using AJAX - javascript

I need your help badly in determining the cause of this problem. This is a hotel management system that keeps track of checked in guests and monitors them if their time is up. I'm using setTimeout as suggested by Mr. A. Wolff (Slow website after some time (with ajax interval of 10 seconds)) in this discussion. It's reloading the content every 5 seconds now but as you can see, the debugger is consuming 10 seconds in getting 56KB of data.
The problem still exists. I have done my researches about modals and timeouts and I am close to giving up. I just need a clue on where to start.
The computer is where the files are located. Technically, it's a server and at the same time, being used as a client for the system.
Here's a screenshot for the debugger. Thank you.
UPDATE:
I removed the setTimeout from the function itself so basically, nothing's reloading the page. Then I opened a checkin page, things got faster, and I mean so fast now. So I think this is what I need to do, I need to stop the function from reloading the page IF I OPEN A MODAL. The reason is that, if the modal closes, it's going to reload the PAGE anyway. So it must be a good idea to stop the recurring function when a modal is opened. Any suggestions?
UPDATE 2:
Here's the link of the script being executed:
https://www.dropbox.com/s/azi51w0pzp69kgh/checkin.php
Here's the live site: http://greenenergiesllc.com/temp
Login: removed by moderator
Password : removed by moderator

i suggest you don't use settimeout,use setinterval for 5 sec instead of it.
if you pull large data from server you must use json.
and also don't create js timer in same time,the server couldn't response over ajax requests.

Related

Can website owner see what client run in console?

I have a refresh script, which clicks automatically in every 5 second on a button.
It looks something like this:
setInterval(function() {
document.getElementsByClassName("buttonclass")[0].click();
}, 5000);
If I put this script into inspect element/console and I run it can the website owner see it?
Can the owner of the site watch what kind of scripts is running in console, which was injected by user/client to the website?
If yes, how can the owner of the website see it?
I probably think the answer here is "it depends on what you do, but usually not". You can talk about these things for hours but put simply: when you "go" to a website you make a HTTP-Request to a web-server which responds with all kinds of data. Your browser uses this data to render the website. The changes you make, or running scripts, etc., happens in your browser. If you change a buttons background-color for example, this change only happens at your machine. But technically speaking, a website could be coded in a way, that every change to the DOM is going to be reported back to the backend (for example via fetch), so it is possible that, for example, a website could track how many times in a second you press a button or something like that. The things you enter in the console though, unless its not interacting with the DOM or any other script, can never be read by the owner, because it has nothing to do with the website, but with your browser (for example, if you type "1+1" in the console, the owner isn't going to see that).
Apart from the fact that it is somewhat technically possible to track some, but not all activity or changes a user makes to a website, by default, if not coded that way, the owner of the website can't see what you are doing with the version of the website that you requested.
JavaScript doesn't provide an API that allows web pages to view everything that is going on in the Console. So to answer the question in your title: no, that is not possible. At least, not directly.
Theoretically there are plenty of ways to detect if specific code is ran. For instance, you can wrap the native setInterval function and sent some AJAX request to the server when someone triggers it.
Here is a small example:
(function() {
const nativeSetInterval = window.setInterval;
window.setInterval = (...args) => {
console.log("Someone ran the setInterval function...");
nativeSetInterval(...args);
}
})();
Open the console, be sure to select the right (stacksnippets.net) frame, and execute <code>setInterval<code>.
<code>setInterval(() => console.log('I run every second.'), 1000);</code>
This is however very unlikely to be the case. What is more likely, is that clicking that button triggers some call to the server of the website, which has some logging. If the logging shows that some action is performed exactly every 5 seconds for an extended period of time, they will easily come to the conclusion that it wasn't done manually.
As far as I know you cant directly see if a user is inputting and using the developer console, that said if you click a button every 5 seconds you could detect that kind of behaviour. So directly you cant see what and if people input thigns in the dev console but indirect you can in some cases

Javascript tabs synchronization and server events

I need some help for my application and sorry for my English.
I'm working on front-end of a website. The final app should work fine with a lot of tabs (~100 in a single browser). Each tab needs to listen for a series of events sent from server and change its content dynamically.
I implemented this feature by using Websocket. Since opening a connection is very expensive. So I assigned a master tab, which will listen to events from the server and distribute them to other tabs using BroadcastChannel. And I have following questions:
How to pick a master tab from all of them and make other tabs listen
to it?
I had these ideas:
1. Using BroadcastChannel.
During initilization tab asks using BroadcastChannel: "is there a master tab?". If it receives an answer, then it will continue working. If it won't receive any response, then it makes itself a master tab.
Problem:
If master tab will freeze inside of heavy loop, then it won't be able to respond in short amount of time, resulting 2 opened connections to the server and a conflict, which needs to be resolved.
2. Using LocalStorage.
During initilization tab will request some field called "X" or smth. If field is empty, then tab will create that field and assign some value, after it will make itself a master tab. If field "X" is not empty, then tab will make itself a slave tab.
Problem:
If two tabs will initilize in the same time, there might be a conflict:
tab_Alpha -> localStorage.getItem("haveMaster") -> undefined // There is no master, so i will make myself a master tab!
tab_Beta -> localStorage.getItem("haveMaster") -> undefined // There is no master, so i will make myself a master tab!
tab_Alpha -> localStorage.setItem("haveMaster", true) // Now it's time to open connection and listen for events
tab_Beta -> localStorage.setItem("haveMaster", true) // Now it's time to open connection and listen for events
And as a result, I have a conflict and two opened connections.
Can someone point out a lightweight solution to me? I will appreciate that.
After a research.
Halcyon suggested to use code from gist.github.com/neilj/4146038. But i was not satisfied with this solution, because if Math.random() will return 2 same numbers for 2 different tabs, while they will initilize, then browser will call masterDidChange() two times. And browser will end up, with conflict and 2 connections.
Then Dimitry Boger suggested to read this: alpha.de/2012/03/javascript-concurrency-and-locking-the-html5-localstorage.
I liked this solution more, but i still have managed to find a way to break it.
If each tab will freeze in couple of places, then it will result, again, an execution of criticalSection().
Then i found a wikipedia.org/wiki/Peterson's_algorithm. I have not found a method to break this locking mechanism, but there is a problem.
For this algorithm to work browser have to know exact amount of tabs before execution. Because if it will initilize a new tab, then previous one's can just miss this event and start their criticalSection() before the new tab will finish it's own.
So, if you are not scared of 1024 tabs initilizing and freezing them selves at the same time, then you can use any of this solutions. But i need a bullet proof one, so i decided, to give a honor of finding a master tab to the backend server.
Thanks everyone for help.
After another research.
There is a bullet proof answer under the post. It can work without a backend server.
SharedWorker can be used to solve the problem.
It will use dedicated blocking thread for all of communication between itself and other browser contexts (tabs/iframes). So it can be used to sync different things.
MDN Article about SharedWorker
I ran into this exact problem a while ago. I found this windowcontroller.js from an app called Overture.
It correctly handles race conditions and timeouts.
I think it works out of the box but I modified it a bit to suit my needs.

PHP Mysql: Avoid overflow on pageviews?

So I have certain profile pages that needs to have page views. I stored the view data in mysql and php (actually laravel). Basic idea is to add view by 1 every time the profile is visited.
Basic idea is to add a php code in the profile page, like
$page->view += 1; $page->save();
But what if the user hits f5 several times? It will cause the query to run a lot and I fear it will eventually slow the app.
I was thinking of making a prompt with js when user hits f5 and an ajax call to add the view. But I was wondering if there is a better solution (like, how did youtube do their views)?
You can count the views after a certain amount of time on the page.
To achieve this, you will need a delayed javascript function like:
setTimeout(function(){countView()},3000); (3 second delay)
Where countView() should be an ajax call to a function that runs $page->view += 1; $page->save();
And since Ajax calls are asynchronous, the execution will not delay your application flow, although a simple increment on a page-view table should not do much harm in terms of performance
This will work as long as the user doesnt delete the cookies.
if ($_COOKIE['returning']!="yes")
{
// first visit!
}
setcookie("returning", "yes", time()+360000);
Another way would be to log the IP in a database and check if user already visited, but the code is more complex than i can post right now. I will edit the post later if accepted.

Triggering a DB call on browser leaving current page?

I've got an application that I intend to set a lock flag in my database that would exclude others from viewing that same page if set.
However, once set - I have no idea how to "unset" it. I could make it up to the user to unset the flag, but that seems unnecessary.
I'd want to simply look for the browser to leave the page, make a call to the database, and unlock the page.
How does one do this "type" (not looking for the exact way) of thing with JSF/Javascript/jQuery (all options)
There's really not a reliable way to do this, that I've seen anyway.
You can use the browser's onbeforeunload event to tell the server, "Hey I'm leaving the page now.". The issue is you can't actually block the page from unloading. If the user is actually closing the browser, any open sockets are going to be closed immediately. Your web server may or may not get the request in time. I've had very flaky results with this approach.
One approach that might work is to employ some sort of timeout mechanism. The page would ping the server every 30 seconds or what not, saying "I'm still here." If the server did not get this update after a few minutes, it would invalidate the session and free up that document. Perhaps this could be optimized by checking for the last ping when someone new came along. One issue with this is if someone left the page, the next user might have to wait a minute or two before they could go to the page. You'd then have to find a ping frequency that doesn't flood your server with traffic, but also doesn't make the next user have to wait too long.
It's also possible to combine these two methods. When the user leaves the page, trap the onbeforeunload event and immediately invalidate the session. However, if it didn't work, the session would time out after a minute of not being pinged.
Are there better solutions?
If you really need to lock a document in a web app so multiple users can't edit it, you might want to investigate your overall design. Are you afraid of users clobbering data? If so, maybe employ a mechanism that can resolve merge conflicts, or detect if both sets of changes can be combined.
If you wanted to go truly Web 2.0, you could design something similar to Google Docs, where changes appear live as they're made. No need for a Save button anywhere!
Sending a "keep-alive signal" might be an option. Something along these lines on the frontend side, combined with session cookies.
setInterval(function() {
var img = new Image();
var src = "http://examle.com/keepalive.gif?cachebuster=" +
Math.ceil(Math.random() * 10000 );
}, 1000);

How to detect browser closing?

In my web app, when a user logs in, I add his Id to a vector of valid Ids in the servlet, when he logs out, I remove his Id from the vector, so I can see how many current users are active, if a user forgets to log out, my servelt generated html has :
<meta http-equiv="Refresh" content="30; url=My_Servlet?User_Action=logout&User_Id=1111">
in the tag to automatically log him out.
But I've noticed many users are there for ever, never logged out. I found out why, by closing their browsers, they never manually or automatically logged out, so their user Ids will never be removed from the valid user Ids vector.
So, my question is : how do I detect users closing their browsers, so my servlet can remove their Ids from the vector ?
I see some light at the end of the tunnel, but there is still a problem, my program has something like this :
Active User List :
User_1 : Machine_1 [ IP_1 address ]
User_2 : Machine_2 [ IP_2 address ]
User_3 : Machine_3 [ IP_3 address ]
...
How do I know, from the session listener, which user's session has ended and therefore remove him from my list?
I was hoping when the session ends, the HttpServlet's destroy() method would be called and I can remove the user Id in there, but it never gets called when user closes his browser, why? And is there any other method in the HttpServlet that gets called when a session closes?
There is no way to know on the server-side (unless you are using some JavaScript to send a message to the server) that the browser has closed. How could there be? Think of how HTTP works - everything is request and response.
However, the application server will track when Sessions are active and will even tell you when a Session has been destroyed (such as due to time-out). Take a look at this page to see how to configure a HttpSessionListener to receive these events. Then you can simply keep track of the number of active sessions.
The number of active sessions will lag behind the actual number of current users, since some period of (configurable) time has to elapse before a session is timed out; however, this should be somewhat close (you can lower the session-timeout to increase the accuracy) and it is a lot cleaner and easier than 1) tracking Sessions yourself or 2) sending some asynchronous JavaScript to the server when a browser is closed (which is not guaranteed to be sent).
I suggest you remove the ID when the Servlet engine destroys the session. Register a HttpSessionListener that removes the user's ID when sessionDestroyed() is called.
Diodeus's idea will only help you detect that the session is over more immediately.
in JavaScript you can use the onbeforeclose event to pass a call back to the server when the user closes the browser.
I typically use a synchronous Ajax call to do this.
I had to do that recently, and after some searches, I found some solutions on the Net... all of them non working universally!
onbeforeclose and onclose events are used for this task. But there are two catches: they are fired when the user reload the page or even just change the current page. There are tricks to see if the event is actually a window/page/tab closing (looking at some Dom properties going haywire on closing event), but:
They are browser dependent
The tricks are undocumented, thus brittle
And actually they vary along the browser version/update...
And worst of all, these events are now ignored by most modern browsers, because they have been abused by rogue ads popping out windows when browser was closing. They are not fired in Safari, Opera, IE7, etc.
As pointed out, most Web applications with login destroy the user session after a while, eg. half an hour. I was asked to logout on browser closing to free faster a precious resource: licenses. Because users often forget to log out...
The solution I gave was to ping with an Ajax request (sending the user ID) the server on regular intervals (say 1 minute). If the server receives no ping for, say, 3 minutes, it disconnect the user.
There is no foolproof way to do what you're trying to do, but both sblundy and Diodeus have plans that will cover most circumstances. There is nothing you can do about someone who turns off Javascript in their browser, or their internet connection goes down, or their power goes out. You should just cull sessions after a certain period of inactivity (which I think is what sblundy's suggestion of listening for session destruction will do).

Categories

Resources