wp-rocket
wp-rocket copied to clipboard
Defer JS compatibility with the Shoptimizer theme
Before submitting an issue please check that you’ve completed the following steps:
- [x] Made sure you’re on the latest version
3.11.5
- [x] Used the search feature to ensure that the bug hasn’t been reported before
Describe the bug When using Defer JS with Shoptimizer, jQuery needs to be excluded from the feature.
This is caused by the following code:
<script type='text/javascript' id='shoptimizer-main-js-after'>
jQuery(document).ready(function($) {
$('body').on('added_to_cart', function(event, fragments, cart_hash) {
if (!$('body').hasClass('elementor-editor-active')) {
$('body').addClass('drawer-open');
}
});
});
document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('click', function(event) {
var is_inner = event.target.closest('.shoptimizer-mini-cart-wrap');
if (!event.target.classList.contains('shoptimizer-mini-cart-wrap') && !is_inner) {
document.querySelector('body').classList.remove('drawer-open');
}
var is_inner2 = event.target.closest('.cart-click');
if (event.target.classList.contains('cart-click') || is_inner2) {
var is_header = event.target.closest('.site-header-cart');
if (is_header) {
event.preventDefault();
document.querySelector('body').classList.toggle('drawer-open');
}
}
if (event.target.classList.contains('close-drawer')) {
document.querySelector('body').classList.remove('drawer-open');
}
});
});
var interceptor = (function(open) {
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
this.addEventListener('readystatechange', function() {
switch (this.readyState) {
case 1:
document.querySelector('#ajax-loading').style.display = 'block';
break;
case 4:
document.querySelector('#ajax-loading').style.display = 'none';
break;
}
}, false);
if (async !== false) {
async = true;
}
open.call(this, method, url, async, user, pass);
};
}(XMLHttpRequest.prototype.open));
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#ajax-loading').style.display = 'none';
});
var observer = new IntersectionObserver(function(entries) {
if (entries[0].intersectionRatio === 0)
document.querySelector('.col-full-nav').classList.add('is_stuck');
else if (entries[0].intersectionRatio === 1)
document.querySelector('.col-full-nav').classList.remove('is_stuck');
}, {
threshold: [0, 1]
});
observer.observe(document.querySelector('.s-observer'));
</script>
Which causes WP Rocket to skip wrapping it inside:
window.addEventListener('DOMContentLoaded', function() {});
Excluding jQuery fixes the issue.
We will need a compatibility file for this case.
To Reproduce Steps to reproduce the behavior:
- Use the Shoptimizer theme
- Enable Defer JS
- See error
Expected behavior The Shoptimizer theme needs to work out for the box with Defer JS.
Screenshots N/A
Additional context Ticket - https://secure.helpscout.net/conversation/1987798788/363719/
Backlog Grooming (for WP Media dev team use only)
- [ ] Reproduce the problem
- [ ] Identify the root cause
- [ ] Scope a solution
- [ ] Estimate the effort
https://secure.helpscout.net/conversation/1992590413/364698?folderId=377611
I have the same issue
Acceptance Criteria:
- When Shoptimizer theme is used, jQuery file needs to be excluded from the Defer JS feature
- When any other theme is used, jQuery file won't be excluded from this feature
- No errors in the JS console when using Defer/Delay JS with this theme (this one goes for QA)
Do we have this theme available on our testing environments?
Yes, it's on this website. I'll reach them and ask for the newest version, just in case.
@Tabrisrp Installed the newest version there, if you want zip, please ping me
@DahmaniAdame I tried to reproduce the issue in local followin your instruction by I got no issue. Could you provide me more context to reproduce the bug?
Reproduce the problem
To find this js code in the page you need to:-
- Disable JS minify and combine features in WPR.
- Enable WooCommerce
- Enable the following option ( Enable sidebar cart drawer ) inside customizer:
Identify the root cause
As mentioned in the issue, we need to exclude jQuery from deferJS feature when this option is enabled.
Scope a solution
So we need to create a compatibility file for this theme and add a callback for the filter rocket_exclude_defer_js
as below:
public function exclude_jquery_deferjs_with_cart_drawer( $exclusions ) {
if ( ! function_exists( 'shoptimizer_get_option' ) || ! shoptimizer_get_option( 'shoptimizer_layout_woocommerce_enable_sidebar_cart' ) ) {
return $exclusions;
}
$exclusions[] = '/jquery-?[0-9.]*(.min|.slim|.slim.min)?.js';
return $exclusions;
}
Estimate the effort
[S]
Few questions @piotrbak that may affect the estimated effort above.
-
Do we need to do anything when their option is enabled after our option is already enabled? I don't think we need to handle this case because for the next cache clear or when the user clears the cache manually all will be good.
-
Excluding jQuery only without jquery migrate will cause any problem for those sites that still have migrate in place?
@engahmeds3ed Thanks for your investigation! For the points:
- Yes, you're right about this, we don't need to do anything here
- We need to exclude both using our current regex:
\/jquery(-migrate)?-?([0-9.]+)?(.min|.slim|.slim.min)?.js(\?(.*))?( |'|"|>)
Solution looks good to me