Я делаю скриншоты HTML-страниц с помощью PhantomJS и успешно использую свой код (см. ниже) уже более года. Однако некоторое время назад я обнаружил, что версия, которую я использую (1.9.8), не поддерживает веб-шрифты: PhantomJS не отображать скриншоты с веб-шрифтами?.
Пытаясь решить эту проблему, я установил PhantomJS 2.0.0. Это решило проблему со шрифтом, но также значительно увеличило время загрузки моего скрипта (обратите внимание, что мой скрипт на 100% одинаков для обоих):
PhantomJS 1.9.8 (Windows): ~1,5 сек.
PhantomJS 2.0.0 (Windows): ~2,25 сек.
Отключение включения веб-шрифтов привело к увеличению производительности примерно на 0,2 секунды для обеих версий.
Я также проверил http://google.com/:
PhantomJS 1.9.8 (Windows): ~1,9 сек.
PhantomJS 2.0.0 (Windows): ~2,6 сек.
Так что вряд ли это связано с моим HTML или тем фактом, что я использую локальные файлы HTML. Следуя этому наблюдению, я провел небольшое исследование и нашел следующие варианты, которые мне не подходят:
- PhantomJS не отображает скриншоты с веб-шрифтами? - удаление
local('...')
из@font-face
не является вариант, так как я загружаю свои шрифты через Google - https://github.com/ariya/phantomjs/issues/13117 — сжатие/ распаковка обоих исполняемых файлов
- http://arunoda.me/blog/phantomjs-webfonts-build.html - звучит идеально, но я застрял с Windows, в то время как предлагаются только Linux и OSX
TL;DR Есть ли у кого-нибудь идеи о том, как я могу улучшить производительность PhantomJS 2.0.0? Улучшения кода, советы по PhantomJS, сборки для Windows (например, 1.9.x, совместимые с веб-шрифтами) — все приветствуется.
Код
Загрузка шрифта в тег <head>
моего локального файла HTML (выглядит нормально, когда я открываю его в своем браузере):
<link href="https://fonts.googleapis.com/css?family=Roboto:500" rel="stylesheet" type="text/css">
Вызов вспомогательной функции PhantomJS PHP:
$output = Image::getPageImage($pathToLocalHTMLFile);
Вспомогательная функция PhantomJS PHP:
class Image {
public static function getPageImage($page, $options = array(), $js = null) {
// Prepare the page path when needed
if (strpos($page, 'http') !== 0) $page = 'file:///' . $page;
// Prepare the PhantomJS directory
$phantomDir = DIR_LIB . 'phantomjs' . DIR_SEPARATOR;
// Add the PhantomJS directory to the PATH
addPath($phantomDir);
// In case no Javascript processing file is given, use the default
if (is_null($js)) $js = $phantomDir . 'phantom.js';
// Prepare the PhantomJS call
$exec = 'phantomjs --ignore-ssl-errors=true ' . $js . ' ' . escapeshellarg($page);
// Prepare the PhantomJS options
foreach ($options as $option) {
$exec .= ' ' . escapeshellarg($option);
}
// Call PhantomJS
exec($exec, $output);// . ' 2>&1', $output, $errorMsg
// Decode and return the image data
return ($output ? base64_decode(reset($output)) : false);
}
}
phantom.js в каталоге PhantomJS:
args = require('system').args;
page = require('webpage').create();
if (typeof args[2] !== undefined) {
page.viewportSize = {
width: args[2],
height: (typeof args[3] === undefined ? args[2] : args[3])
};
}
page.open(args[1], function() {
var width = page.evaluate(function() {
return document.body.offsetWidth;
});
var height = page.evaluate(function() {
return document.body.offsetHeight;
});
page.clipRect = {top: 0, left: 0, width: width, height: height};
var base64 = page.renderBase64('png');
console.log(base64);
phantom.exit();
});
Моя серверная среда — Windows Server 2008 R2 Standard с IIS7.5 + FastCGI под управлением PHP 5.4. Как я уже упоминал ранее, единственная переменная в моих тестах — это версия PhantomJS.
Спасибо за помощь!
casper.options.verbose = true; casper.options.logLevel = "debug";
- person Diego Borges   schedule 03.07.2015