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

Feat: improve views #484

Merged
merged 12 commits into from
Sep 8, 2024
Merged

Feat: improve views #484

merged 12 commits into from
Sep 8, 2024

Conversation

MrPunyapal
Copy link
Collaborator

@MrPunyapal MrPunyapal commented Aug 4, 2024

Current Scenario and Problem

On page render, if there are 10 posts, we dispatch a job for those 10 posts. When the user scrolls, another 10 posts are loaded, resulting in a total of 20 posts (including the previously loaded 10). A job is dispatched for all 20 posts, even though 10 were already viewed. This continues until the maximum number of posts allowed is reached. For example, if we allow 100 posts, a job is dispatched for 100 posts on the last scroll event, even though most of them (around 90) were already viewed.

If the user refreshes the page, the same process repeats, dispatching jobs for posts that were already viewed.
I also noticed that on the show page if we view a comment or parent post it does not increase the view count.

How This PR Solves It

No jobs are dispatched on rendering or scroll events. Instead, when a post enters the user's viewport, it triggers an event to the ViewManager, indicating that the post has been viewed.

Whenever a user sees a post on every scroll, the ViewManager collects the post IDs on the client side. These IDs are sent to the server once 10 posts (configurable) are collected. Additionally, it caches the already viewed posts on the client side with a timestamp. Before sending post IDs to the server, it filters out any posts that were viewed within the last 2 hours (also configurable).

Thus, if the user refreshes the page and views all posts again within 2 hours, no jobs are dispatched. As it is now managed by the ViewManager on the client side it will also solve the issue of comment and parent post views on the show/details page.

I have also handled the Livewire navigate event, ensuring that if the user navigates away, the viewed post IDs are sent to the server if they haven't been recently viewed.

The solution also covers scenarios like closing the window or changing history (e.g., clicking the back button or altering history with JavaScript).

It also checks for the visibility change event so if the user switches the tab or minimizes the window, we will send all IDs to the server collected by ViewManager.

This approach can significantly reduce the load on the server. If we measure the jobs in the queue, we anticipate a reduction of more than 70-80% in the number of jobs.

resources/js/view-manager.js Outdated Show resolved Hide resolved
resources/js/view-manager.js Outdated Show resolved Hide resolved
@MrPunyapal MrPunyapal changed the title [WIP] Feat: improve views Feat: improve views Aug 5, 2024
@MrPunyapal MrPunyapal requested a review from CamKem August 7, 2024 03:19
@MrPunyapal MrPunyapal changed the title Feat: improve views [wip] Feat: improve views Aug 7, 2024
Copy link
Collaborator

@CamKem CamKem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, I confirmed the issue by adding a log in the constructor.

    public function __construct(private Collection $viewables, private int|string $id)
    {
        logger('posts being viewed', ['viewables' => $viewables->pluck('id')->toArray()]);
        //
    }

The log shows there is duplication of the id's to be incremented. We have accounted for this with our caching & checking the ids before incrementing in our current solution.

@MrPunyapal Solution of handling it on the client is better, will mean less load on the server as the site grows & doesn't require any change the IncrementViews job to work.

@MrPunyapal MrPunyapal changed the title [wip] Feat: improve views Feat: improve views Aug 7, 2024
@MrPunyapal MrPunyapal force-pushed the feat/improve-views branch 2 times, most recently from a2742ab to 845ac48 Compare September 7, 2024 11:47
resources/js/view-manager.js Outdated Show resolved Hide resolved
resources/js/view-manager.js Outdated Show resolved Hide resolved
};
});
viewedPosts = [...previousViewedPosts, ...viewedPosts];
localStorage.setItem('viewedPosts', JSON.stringify(viewedPosts));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens when local storage if full?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will only store newly viewed questions and for other questions server will handle them. so mostly if this kind of thing happens then newly viewed can be sent twice to the server.

btw it will always have posts less viewed within two hours as for every server call we remove older posts.

app/Livewire/ViewsManager.php Outdated Show resolved Hide resolved
app/Livewire/ViewsManager.php Outdated Show resolved Hide resolved
app/Livewire/ViewsManager.php Outdated Show resolved Hide resolved
resources/js/app.js Outdated Show resolved Hide resolved
resources/js/view-manager.js Outdated Show resolved Hide resolved
resources/js/view-manager.js Outdated Show resolved Hide resolved
resources/js/view-manager.js Outdated Show resolved Hide resolved
@nunomaduro nunomaduro merged commit c2e7075 into main Sep 8, 2024
@nunomaduro nunomaduro deleted the feat/improve-views branch September 8, 2024 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature: adjust the feeds limit based on how many questions / answer the user can see
5 participants