wp-rocket icon indicating copy to clipboard operation
wp-rocket copied to clipboard

Defer JS compatibility with the Shoptimizer theme

Open DahmaniAdame opened this issue 2 years ago • 1 comments

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:

  1. Use the Shoptimizer theme
  2. Enable Defer JS
  3. 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

DahmaniAdame avatar Aug 31 '22 10:08 DahmaniAdame

https://secure.helpscout.net/conversation/1992590413/364698?folderId=377611

webtrainingwheels avatar Aug 31 '22 16:08 webtrainingwheels

I have the same issue

kevin25 avatar Jun 20 '23 02:06 kevin25

Acceptance Criteria:

  1. When Shoptimizer theme is used, jQuery file needs to be excluded from the Defer JS feature
  2. When any other theme is used, jQuery file won't be excluded from this feature
  3. No errors in the JS console when using Defer/Delay JS with this theme (this one goes for QA)

piotrbak avatar Jul 24 '23 12:07 piotrbak

Do we have this theme available on our testing environments?

remyperona avatar Jul 31 '23 17:07 remyperona

Yes, it's on this website. I'll reach them and ask for the newest version, just in case.

piotrbak avatar Jul 31 '23 18:07 piotrbak

@Tabrisrp Installed the newest version there, if you want zip, please ping me

piotrbak avatar Aug 01 '23 13:08 piotrbak

@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?

CrochetFeve0251 avatar Aug 04 '23 11:08 CrochetFeve0251

Reproduce the problem

To find this js code in the page you need to:-

  1. Disable JS minify and combine features in WPR.
  2. Enable WooCommerce
  3. Enable the following option ( Enable sidebar cart drawer ) inside customizer:

image

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.

  1. 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.

  2. Excluding jQuery only without jquery migrate will cause any problem for those sites that still have migrate in place?

engahmeds3ed avatar Aug 07 '23 11:08 engahmeds3ed

@engahmeds3ed Thanks for your investigation! For the points:

  1. Yes, you're right about this, we don't need to do anything here
  2. We need to exclude both using our current regex: \/jquery(-migrate)?-?([0-9.]+)?(.min|.slim|.slim.min)?.js(\?(.*))?( |'|"|>)

piotrbak avatar Aug 07 '23 11:08 piotrbak

Solution looks good to me

remyperona avatar Aug 07 '23 15:08 remyperona