Skip to content

Commit 9d6fa01

Browse files
committed
Moving JS feature
1 parent f4960da commit 9d6fa01

File tree

11 files changed

+2287
-17
lines changed

11 files changed

+2287
-17
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/**
4+
* Copyright © Alexandru-Manuel Carabus All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Hawksama\PerformanceOptimization\Block\Adminhtml\Magento\Config\Block\System\Config\Form\Field\FieldArray;
11+
12+
use \Magento\Framework\Data\Form\Element\Factory;
13+
use \Magento\Backend\Block\Template\Context;
14+
15+
class AbstractFieldArray extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray
16+
{
17+
18+
/**
19+
* @var Factory
20+
*/
21+
protected $_elementFactory;
22+
23+
/**
24+
* Constructor
25+
*
26+
* @param Context $context
27+
* @param Factory $elementFactory
28+
* @param array $data
29+
*/
30+
public function __construct(
31+
Context $context,
32+
Factory $elementFactory,
33+
array $data = []
34+
) {
35+
$this->_elementFactory = $elementFactory;
36+
parent::__construct($context, $data);
37+
}
38+
39+
/**
40+
* @return string
41+
*/
42+
public function _construct()
43+
{
44+
$this->addColumn('defer', ['label' => __('Expression'), 'class' => 'required-entry']);
45+
$this->_addAfter = false;
46+
$this->_addButtonLabel = __('Add');
47+
parent::_construct();
48+
}
49+
}

