Вызов PhantomJS из PHP - производительность


В настоящее время я выполняю PhantomJS (с PHP) для надежного рендеринга некоторого HTML (с использованием сторонних js-библиотек, которые нелегко воспроизвести в PHP), а затем отправляю отрисованный HTML обратно клиенту.

$fh = fopen('/dev/shm/graph-'.$sig.'.html', 'w');
fwrite($fh, $html);
fclose($fh);
$stime = microtime(true);
$res = exec('/usr/bin/phantomjs /home/me/www/js/render_svg.js '.
                  escapeshellarg($sig), $output, $return_var);
var_dump(microtime(true)-$stime);  // 400 ms
print implode("\n", $output);
exit();

Render_svg.js :

var system = require('system');
var fs = require('fs');
var page = require('webpage').create();
page.onLoadFinished = function() {
    system.stdout.write(page.content);
    phantom.exit(0);
};
content = '';
f = fs.open('/dev/shm/graph-'+system.args[1]+'.html', 'r');
content += f.read();
page.content = content;

Время выполнения для PhantomJS составляет около 400 мс, что супер, но, вероятно, слишком большая задержка для использования в производстве. Есть ли какой-либо способ уменьшить это, например, не используя exec для запуска phantomjs каждый раз, но имея его уже работает в фоновом режиме?

Author: EoghanM, 2014-02-03

3 answers

Вы можете попробовать модуль веб-сервера: http://phantomjs.org/api/webserver/

Здесь есть учебник по этому вопросу: http://benjaminbenben.com/2013/07/28/phantomjs-webserver/

(Если вы попробуете это, я хотел бы услышать, как вы справляетесь и как задержка сравнивается с вашими текущими 400 мс при использовании exec.)

Кстати, я думаю, что в лицензии мангуста недавно произошли изменения, которые сделали ее несовместимой с лицензией PhantomJS. Так что вполне возможно, что эта функция будет исчезнет в будущих выпусках. (Также были разговоры о переходе в альтернативную библиотеку на мангуста, и в этом случае она может не исчезнуть!)

 2
Author: Darren Cook, 2014-08-25 18:52:59

Ответ благодаря Даррену Куку:

$fh = fopen('/dev/shm/graph-'.$sig.'.full.html', 'w');
fwrite($fh, $html);
fclose($fh);
$stime = microtime(true);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://127.0.0.1:8080');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'sig='.$sig);
$output = curl_exec($ch);
curl_close($ch);
var_dump(microtime(true)-$stime); // 150ms
print $output;
exit();

Render_svg.js :

var system = require('system');
var fs = require('fs');
var page = require('webpage').create();
var server = require('webserver').create();
var service = server.listen('127.0.0.1:8080', function(request, response) {
    var stime = new Date();
    content = '';
    f = fs.open('/dev/shm/graph-'+request.post['sig']+'.full.html', 'r');
    content += f.read();
    page.content = content;
    page.onLoadFinished = function() {
        response.statusCode = 200;
        response.write(page.content);
        response.close();
    };    
});
 2
Author: EoghanM, 2014-02-04 10:40:26

Короче говоря, нет. PhantomJS не может быть запущен как демон или сервер, поэтому вам нужно будет выполнять этот скрипт каждый раз. Если вы хотите повысить производительность, вам следует попробовать найти другой метод отображения html.

 -2
Author: smithbh, 2014-02-03 18:40:26