swup / preload-plugin

A swup plugin for preloading pages to speed up navigation 🚀

Home Page:https://swup.js.org/plugins/preload-plugin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Detect network idle time for preloading?

riddla opened this issue · comments

First of, thanks for swup in general. We integrated it some days ago in one of our sites and it works like a charm.

I had the idea of using requestIdleCallback for preloading other pages. What do you think? I would be happy to try it out in a fork and make a PR, if you are interested.

Hi @riddla, sorry for the late reply, totally missed this issue.
Thanks and I'm glad it works for you guys.

Your idea sounds great! quicklink by google could actually be a great source of inspiration here. I would probably make it possible to disable this behavior and current on hover preload by two separate options that would by default be both enabled.

To sum it up, if you're still up for it, please create a PR.

PS: If you'd like to share a link for your site with others as an example, I would be happy to include it in swup docs.

Thanks for your insights. Do you mean an option to disable the [data-swup-preload] alltogehter or just an option to disable the requestidlecallback version of it?

const defaultOptions = {
    useRequestIdleCallback: true,
    useOnMouseOverPreload: true
};

// ... or ...

const defaultOptions = {
    useDataAttributePreload: true,
    useOnMouseOverPreload: true
};

Hi @riddla, damn I did it again... sorry man! I just started following you here on GH so I won't miss any of your great input anymore. 🙂

Well that really depends, in case preload plugin will have more opt-in options, each should probably have a way to disable that option.

However, since data attributes are already opt-in by design (as you need to add the attribute to specific links), I think the option is unnecessary there. Now that I think about it, the same kind of goes for the mouse over, because if you don't want to preload on hover, you simply don't include the preload plugin. In case useRequestIdleCallback would be enabled, any link that you would be able to hover would already be loaded. This plugin already checks whether the page is already loaded and won't load it again, so no issue there.

TL/DR
I think it's enough to just limit the usage with only one option - useRequestIdleCallback.

Just a note, we only need to load pages that are "loadable" by swup, so we should probably use the swup.options.linkSelector in the plugins requestIdleCallback handler.

I finally found some time for the PR, see #5. The requestIdleCallback fork was running some weeks within a staged project of ours and doing fine in all major browsers.

Sorry @riddla for this astronomical waiting time 😅 TIL that requestIdleCallback actually serves to detect user inactivity, not network inactivity. Did you also have the misconception that it would actually detect network idle time? I'll leave this open for a few more days, in case you are still interested in a conversation.

While requestIdleCallback only makes a statement about the browser's internal activity, there's two options that I know of to approach network inactivity:

  • Intercepting requests in a service worker to know when nothing is being requested. There's an npm package network-idle-callback that does most of the heavy lifting.
  • Use the somewhat newer PerformanceObserver to intersect fetch events. See this StackOverflow example.

Not sure if that's overkill.

Thanks for the pointer to PerformanceObserver! Actually, this seems like the tool of choice for this kind of task.

Just implementing this for all swup.preloadPage() calls wouldn't be sufficient, consumers might still want to control when a page preload request should be eager vs. lazy – so we would need some kind of modifier for the [data-swup-preload] attribute. Something like [data-swup-preload=lazy] comes to mind.

Not sure if that's overkill.

I agree. Closing this for now.