Helper/Data.php

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ public function getConfig($configName = '')
6565
public function getConfigModule($configName = '', $value = null)
6666
{
6767
$values = $this->configModule;
68-
69-
if (!$configName){
68+
69+
if (!$configName) {
7070
return $values;
7171
}
7272

@@ -107,16 +107,91 @@ public function getArea()
107107
*/
108108
public function getMode(): bool
109109
{
110-
return true;
111110
switch ($this->_appState->getMode()) {
112111
case \Magento\Framework\App\State::MODE_DEFAULT:
113112
case \Magento\Framework\App\State::MODE_PRODUCTION:
114113
return true;
115114
break;
116115
case \Magento\Framework\App\State::MODE_DEVELOPER:
117116
default:
118-
return false;
117+
if ($this->getConfigModule('general/enabled_developer_mode')):
118+
return true;
119+
else :
120+
return false;
121+
endif;
119122
break;
120123
}
121124
}
125+
126+
/**
127+
* @return bool
128+
*/
129+
public function isJsDeferEnabled($request)
130+
{
131+
if (!$this->getConfigModule('general/enabled')) {
132+
return false;
133+
}
134+
135+
$active = $this->getConfigModule('movejs/enabled');
136+
if ($active != 1) {
137+
return false;
138+
}
139+
140+
$active = $this->getConfigModule('movejs/home_page');
141+
if ($active == 1 && $request->getFullActionName() == 'cms_index_index') {
142+
return false;
143+
}
144+
145+
$module = $request->getModuleName();
146+
$controller = $request->getControllerName();
147+
$action = $request->getActionName();
148+
if ($this->regexMatchSimple($this->getConfigModule('movejs/controller'), "{$module}_{$controller}_{$action}", 1))
149+
return false;
150+
if ($this->regexMatchSimple($this->getConfigModule('movejs/path'), $request->getRequestUri(), 2))
151+
return false;
152+
153+
return true;
154+
}
155+
156+
/**
157+
* @return bool
158+
*/
159+
public function regexMatchSimple($regex, $matchTerm, $type)
160+
{
161+
if (!$regex) {
162+
return false;
163+
}
164+
165+
$rules = @unserialize($regex);
166+
if (empty($rules)) {
167+
return false;
168+
}
169+
170+
foreach ($rules as $rule) {
171+
$regex = trim($rule['defer'], '#');
172+
if ($regex == '') {
173+
continue;
174+
}
175+
176+
if ($type == 1) {
177+
$regexs = explode('_', $regex);
178+
switch (count($regexs)) {
179+
case 1:
180+
$regex = $regex . '_index_index';
181+
break;
182+
case 2:
183+
$regex = $regex . '_index';
184+
break;
185+
default:
186+
break;
187+
}
188+
}
189+
190+
$regexp = '#' . $regex . '#';
191+
if (@preg_match($regexp, $matchTerm)) {
192+
return true;
193+
}
194+
}
195+
return false;
196+
}
122197
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
/**
4+
* Copyright © Alexandru-Manuel Carabus All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Hawksama\PerformanceOptimization\Observer\Frontend\Controller;
11+
12+
use Hawksama\PerformanceOptimization\Helper\Data;
13+
14+
class FrontSendResponseBefore implements \Magento\Framework\Event\ObserverInterface
15+
{
16+
/**
17+
* @var Data
18+
*/
19+
protected $helper;
20+
21+
public function __construct(
22+
Data $helper
23+
) {
24+
$this->_helper = $helper;
25+
}
26+
/**
27+
* Execute observer
28+
*
29+
* @param \Magento\Framework\Event\Observer $observer
30+
* @return void
31+
*/
32+
public function execute(
33+
\Magento\Framework\Event\Observer $observer
34+
) {
35+
$request = $observer->getEvent()->getData('request');
36+
if (
37+
!$this->_helper->getConfigModule('general/enabled') ||
38+
!($this->_helper->getMode() && $this->_helper->getArea()) ||
39+
!$this->_helper->isJsDeferEnabled($request)
40+
) {
41+
return;
42+
}
43+
44+
$response = $observer->getEvent()->getData('response');
45+
if (!$response) {
46+
return;
47+
}
48+
49+
$html = $response->getBody();
50+
if ($html == '') {
51+
return;
52+
}
53+
54+
$conditionalJsPattern = '@(?:<script type="text/javascript"|<script)(.*)</script>@msU';
55+
preg_match_all($conditionalJsPattern, $html, $_matches);
56+
$_js_if = implode('', $_matches[0]);
57+
$html = preg_replace($conditionalJsPattern, '', $html);
58+
$html = str_replace('</body>', $_js_if . '</body>', $html);
59+
60+
$response->setBody($html);
61+
}
62+
}

Plugin/Frontend/Magento/Framework/App/Response/Http.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,29 @@ class Http extends \Magento\Framework\View\Element\Template
2525
*/
2626
protected $helper;
2727

28+
/**
29+
* @var bool
30+
*/
2831
protected $compress_css = true;
2932

30-
33+
/**
34+
* @var bool
35+
*/
3136
protected $compress_js = false;
37+
38+
/**
39+
* @var bool
40+
*/
3241
protected $info_comment = false;
42+
43+
/**
44+
* @var bool
45+
*/
3346
protected $remove_comments = false;
3447

35-
// Variables
48+
/**
49+
* @var string
50+
*/
3651
protected $html;
3752

3853
public function __construct(
@@ -43,7 +58,7 @@ public function __construct(
4358
) {
4459
parent::__construct($context, $data);
4560
$this->request = $request;
46-
$this->helper = $helper;
61+
$this->_helper = $helper;
4762
}
4863

4964
/**
@@ -52,13 +67,13 @@ public function __construct(
5267
*/
5368
public function beforeSendResponse(MagentoHttp $response)
5469
{
55-
if (!$this->helper->getConfigModule('general/enabled')) {
70+
if (!$this->_helper->getConfigModule('general/enabled')) {
5671
return;
5772
}
5873

5974
$body = $response->getBody();
6075

61-
$minifyHtml = $this->helper->getConfigModule('general/minify_html');
76+
$minifyHtml = $this->_helper->getConfigModule('general/minify_html');
6277
if ($minifyHtml) {
6378
$body = $this->minifyHtml($body);
6479
}

README.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@
1010

1111

1212
## Main Functionalities
13-
This module eliminates render-blocking CSS files and helps with Google Page Speed results by asynchronously loading CSS using RequireJS. <br />
14-
Extends the Magento 2.3.3 functionality CSS critical path to be compatible with the new asynchronously mode to make the first First Contentful Paint faster. <br />
15-
The production mode is required because in the developer mode the LESS path hints do not work.
13+
Google Page Speed optimizer.
14+
15+
### Main features
16+
- Eliminates render-blocking CSS files by asynchronously loading CSS using RequireJS. <br />
17+
- Minifies the HTML without affecting KnockoutJs, RequireJs, jQuery or VanillaJs.
18+
- Moves all script tags with either the `src` attribute or inline scripts that are loaded in the source page at the bottom of the page before closing `</body>` with the ability to skip some pages or controllers. <br />
19+
- Adds custom `critical.css` file to improve `First Contentful Paint` score. Extends the Magento 2.3.3 functionality CSS critical path to be compatible with the new CSS asynchronously mode. <br />
1620

1721
## Installation
1822
\* = in production please use the `--keep-generated` option
@@ -39,16 +43,21 @@ The production mode is required because in the developer mode the LESS path hint
3943
- Flush the cache by running `php bin/magento cache:flush`
4044

4145
## Configuration
46+
Module enabled by default. CSS critical path recommended.
4247

4348
- Enabled (hawksama_performanceoptimization/general/enabled)
4449

4550
- Minify Html (hawksama_performanceoptimization/general/minify_html)
4651

4752
- RequireJS CSS (hawksama_performanceoptimization/general/requirejs_css)
48-
49-
- Module enabled by default. CSS critical path recommended.
5053

51-
- Stores > Settings > Configuration > HAWKSAMA -> Performance Optimization -> General
54+
- MoveJS to bottom Enabled (hawksama_performanceoptimization/movejs/enabled)
55+
56+
- MoveJS to bottom Exclude Controllers (hawksama_performanceoptimization/movejs/home_page)
57+
58+
- MoveJS to bottom Exclude Paths (hawksama_performanceoptimization/movejs/controller)
59+
60+
- Stores > Settings > Configuration > HAWKSAMA -> Performance Optimization
5261

5362
### Activate CSS critical path
5463

@@ -61,5 +70,11 @@ The production mode is required because in the developer mode the LESS path hint
6170

6271
- Plugin
6372
- beforeSendResponse - Magento\Framework\App\Response\Http > Hawksama\PerformanceOptimization\Plugin\Frontend\Magento\Framework\App\Response\Http
73+
74+
- Observer
75+
- controller_front_send_response_before > Hawksama\PerformanceOptimization\Observer\Frontend\Controller\FrontSendResponseBefore
76+
77+
- Block
78+
- Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray > magento/config/block/system/config/form/field/fieldarray/abstractfieldarray.phtml
6479
## Support
6580

0 commit comments

Comments
 (0)