Prefetch

Prefetch effect

Prefetch pages on hoverIntent!
Prefetch effect
– When the user comes to rest on a link, he usually has the intention of clicking it
– Only in this event, the target page is pre-fetched

It results in faster page loads and usually does not increase bandwidth.

– In case of a touchscreen, the first “touchstart” event disables the prefetch mechanism, also to save bandwidth.

Default: prefetchoff: false

To turn off, please set to true, or supply hints (substrings delimited with “, ” i.e comma and space) to selectively turn off e.g.:

prefetchoff: "login, admin"

…will selectively turn off the prefetch for pages that contain “login” or “admin” in the URL.

Goes hand in hand with the memory and preview effects

20 thoughts on “Prefetch”

  1. Hi Arvind,

    sorry for late response. I took some time to test ajaxify more and analyze its structure better, and also to rewrite my gulp script for assets compiling, now it’s more friendly for minification/uglify of ajaxify source file (with push object functions and commented) to get minified file in few seconds without copying dumped code from console. If you are familiar with gulp, and if you think that script could be helpful for others I can share that part publicly.

    I don’t have problem for sitform.ba to stay in demos, It’s almost finished.

    studioarh.ba is updated to newest version with prefetch and memory, but with some modifications to ajaxify. First I tested this addition for prefetchoff and previewoff if condition:

    If ($.rq(“=”) || !lnk || _searchHints(lnk.href, prefetchoff) || _searchHints(lnk.getAttribute(“class”), prefetchoff)) return; //same page, no data or selected out

    With that it is posible to do
    Link
    to prevent prefetch (npr is my prefetchoff hint). I’m looking for best way to implement same thing for memoryoff.

    Next thing is a bug that I’m experiencing for a long time, where after few page changes in a row page refresh occurs. Afer some code digging, everything points to lAjax part of code. In case of two requests in less than 100ms two requests somehow interacts with each other variables, then breaks and refresh page. This thing is happening even more after prefetch is fixed. Temporarily I added code to prevent prefetch triggering if user hovered and already clicked link under 100ms (time for hover intent to start prefetching). There is no need to prefetch page if link is already clicked anyway.

    You can reproduce bug in two ways:
    – first, as described above, try to hover and click link before prefetch starts (under 100ms)
    – second, turn off memory and prefetch, and set refresh to true, after double clicking same link page refresh occurs (_isHtml function false detects that response is not html) and proceeds to refresh.

    Also, I had to turn off prefetching for touch screen devices again because after testing it noticed that there is no history pushing for mobile devices. Everything else works fine.

    Here is the file with my changes that are not fixing bug, but lowering its occurring chance to minimum. You can compare changes with git.
    studioarh.ba/js/ajaxify.js

    I’m sure you’ll find better solution for that behavior.

    And last thing, my question about recaching in one of previous posts. But that requires implementing memoryoff hints for class atrribute like I did above for prefetchoff.
    For example, with that feature, it will be possible to do something like this.

    Link1

    Link2

    If I know that some changes happened on categories page Link1 will be generated for user, and after click page will be freshly loaded and cached even if it’s already in cache (ignoring cache).

    For other cases Link2 will be generated to load page from cache if it is available, if not, it will load fresh page and cache it(default behavior).

    Currently this is only possible with cache(“f”) call, but that will flush all other cached pages.

    Best regards,
    Edin

    1. I didn’t knew that comments are not html escaped, if you could just edit links to be html visible.
      Link – a href=”./logout” class=”npr”
      Link1 – a href=”./categories” class=”nmm”
      Link2 – a href=”./categories”.
      And sorry for duplicate post, I have no idea how that happened.

      Best regards,
      Edin

      1. Hi Edin, thanks for all the trouble you went through and posting your findings!

        I would like to apologise – I was not aware of the bugs you found at all.

        Currently, I am on a holiday abroad with limited internet access.

        (The double post was also my fault)

        I will be back in the office on Saturday…

        Your findings are invaluable… I would like to make the next version cleaner for sure and that should obviously not be done in a rush.

        We can commute in the meantime, if you like. Will get back to you asap…

        Thanks again, Arvind

  2. Hi,

    tested version 7.3.9 and even some previous versions. Same problem, this is kind of bug that can go unnoticed for a long time.

    No need to rush, when you find some free time you can test it.
    I hope it’s not hard to fix.

    Best regards,
    Edin

    1. Hi Edin,

      thanks for your rigorous testing and finding out, that the bug has been there for quite a while…

      I have attempted to perform a fix just now.
      First of all, I researched the workings of hoverIntent.
      Fortunately, hoverIntent supports event delegation, in order to support dynamically inserted links as well.
      I should have used this type of function call from the start! ->

      $(document).hoverIntent(_prefetch, function(){}, selector);

      …so the change entails a few characters only (not even an additional line).
      I have a better feeling now, because the above call is more elegant and appropriate to our needs.

      Also ran a few tests against our partner site.
      Any dynamically inserted links in the main content div now seem to be affected by hoverIntent as well.

      Here is the (only) file with the new logic.
      If you agree, that it works as you expected in the first place, I will quickly craft a new minified file and new version…

      Thanks again for your sharp thinking and
      Best regards,
      Arvind

      1. Hi Arvind,

        everything works great right now. Thanks for your kind offer. I don’t have my portfolio website yet, but I can give my github profile https://github.com/Edin990 (Edin Topalović).
        Also you already added one of my finished projects (sitform.ba/en) to demo page (will be soon updated to latest ajaxify version).

        Thanks again and
        Best regards,
        Edin

        1. Hi Edin,

          Great stuff – thanks again! Much appreciated!
          I’ve added your GitHub profile to the Thanks page.
          I’ve also added your finished project with the nice visual effects on my Demos page.
          (Couldn’t find it – it didn’t seem to be already there. It now is at the very bottom)
          If you feel like it, you can tell me, what “hints” you’re going to provide in the parameter prefetchoff… (I left the placeholder “todo” in there for now)
          (That will be the first demo page using this new hints parameter!)
          What also came to my mind is that using the new prefetchoff functionality we just worked on only makes sense if memoryoff is not set to true, right?

          I will craft a new Ajaxify version (7.4.1) tomorrow morning.

          You seem to be not only technically, but also strategically fit!
          May I ask you one more question? ->

          What do you think should be the appropriate behaviour of Ajaxify on devices with touchscreens?

          (hoverIntent doesn’t support this feature “out of the box”, as obviously the behaviour is very different on those devices)

          Here’s what I’m doing at the moment:

          $(document).one("touchstart", function(){ prefetchoff = true;}); // for touchscreens - turn prefetch off

          Thanks again and
          Best regards,
          Arvind

          1. Hi,

            i meant studioarh.ba/en (finished one) when wrote sitform.ba/en (current one, few pages are under construction), my bad, probably overthinking about it these days.

            I’m planning to do something like
            memory: ‘nmm, dyn, logout’,
            prefetch: ‘npr, dyn, logout’

            Npr, nmm and dyn will be for leaving future customization options, so I can make href like “…/option?npr” for link to ignore prefetching, “…/option?nmm” to prevent memory or “…/edit?dyn” to prevent both (server side routing will ignore those empty parameters). I would rather use some hint option to force caching of target page again if it is cached already, instead of completely ignoring cache with nmm (for example, user sends form submit request that inserts new data row on target page, but with forced recaching hint in action attribute, with that content will be updated inside memory for future renders of that page), what you think?

            As you mentioned and probably wondering why I use prefetch without memory caching (didn’t used memory because wrong understanding of hints filtering), but tests showed me that prefetch have about 60%, in some cases even more, of its power even without memory, because it’s still loading images and fonts from the target page into browser cache.

            And for touch screen devices, thought about that this morning, saw code implementation and documentation description long time ago. They are impossible to cover with hoverIntent, but from other side, newer laptop/computer screens support touch features, that means on first touch detection prefetch is (probably) lost. Only one thing comes to my mind, some kind of preloading mechanic, for most used links (eg. navigation), to be able to mark them as preloadable and after page finishes loading, they get prefetched in background one by one asynchronously.

            Those are just ideas, and I’m aware of that if they’re mine doesn’t mean they’re best. You decide if they fit in future updates of plugin.

            Best regards,
            Edin

          2. Hi Edin,

            thanks for the extensive reply!

            Hope you don’t mind, that your new page is listed?

            Glad you like the hints features – maybe I should dedicate another page to it, so that everybody understands it.
            I mean, you’re pretty bright, but didn’t get the last details of how to use it either…
            (better documentation might be the solution)

            Interesting, that you think, that the prefetch performs so well (you mentioned it saves 60%, even without memory)
            It should save even more, if memory is enabled…

            Regarding the touchscreen business, I might just have a look, how the competition is handling it…
            (I have no re-collection, why I have completely shut off the prefetch on touchstart)

            Best regards,
            Arvind

          3. Hi Edin,

            I have also re-enabled prefetching on touchstart for touchscreens, very similar to the line of code we just worked on:

            $(document).on("touchstart", selector, _prefetch);

            …available in this file(only)…

            What do you think of that?

            EDIT: The above change works like a charm on our partner site “Öko-Fakt” but fails completely on 4nf.org, to my big surprise(on my mobile phone). Virtually no links function on 4nf.org (no errors in the Chrome console)

            Thanks and
            Best regards,
            Arvind

  3. A little suggestion for Prefetch option. I’m working on one project currently, and have some links that shouldn’t be prefetched, like logout link (in case user accidentaly hover over it, or changes mind and gets logged out anyway). It would be nice to have option to add some class, for example “no-pref” or “prefetch-off” directly on element, so I don’t have to turn it off for whole website. Same thing will be nice for Memory option (“no-memory” or “memory-off”).
    Thanks in advance.

    1. Hi Edin,

      what a great idea, thanks!

      The easiest bit first – concerning the current memoryoff switch – it already exists.
      You can specify, what I call “hints” (substrings separated by comma and space).
      The hinting mechanism works like this:

      1. Search for all hints in the current URL.
      2. If found, then skip this current URL.

      So you could already achieve what you want by specifying e.g.:

      memoryoff: "dyna" //turn memory off for dynamic pages - i.e. all URLs containing the substring "dyna"

      I could easily apply the same mechanism to prefetching, by changing the parameter from prefetch to prefetchoff and supporting a list of “hints”, as described above…

      (That breaks backward compatibility a bit but the future is more important than the past…)

      What do you think?

      Thanks again


      EDIT: I have quickly implemented the new logic for prefetchoff (only) in this file:

      https://4nf.org/ajaxify.js

      You should now be able to do something like this:

      • prefetchoff: "login"

      …feel free to test…

      1. Hi,

        thanks for the fast response, I knew about this memory filter option, but didn’t understood before that I can use only one specific substring from URL to filter it out. That’s awesome if it’s implemented for prefetch too. I’ll test it out soon.

        My suggestion for class filter was primarily for users that doesn’t work with assets compiling, minifying, concatenating and versioning (gulp, webpack or something similar) so they have to empty browser cache on every change. They’ll find it easier to have things hardcoded inside javascript and modify only html templates, but it’s harder to implement.

        I also had thoughts for some feature like if option is off globally to be able to turn it on for certain links and vice versa, if it is on globally to turn it off by class filter. But this is even harder to implement.

        Everything is just fine right now, no need for overcomplicating, this plugin is “creme de la creme” of its kind.

        Best regards, Edin.

        1. Hi Edin,

          Thanks for those kind words – exactly what keeps an open-source author going 🙂
          Please excuse the delay, but I chose to implement and test the new functionality straight away.
          So I went forward and multiplied-out the “hints” mechanism for the prefetchoff and previewoff parameters.

          I also tested them in one pass against Öko-Fakt – our German partner site:

          For prefetchoff:

          • true: no prefetch performed
          • false: prefetch always performed
          • "produkt, studien": prefetch not performed on those pages (please note, that “produkt” addresses a whole family of pages)

          For previewoff:

          • true: no preview performed
          • false: preview always performed
          • "produkt, studien": preview not performed on those pages (please note, that “produkt” addresses a whole family of pages)

          I don’t fully understand your other suggestions, but you said yourself, they might be overcomplicated…

          Thanks very much once more and
          Best regards, Arvind.

          1. Hi Arvind,

            tested new prefetch features a bit. Filters are working great, but I noticed one flaw for prefetch hover option itself. After some code digging and options changing I realized that prefetch doesn’t work for new links loaded inside content div(s), like hoverIntent detection is not attached to them. In my case there are #dynNav, #dynData and #dynFoot dynamic containers (dynamic navigation is for “active” classes to highlight current page link and eventually to load new links while switching to admin section). So after first navigation link inside #dynNav gets clicked that container is populated with new (sometimes same) links and there is no hover reaction anymore.

            Tested it on 4nf.org also, navigation bar is static and links inside are prefetching always, but those inside dynamically loaded pages are not reacting.

            P.S. Sorry for posting this reply inside “More section”, my mistake.

            Best regards,
            Edin

          2. Hi again Edin,

            if you’ve got the time – could you test whether you can observe the same in the older version (7.3.9)?
            I can only start testing tomorrow morning unfortunately…

            Thanks and
            Best regards,
            Arvind

Leave a Reply to admin Cancel reply

Your email address will not be published. Required fields are marked *