shinsenter / defer.js

🥇 A lightweight JavaScript library that helps you lazy load (almost) anything. Defer.js is dependency-free, highly efficient, and optimized for Web Vitals.
https://shinsenter.github.io/defer.js/
MIT License
277 stars 45 forks source link

The first tap on any link is not working on mobile safari #121

Closed f2exer closed 1 year ago

f2exer commented 1 year ago

Safari version 16.1.2. With defer.js code on site the first tap on any link does nothing and then second tap works as expected. It doesn't matter if deferred scripts were loaded or not. Without defer.js everything works correctly. Site example: https://sufityideal.pl. Without defer.js: https://sufityideal.pl/index-new.php

shinsenter commented 1 year ago

Hey @f2exer

Currently, the problem you described cannot be reproduced on my Safari browser, and the library works fine on other browsers, so I think there is a possibility that this may be a temporary error in some cases.

I hope you can provide a video showing the error or another intermediate environment where this error occurs.

I will look into your issue next week.

Regards

shinsenter commented 1 year ago

Hey @f2exer

I have not been able to reproduce the error you encountered on mobile Safari.

To determine if one of your script files may be conflicting with this library, please try disabling all script tags with type="deferscript" and see if the error persists. If it does not resolve your issue, please try setting the waitForUserAction parameter of the Defer.all() function to false and see if that helps.

By the way, I am currently working on a draft version of the next release of this library. If you have time, please try it out to see if the new version helps resolve the issue. https://raw.githubusercontent.com/shinsenter/defer.js/develop/dist/defer.min.js

Please let me know the results of these solutions. Thank you.

f2exer commented 1 year ago

Thanks for the answer. This is completely "feature" of ios (safari and chrome behave the same) .

Steps to reproduce:

  1. Insert links on the empty page.
  2. Insert deferred script (inline or with src attribute) with type "your-type". Deferred script must have code to generate anchor, for example: document.getElementById("element-id-on-the-page").innerHTML='<a href="javascript:void();" onclick="alert(\'test3 alert\');">link generated by deferred script</a>';
  3. Insert defer.js code to head.
  4. Insert Defer.all('script[type="your-type"]', 0, true); in the end of the page.

Steps to fix:

  1. Add the pause to Defer.all. Minimal pause is about 410 for inline deferred script and 110 for script with src attribute. For example: Defer.all('script[type="your-type"]', 410, true);. That fixes "double tap" in that case when you directly tap on the link (without scrolling or anything else) and deferred script still didn't load.
  2. Add the code (for example): window.addEventListener('touchstart', () => {}); window.addEventListener('touchmove', () => {}); That fixes "double tap" when deferred script already loaded.
  3. In some cases (I think it's related to css :hover on the page) the second item doesn't work. Then you can disable passive mode in window.addEventListener: window.addEventListener('touchmove', () => {}, {passive: false}); (of course you can check for the passive option support, link)

Sorry for disturbing. I'm done with it.

shinsenter commented 1 year ago

@f2exer Thanks for the details. Since it has been solved, I will close the issue. I will also test using your steps.

Best regards.

shinsenter commented 1 year ago

@f2exer I have found an interesting article discussing the phenomenon of "ghost clicks" on mobile browsers, so I would like to note it here in this thread for future reference.

shinsenter commented 1 year ago

Safari iOS stops firing events when a DOM change takes place.

http://www.quirksmode.org/blog/archives/2014/02/the_ios_event_c.html

shinsenter commented 1 year ago

@f2exer I released a temporary fix (#123) for your issue. Please check the v3.6.0 version.