Too slow PhantomJS script - php

I need to get the items(with selector a[id=test]) from the page that is loaded by ajax. For this I use phantomjs.
In PHP:
$phantom_path = '/usr/bin/phantomjs';
$names = shell_exec("$phantom_path model/phantomscript-names.js $url");
in phantomjs i received items:
var page = require('webpage').create(),
system = require('system'),
url = system.args[1];
page.open(url, function(status) {
page.injectJs('jquery-2.1.4.min.js');
var links = page.evaluate(function() {
return [].map.call(document.querySelectorAll('a[id=test]'), function(link) {
return link.innerText;
});
});
console.log(links.join('\n'));
phantom.exit();
});
the script runs for about a minute for each page.
whether it is possible to reduce this time using phantomjs or i need to use another tool for this?

On some sites I've found this benefits the load time on Phantom JS.
on other sites the images still come up and it makes no difference.
page.settings.loadImages = false;

Related

using ajax to fetch a result from php and reload page

So I have been working on this for hours now, I have read a bunch of StackOverflow posts and I am still having no luck.
I have a page that has 2 sections to it, depending on the int in the database will depend on which section is being displayed at which time.
My goal is to have the page look to see if the database status has changed from the current one and if it has then refresh the page, if not then do nothing but re-run every 10 seconds.
I run PHP at the top of my page that gets the int from the database
$online_status = Online_status::find_by_id(1);
I then use HTML to load the status into something that jquery can access
<input type="hidden" id="statusID" value="<?php echo $online_status->status; ?>">
<span id="result"></span>
So at the bottom of my page, I added some jquery and ajax
$(document).ready(function(){
$(function liveCheck(){
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST',
success:function(data){
if(!data.error){
$newResult = $('#result').html(data);
window.setInterval(function(){
liveCheck();
}, 10000);
}
}
});
});
liveCheck();
});
this then goes to another PHP page that runs the following code
if(isset($_POST['search'])){
$current_status = $_POST['search'];
$online_status = Online_status::find_by_id(1);
if($current_status != $online_status->status){
echo "<script>location.reload()&semi;</script>";
}else{
}
}
the jquery then loads into the HTML section with the id of "result" as shown earlier. I know this is a very bad way to do this, and as a result, it will work at the beginning but the longer you leave it on the page the slower the page gets, till it just freezes.
If anyone is able to point me towards a proper method I would be very grateful.
Thank you!!
js:
(function(){
function liveCheck(){
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST',
success:function(data){
if(data.trim() == ''){
location.reload();
}else{
$('#result').html(data);
window.setTimeout(function(){
liveCheck();
}, 10000);
}
}
});
}
$(function(){
liveCheck();
});
})(jQuery)
php:
<?php
if(isset($_POST['search'])){
$current_status = $_POST['search'];
$online_status = Online_status::find_by_id(1);
if($current_status != $online_status->status){
$data = '';
}else{
$data = 'some html';
}
echo $data;
}
Your page is slowing down because you are creating a new interval every time you call the liveCheck function. Over time, you have many intervals running and sending requests to your PHP file concurrently. You can verify this behavior by opening the developer console in your browser and monitoring the Network tab.
What you should do instead is set the interval once, and perform the $.ajax call inside that interval. Additionally, it's good practice to not send a new request if a current request is pending, by implementing a boolean state variable that is true while an request is pending and false when that request completes.
It looks like the intended behavior of your function is to just reload the page when the $online_status->status changes, is that correct? If so, change your PHP to just echo true or 1 (anything really) and rewrite your JS as:
function liveCheck() {
if (liveCheckPending == true)
return;
liveCheckPending = true;
var search = $('#statusID').val();
$.ajax({
url:'check_live.php',
data:{search:search},
type:'POST'
}).done(function(data){
if (!data.error)
location.reload();
}).always(function(data){
liveCheckPending = false;
});
}
var liveCheckPending = false;
setInterval(liveCheck, 10000);

Simple PHP script on loop causing server CPU overload

