PluginProbe
JCH Optimize / trunk
JCH Optimize vtrunk
6.0.2 6.0.1 trunk 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.1.0 2.10.0 2.2.0 2.2.1 All 58 releases
jch-optimize / lib / src / Optimize.php

Optimize.php in JCH Optimize trunk, at lib/src/Optimize.php

175 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * JCH Optimize - Performs several front-end optimizations for fast downloads
5 *
6 * @package jchoptimize/core
7 * @author Samuel Marshall <samuel@jch-optimize.net>
8 * @copyright Copyright (c) 2022 Samuel Marshall / JCH Optimize
9 * @license GNU/GPLv3, or later. See LICENSE file
10 *
11 * If LICENSE file missing, see <http://www.gnu.org/licenses/>.
12 */
13
14 namespace JchOptimize\Core;
15
16 // No direct access
17 use _JchOptimizeVendor\V91\Joomla\DI\ContainerAwareInterface;
18 use _JchOptimizeVendor\V91\Joomla\DI\ContainerAwareTrait;
19 use _JchOptimizeVendor\V91\Psr\Log\LoggerAwareInterface;
20 use _JchOptimizeVendor\V91\Psr\Log\LoggerAwareTrait;
21 use CodeAlfa\Minify\Html;
22 use JchOptimize\Core\Debug\JchProfiler;
23 use JchOptimize\Core\Debug\JchProfilerInterface;
24 use JchOptimize\Core\Exception\ExceptionInterface;
25 use JchOptimize\Core\Html\CacheManager;
26 use JchOptimize\Core\Html\HtmlManager;
27 use JchOptimize\Core\Html\HtmlProcessor;
28 use JchOptimize\Core\Platform\ProfilerInterface;
29 use JchOptimize\Core\Platform\UtilityInterface;
30 use JchOptimize\Core\Preloads\Http2Preload;
31
32 use function defined;
33 use function ini_get;
34 use function ini_set;
35 use function json_encode;
36 use function version_compare;
37
38 use const JSON_PRETTY_PRINT;
39 use const JSON_UNESCAPED_SLASHES;
40
41 defined('_JCH_EXEC') or die('Restricted access');
42
43 /**
44 * Main plugin file
45 *
46 */
47 class Optimize implements LoggerAwareInterface, ContainerAwareInterface
48 {
49 use LoggerAwareTrait;
50 use ContainerAwareTrait;
51
52 private string $jit;
53
54 /**
55 * @throws Exception\RuntimeException
56 */
57 public function __construct(
58 private Registry $params,
59 private HtmlProcessor $htmlProcessor,
60 private CacheManager $cacheManager,
61 private HtmlManager $htmlManager,
62 private Http2Preload $http2Preload,
63 private ProfilerInterface $jProfiler,
64 private UtilityInterface $utility
65 ) {
66 $this->jit = ini_get('pcre.jit');
67
68 self::setPcreLimits();
69
70 if (version_compare(PHP_VERSION, '8.0', '<')) {
71 throw new Exception\RuntimeException('PHP Version less than 8.0, Exiting plugin...');
72 }
73 }
74
75 public static function setPcreLimits(): void
76 {
77 ini_set('pcre.backtrack_limit', '1000000');
78 ini_set('pcre.recursion_limit', '1000000');
79 ini_set('pcre.jit', '0');
80 }
81
82 public function process(string $html): string
83 {
84 !JCH_DEBUG ?: $this->jProfiler->start('Process', true);
85
86 try {
87 $this->htmlProcessor->setHtml($html);
88
89 $this->htmlManager->preProcessHtml();
90 $this->htmlProcessor->processCombineJsCss();
91 $this->htmlProcessor->processImageAttributes();
92
93 $this->cacheManager->handleCombineJsCss();
94 $this->cacheManager->handleImgAttributes();
95
96 $this->htmlProcessor->processCdn();
97 $this->htmlProcessor->processLazyLoad();
98 $this->htmlManager->postProcessHtml();
99
100 $optimizedHtml = $this->minifyHtml($this->htmlProcessor->getHtml());
101
102 !JCH_DEBUG ?: $this->jProfiler->stop('Process', true);
103
104 !JCH_DEBUG ?: $this->jProfiler->attachProfiler($optimizedHtml, $this->htmlProcessor->isAmpPage);
105 } catch (ExceptionInterface $e) {
106 $this->logger->error((string)$e);
107
108 $optimizedHtml = $html;
109 }
110
111 $profiler = $this->getContainer()->get(JchProfilerInterface::class);
112
113 if ($profiler instanceof JchProfiler) {
114 $stats = $profiler->snapshot();
115
116 if ($stats) {
117 $this->logger?->debug(
118 json_encode($stats, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
119 );
120 }
121 }
122
123 ini_set('pcre.jit', (string)$this->jit);
124
125 return $optimizedHtml;
126 }
127
128 /**
129 * If parameter is set will minify HTML before sending to browser;
130 * Inline CSS and JS will also be minified if respective parameters are set
131 *
132 * @param string $html
133 *
134 * @return string Optimized HTML
135 */
136 public function minifyHtml(string $html): string
137 {
138 !JCH_DEBUG ?: $this->jProfiler->start('MinifyHtml');
139
140 if (
141 $this->params->get('combine_files_enable', '1')
142 && $this->params->get('html_minify', 0)
143 ) {
144 $options = [];
145
146 if ($this->params->get('css_minify', 0)) {
147 $options['cssMinifier'] = array('CodeAlfa\Minify\Css', 'optimize');
148 }
149
150 if ($this->params->get('js_minify', 0)) {
151 $options['jsMinifier'] = array('CodeAlfa\Minify\Js', 'optimize');
152 }
153
154 $options['jsonMinifier'] = array('CodeAlfa\Minify\Json', 'optimize');
155 $options['minifyLevel'] = $this->params->get('html_minify_level', 0);
156 $options['isXhtml'] = Helper::isXhtml($html);
157 $options['isHtml5'] = Helper::isHtml5($html);
158
159 $htmlMin = Html::optimize($html, $options);
160
161 if ($htmlMin == '') {
162 $this->logger->error('Error while minifying HTML');
163
164 $htmlMin = $html;
165 }
166
167 $html = $htmlMin;
168 }
169
170 !JCH_DEBUG ?: $this->jProfiler->stop('MinifyHtml', true);
171
172 return $html;
173 }
174 }
175