Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea: only make request if element is visible #34

Open
elsurudo opened this issue Oct 24, 2017 · 8 comments
Open

Idea: only make request if element is visible #34

elsurudo opened this issue Oct 24, 2017 · 8 comments

Comments

@elsurudo
Copy link
Contributor

elsurudo commented Oct 24, 2017

Use case:

Utilizing responsive principles, different elements of my page are hidden/shown depending on the screen size. As render_async works now, my page fetches all the elements at page load time, even the ones that are currently not being shown (perhaps they are only shown on small screens, for example). Obviously this is not ideal for performance reasons.

At least for the jQuery case, we could use the elem.is(':visible') pseudo-selector (as per https://stackoverflow.com/questions/178325/how-do-i-check-if-an-element-is-hidden-in-jquery) to determine whether the element is visible, and only fetch the async partial if it is (not sure about the non-jQuery case).

What if the user loads the page full-screen, and then shrinks the window? Perhaps there is a way to handle this case as well, but I haven't done the research.

Just putting this here as a feeler for now. What do you think?

@elsurudo elsurudo changed the title Idea: only make request is element is visible Idea: only make request if element is visible Oct 24, 2017
@nikolalsvk
Copy link
Collaborator

Sounds like a great idea. We could add some lazy_load flag to render_async which will do a request only when it's visible.

I love the idea, if you want to submit a PR I'd be more than glad to help out :)

@elsurudo
Copy link
Contributor Author

elsurudo commented Nov 20, 2017

When things calm down a bit, I might give this one a try. Good to get some validation that it would be useful for others as well.

@nightsurge
Copy link

Maybe using this library? Might be pretty quick and painless, but is a dependency so perhaps a conditional gem install or something to signify they only add this dependency if they wish to do these types of "is visible" render_async calls?

https://github.com/creativelive/appear

@vanboom
Copy link

vanboom commented Aug 19, 2021

Suggestion - because we have the "refresh" event which can refresh the partial, a simple flag to inhibit the initial load of the partial would allow the developer more flexibility.

Eg.

= render_async user_comments_path(user), container_id: "user_comments", replace_container: false, lazy: true

would set up the plumbing, then later the user could fire the refresh event to load/refresh the container...

$("#user_comments").trigger("refresh"); 

@nikolalsvk
Copy link
Collaborator

nikolalsvk commented Aug 24, 2021

We can do this even with the toggle functionality

Basically, you should be able to do the following:

<%= render_async user_comments_path(user), 
                 container_id: "user_comments", 
                 toggle: { selector: "#user_comments", event: "load-me" } %>

And, then you can do:

const callbackToCallOnElementVisible = () => { // I got it to work by passing this callback to the IntersectionObserver
  $("#user_comments").trigger("load-me");
}

WDYT about this, @vanboom?

@vanboom
Copy link

vanboom commented Aug 26, 2021

Yes - this makes sense. I might be misunderstanding the toggle feature. If we do not specify interval the toggle event would not cause it to poll? (In many cases we want to delay loading, but cause the partial to refresh based upon the user clicking a refresh button or some other ajax event.)

@nikolalsvk
Copy link
Collaborator

If we do not specify interval the toggle event would not cause it to poll?

Yes, the toggle feature can be used without polling. I tried what I suggested above and it works. It might be worth to add it to the docs as an example.

@vanboom
Copy link

vanboom commented Nov 28, 2021

Yes, this works great. I was able to use the jquery.appear plugin to detect the appearance of the element, then trigger the render-async toggle event...

  $("#user_comments").appear({container: "body"});
  $("#user_comments").on("appear", function(event, $all_appeared_elements){ $("#user_comments").trigger("load-me"); });

I actually put this code into a global function called render_async_on_appear(selector) to make it easy to call from anywhere in the app. Thanks for the tips on how to use the trigger functionality to achieve this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants