Unwanted script loading and performance issue

Shop Pay script (https://shop.app/pay/hop) loading issue. I understand that seeing this script continue to load is confusing and is actively slowing down your site performance—that’s a critical issue

Every Shopify store load that issue and major performance issue all Shopify store facing so google search gives performance error.

Hey @simon_luis

Can you share the store URL from this screenshot?

You can see that issue in all shopify store @Liam-Shopify
i have already mentioned issue to support as well but not getting any fast solutions for that.

you can test it here https://ramautomations.com/

Hi again @simon_luis

What are the conditions where you’re seeing this fail? I’m seeing 200 on Chrome and this script doesn’t even appear for me on Firefox:

Please can you check in chrome its have issue and also impacted in google search console result as well please check that

For me also same issue

URL: Coastal Frames (Bay Frames) – Demo LIVEARf

@LIVEARf @Liam-Shopify i already informed to support but they not take immediate action and close my ticket without proper answer and resolution.

They have said they need to investigate the issue. There isn’t anything else they can report back right now.

@Luke as developer i checked almost 10 shopify store and all have same issue and its impacting on seo and we are losing rank.

Hi folks!

I investigated the issue and it seems like one of Shop Pay’s analytics beacons is failing unintentionally. Thank you for raising this, we informed the relevant team and will fix it as soon as possible.

The issue has no impact on the page functionality and loading performance.

@simon_luis Looking at the public data from the Chrome User Experience Report, I can see that the store has been declining across all loading metrics in the recent weeks. This is what you’re seeing in Google Search Console as well. I suggest going through this guide to pinpoint the slow theme logic on the server and checking out performance.shopify.com for the overall guidance around performance.

@Mateusz-Shopify Script failed load takes time average 5 to 20 sec and in after that failed the another script like live chat or tawk to load so that much time there is not loading live chat script. So that is not good thing.

I understand you’re concerned but as I mentioned this is just an analytics beacon. It’s asynchronous and doesn’t interfere with anything else on the page. It also responds very quickly, just gets blocked because of incorrect security headers:

We are going to fix it, but it won’t change anything regarding your store’s performance issues.

I am facing the same issue in many of my stores as well. @Liam-Shopify , @simon_luis

@simon_luis , have you found any solution? If so, please share it with us.

@Devraj_Jangid1 no didn’t get because its from shopify backend so we are not able to do anything and support said we are working but i didn’t think still they made any progress on it

There is anyone got solutions for that because i already told support but look like they not helped in that.

I have found a solution and have implemented on my current website

Warning: Only use this if you are not using shop pay.

On this file - layout/theme.liquid , there are two scripts here.

1st script above this part - {{ content_for_header }}


<script>                                                                                                                                                       
    (function() {                                                                                                                                                
      // Block fetch requests to shop.app                                                                                                                        
      const originalFetch = window.fetch;                                                                                                                        
      window.fetch = function(url, options) {                                                                                                                    
        const urlStr = typeof url === 'string' ? url : url?.url || '';                                                                                           
        if (urlStr.includes('shop.app') || urlStr.includes('pay/hop')) {                                                                                         
          console.warn('Blocked Shop Pay request:', urlStr);                                                                                                     
          return Promise.resolve(new Response('{}', { status: 200 }));                                                                                           
        }                                                                                                                                                        
        return originalFetch.apply(this, arguments);                                                                                                             
      };                                                                                                                                                         
                                                                                                                                                                 
      // Block XMLHttpRequest to shop.app                                                                                                                        
      const originalXHROpen = XMLHttpRequest.prototype.open;                                                                                                     
      XMLHttpRequest.prototype.open = function(method, url) {                                                                                                    
        if (url && (url.includes('shop.app') || url.includes('pay/hop'))) {                                                                                      
          console.warn('Blocked Shop Pay XHR:', url);                                                                                                            
          this.\_blocked = true;                                                                                                                                  
        }                                                                                                                                                        
        return originalXHROpen.apply(this, arguments);                                                                                                           
      };                                                                                                                                                         
      const originalXHRSend = XMLHttpRequest.prototype.send;                                                                                                     
      XMLHttpRequest.prototype.send = function() {                                                                                                               
        if (this.\_blocked) return;                                                                                                                               
        return originalXHRSend.apply(this, arguments);                                                                                                           
      };                                                                                                                                                         
                                                                                                                                                                 
      // Block iframes to shop.app                                                                                                                               
      const originalCreateElement = document.createElement.bind(document);                                                                                       
      document.createElement = function(tagName) {                                                                                                               
        const element = originalCreateElement(tagName);                                                                                                          
        if (tagName.toLowerCase() === 'iframe') {                                                                                                                
          const origSetAttr = element.setAttribute.bind(element);                                                                                                
          element.setAttribute = function(name, value) {                                                                                                         
            if (name === 'src' && value && (value.includes('shop.app') || value.includes('pay/hop'))) {                                                          
              console.warn('Blocked Shop Pay iframe:', value);                                                                                                   
              return;                                                                                                                                            
            }                                                                                                                                                    
            return origSetAttr(name, value);                                                                                                                     
          };                                                                                                                                                     
        }                                                                                                                                                        
        // Also block undefined stylesheets                                                                                                                      
        if (tagName.toLowerCase() === 'link') {                                                                                                                  
          const origSetAttr = element.setAttribute.bind(element);                                                                                                
          element.setAttribute = function(name, value) {                                                                                                         
            if (name === 'href' && (value === 'undefined' || value === '/undefined' || value.endsWith('/undefined'))) {                                          
              console.warn('Blocked broken stylesheet:', value);                                                                                                 
              return;                                                                                                                                            
            }                                                                                                                                                    
            return origSetAttr(name, value);                                                                                                                     
          };                                                                                                                                                     
        }                                                                                                                                                        
        return element;                                                                                                                                          
      };                                                                                                                                                         
    })();                                                                                                                                                        
  </script>

2nd script AFTER {{ content_for_header }}

<script>                                                                                                                                                       
    (function() {                                                                                                                                                
      // Remove shop.app iframes and broken stylesheets                                                                                                          
      function cleanupDOM() {                                                                                                                                    
        // Remove shop.app iframes                                                                                                                               
        document.querySelectorAll('iframe').forEach(function(iframe) {                                                                                           
          var src = iframe.src || iframe.getAttribute('src') || '';                                                                                              
          if (src.includes('shop.app') || src.includes('pay/hop')) {                                                                                             
            console.warn('Removed Shop Pay iframe:', src);                                                                                                       
            iframe.remove();                                                                                                                                     
          }                                                                                                                                                      
        });                                                                                                                                                      
        // Remove broken stylesheets                                                                                                                             
        document.querySelectorAll('link[rel="stylesheet"]').forEach(function(link) {                                                                             
          var href = link.getAttribute('href');                                                                                                                  
          if (!href || href === 'undefined' || href === '/undefined' || href.endsWith('/undefined') || href === 'null') {                                        
            console.warn('Removed broken stylesheet:', href);                                                                                                    
            link.remove();                                                                                                                                       
          }                                                                                                                                                      
        });                                                                                                                                                      
      }                                                                                                                                                          
      cleanupDOM();                                                                                                                                              
                                                                                                                                                                 
      // Watch for new iframes and broken links                                                                                                                  
      var observer = new MutationObserver(function(mutations) {                                                                                                  
        mutations.forEach(function(mutation) {                                                                                                                   
          mutation.addedNodes.forEach(function(node) {                                                                                                           
            if (node.nodeType !== 1) return;                                                                                                                     
            // Check iframes                                                                                                                                     
            if (node.tagName === 'IFRAME') {                                                                                                                     
              var src = node.src || node.getAttribute('src') || '';                                                                                              
              if (src.includes('shop.app') || src.includes('pay/hop')) {                                                                                         
                console.warn('Blocked Shop Pay iframe:', src);                                                                                                   
                node.remove();                                                                                                                                   
              }                                                                                                                                                  
            }                                                                                                                                                    
            // Check links                                                                                                                                       
            if (node.tagName === 'LINK' && node.rel === 'stylesheet') {                                                                                          
              var href = node.getAttribute('href');                                                                                                              
              if (!href || href === 'undefined' || href === '/undefined' || href.endsWith('/undefined') || href === 'null') {                                    
                console.warn('Blocked broken stylesheet:', href);                                                                                                
                node.remove();                                                                                                                                   
              }                                                                                                                                                  
            }                                                                                                                                                    
            // Also check children                                                                                                                               
            if (node.querySelectorAll) {                                                                                                                         
              node.querySelectorAll('iframe').forEach(function(iframe) {                                                                                         
                var src = iframe.src || iframe.getAttribute('src') || '';                                                                                        
                if (src.includes('shop.app') || src.includes('pay/hop')) {                                                                                       
                  console.warn('Blocked nested Shop Pay iframe:', src);                                                                                          
                  iframe.remove();                                                                                                                               
                }                                                                                                                                                
              });                                                                                                                                                
            }                                                                                                                                                    
          });                                                                                                                                                    
        });                                                                                                                                                      
      });                                                                                                                                                        
      observer.observe(document.documentElement, { childList: true, subtree: true });                                                                            
                                                                                                                                                                 
      // Also intercept iframe.src property setter                                                                                                               
      var iframeProto = HTMLIFrameElement.prototype;                                                                                                             
      var srcDescriptor = Object.getOwnPropertyDescriptor(iframeProto, 'src');                                                                                   
      if (srcDescriptor && srcDescriptor.set) {                                                                                                                  
        Object.defineProperty(iframeProto, 'src', {                                                                                                              
          set: function(value) {                                                                                                                                 
            if (value && (value.includes('shop.app') || value.includes('pay/hop'))) {                                                                            
              console.warn('Blocked Shop Pay iframe src:', value);                                                                                               
              return;                                                                                                                                            
            }                                                                                                                                                    
            srcDescriptor.set.call(this, value);                                                                                                                 
          },                                                                                                                                                     
          get: srcDescriptor.get                                                                                                                                 
        });                                                                                                                                                      
      }                                                                                                                                                          
                                                                                                                                                                 
      // Run cleanup periodically for first few seconds                                                                                                          
      var cleanupCount = 0;                                                                                                                                      
      var cleanupInterval = setInterval(function() {                                                                                                             
        cleanupDOM();                                                                                                                                            
        cleanupCount++;                                                                                                                                          
        if (cleanupCount > 10) clearInterval(cleanupInterval);                                                                                                   
      }, 500);                                                                                                                                                   
    })();                                                                                                                                                        
  </script>

Basically:

  <head>                                                                                                                                                         
    ...                                                                                                                                                          
                                                                                                                                                                 
    <!-- 1st SCRIPT -->                                                                                                                                   
    <script>...</script>                                                                                                                                         
                                                                                                                                                                 
    {{ content_for_header }}                                                                                                                                     
                                                                                                                                                                 
    <!-- 2nd SCRIPT -->                                                                                                                                       
    <script>...</script>                                                                                                                                         
                                                                                                                                                                 
    ...                                                                                                                                                          
  </head>

SHOP PAY BLOCKER

Blocks: shop.app, pay/hop                                                                                                                                    
                                                                                                                                                             
Implementation:                                                                                                                                              
1. Override window.fetch() - returns empty Response for blocked URLs                                                                                         
2. Override XMLHttpRequest.open() - sets _blocked flag, send() checks flag                                                                                   
3. Override document.createElement() - intercepts iframe/link setAttribute()                                                                                 
4. Override HTMLIFrameElement.prototype.src setter - blocks src assignment                                                                                   
5. MutationObserver on document.documentElement - removes blocked iframes/links                                                                              
6. setInterval cleanup every 500ms x 10 iterations                                                                                                           
                                                                                                                                                             
Pattern matched: url.includes('shop.app') || url.includes('pay/hop')
2 Likes

@getparth can you post proper solution with changes because if i am not developer then i am might be not able to do that.

Hi,

These forums are for developers using Shopify API’s. I’d advise visiting the merchant forums or hiring someone to help you with technical work on your store at somewhere like Storetasker.