I have an AJAX call on a loop, set to 1000 miliseconds.
The PHP script is simple, it just puts some information (a number) into a session variable. Yesterday I've recived an email from my hosting provider (HostGator), which states that I've been using 75%+ of CPU on shared hosting. After looking the logs, I've found that the problem is in that AJAX call. Here is the code:
PHP (ajax.session.php):
<?php
session_start();
$movieID_e = $_POST['id'];
$state = trim(strtolower($_POST['status']));
if ($state == 'playing') {
if (empty($_SESSION[$movieID_e])) {
$_SESSION[$movieID_e] = 1;
}
else {
$_SESSION[$movieID_e]++;
}
}
echo $_SESSION[$movieID_e];
?>
Javascript:
function interval(func,wait,times){
var interv = function(w, t){
return function(){
if(typeof t === "undefined" || t-- > 0){
setTimeout(interv, w);
try{
func.call(null);
}
catch(e){
t = 0;
throw e.toString();
}
}
};
}(wait,times);
setTimeout(interv, wait);
};
var watched = (function() {
var executed = false;
return function () {
$.post('ajax.session.php',{id:'<?php echo encrypt($id); ?>',status:'none'},function(result) {
if (result == 1000) {
if (!executed) {
executed = true;
var highlightad = introJs();
highlightad.setOptions({
steps: [
{
element: '#advertisment1',
intro: 'test',
position: 'bottom'
},
{
element: '#advertisment2',
intro: 'test2',
position: 'left'
}
]
});
highlightad.start();
}
}
else {
executed = false;
return false;
}
});
};
})();
interval(function(){watched()},1000,3000);
Explanation of JS:
function interval() -> Alternative to setInterval(), taken from thecodeship.com
function watched() -> AJAX request to file ajax.session.php shown above. If the result is 1000 then it highlights a part of a website using Intro.JS.
interval(function(){watched()},1000,3000); -> repeat watched() every 1000ms, max. number of repetitions is 3000 times.
Note that PHP script (ajax.session.php) is also called by AJAX from another script, also with function interval() every 1000ms.
I am using the interval() every second to count the number of seconds that past in a video player.
Do you have any suggestions on how to prevent CPU overload with the following script?
What server stats do you have? I think the problem is, that you have too much traffic for a weak server. Also of course 1second intervals for ajax calls are tooo often. Check your console, you will see that most of them will get timedout.
Sessions will be server side, so it will use servers resources. If you would convert your script to cookies, then the data will be stored in users browser. Also you could use $.cookie jQuery plugin to easily read the cookies via JS, so no need to ajax call.
Also, I would not recommend to use sessions at all, unless making some highly secure login system. I would recommend to use memcache to store temporary data.
Also, I'm pretty sure your JS could use optimization, because on first look I didn't see that you would check if one ajax call is active already. So it wouldn't ajax call before the last call was finished. Otherwise you can imagine the pointless ajax calls going to the server, where 50% of them get timedout.

Phantomjs not creating screenshot

I was try to create a web screenshot with phantomjs,But alwaise it result a blank image.I am using Fedora OS.Here is my javascript.
screen.js
var WebPage = require('webpage');
page = WebPage.create();
page.open('http://google.com');
page.onLoadFinished = function() {
page.render('googleScreenShot' + '.png');
phantom.exit();}
And here is my php code
shot.php
$exec = '/var/www/html/test/bin/phantomjs /var/www/html/test/screen.js';
$escaped_command = escapeshellcmd($exec);
exec($escaped_command);
But the created image was blank.phantomjs have executre permission.Please help me
I am not sure but this may work,try it
var WebPage = require('webpage');
page = WebPage.create();
page.open('http://google.com');
page.onLoadFinished = function() {
window.setTimeout(function () {
page.render('googleScreenShot' + '.png');
phantom.exit();
}, 2000);
}
You have a problem because the time your code execute the next line of code is more faster than phantomjs logging that page.onLoadStarted is True.
easy and clean way to fix this is by adding a time interval of 100 ms between each function and make all your code in functions, check Vijay Boyapati method for more clarification : https://stackoverflow.com/a/9256079/1738230
In dealing with this problem I completed a code module, as follows:
link
You can download it locally, and then invoke it by command
phantomjs rasterize.js "http://www.google.com" 800px*800px > wait.html

How To Use setInterval in PHP?

I want to ask that how can i use php function again and again after some time automatically just like setInterval in Javascript. We set the time and it is on its job until the script is aborted or closed.
INDEX.PHP
<?
$Wall = new Wall_Updates();
$updatesarray=$Wall->Updates();
foreach($updatesarray as $data)
{
$likes=$data['likes'];
?>
<div id="likes"><?php echo $likes; ?></div>
<?
}
?>
And Wall_Updates() Function is defined here in FUNCTION.PHP
<?php
class Wall_Updates {
public function Updates() {
$myname=$_COOKIE['usename'];
$query=mysql_query("SELECT * FROM posts WHERE name='$myname'");
while($row=mysql_fetch_array($query))
$data[]=$row;
return $data;
}
}
?>
I want this Wall_Updates() function to fetch data from mysql again and again.So, It will be Updated.
For the record: I think it's bad idea. But whatever :)
Try this code
function setInterval($f, $milliseconds)
{
$seconds=(int)$milliseconds/1000;
while(true)
{
$f();
sleep($seconds);
}
}
Usage:
setInterval(function(){
echo "hi!\n";
}, 1000);
Or:
$a=1;
$b=2;
setInterval(function() use($a, $b) {
echo 'a='.$a.'; $b='.$b."\n";
}, 1000);
your solution is quite simple :
$event = new EVTimer(10,2, function() {
Do your things .. :)
});
https://www.php.net/manual/en/ev.examples.php
I would suggest using setInterval to poll for results from a .php page using AJAx and then output your results.
So it would look something like this using jQuery:
<script>
var poll = true;
var getData = function() {
if (poll) {
$.get('getData.php', function(data) { $('#likes').html(data); });
}
};
$(document).ready(function() {
setInterval(getData, 5000);
$('.comm').click(function() { poll = false; });
$('.comm').blur(function() { poll = true; });
});
</script>
It isn't clear what you want to achieve exactly.
Are you aware that PHP only delivers content on request?
If you want the server to update something once in a while (a file for example), use a cronjob (on *nix).
If you want your WEBPAGE to re-query something, do it in javascript and call a PHP script that delivers fresh content.
Unlike Javascript, PHP is executed on the server side. There is no setTimeout functionality in PHP. You can get close by using cronjobs - or other PHP scripts - that call your scripts though.
I will surgest that you use a cron job to implement such functionality in your code.
Cron will run in the background based on the instruction you give it. check out this article
Since the asynchronous concept of web development has to do with effecting the changes on a web page without reloading the page, we must not always run to the ways of Ajax when ever we need such effects on our web pages.
PHP can simply do the job of going to the database # sleep seconds to retrieve some sets of data for our usage especially for chat application purposes.
See the below codes:
function setInterval ( $func, $seconds )
{
$seconds = (int)$seconds;
$_func = $func;
while ( true )
{
$_func;
sleep($seconds);
}
}
Now, let's say we have a function get_msg() that goes to the database to download some sets of information. If we must do that repeatedly without the repeated usage of button calls, then, see the usage of the setInterval function written above with the get_msg function.
setInterval ( get_msg(), 5 );
Javascript executes setInterval in other threads to continue its code-flow execution. But php hangs on the line you have called the function that is implemented by for loops.
However php supports multithreading and forking tools, but they're not recommended and not thread safety yet.

Is there a better way to track pagination with hashtags?

Using a hashchange event I'm detecting when a user clicks the back button in a browser and changing the URL accordingly. Is there a better way to do this for pagination? I'm currently changing the URL after a user clicks my pagination control like so:
$(".pager").click(function(){
var start = null;
if ($.browser.msie) {
start = $(this).attr('href').slice($(this).attr('href').indexOf('#')+1);
}
else {
start = $(this).attr('href').substr(1);
}
$('#start').val(start);
$.post("visits_results.php", $("#profile_form_id").serialize(),
function(data) {
$('#search_results').html(data);
location.href = "#visits=" + start;
});
return false;
});
My javascript to detect the back button looks like this:
function myHashChangeCallback(hash) {
if (hash == "") {
$("#loadImage").show();
var no_cache = new Date().getTime();
$('#main').load("home.php?cache=" + no_cache, function () {
$("#loadImage").hide();
});
return false;
}
else {
// adding code to parse the hash URL and see what page I'm on...is there a better way?;
}
}
function hashCheck() {
var hash = window.location.hash;
if (hash != _hash) {
_hash = hash;
myHashChangeCallback(hash);
}
}
I currently plan on checking each hashtag and the value to see what page I should load unless there is a better more efficient way.
Any thoughts or suggestions?
The jQuery Address plugin does this very well. Once setup it provides a series of logical navigation events which you can hook into. It also has very good support for history.pushState() which eliminates the need for hashtags in newer browsers and has equally good fallback support for those browsers that do not support pushState.
A simple implementation would look like this:
// Run some code on initial load
$.address.init(function(e) {
// Address and path details can be found in the event object
console.log(e);
});
// Handle hashtag/pushState change events
$.address.change(function(e) {
// Do more fancy stuff. Don't forget about the event object.
console.log(e);
});
// Setup jQuery address on some elements
$('a').address();
To enable pushState() support pass an argument to the script like so:
<script type="text/javascript" src="jquery.address-1.3.min.js?state=/absolute/path/to/your/application"></script>

Categories