最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

vue.js - laravelvue design: different ways to handle a loader on a SPA while laravel is processing a job - Stack Overflow

programmeradmin5浏览0评论

It is a design question, and though I am a full stack dev, I am weaker on frontend UX stuff:

I am creating a laravel application with Inertia and Vue, where each user has portfolios. Portfolios rely on calculations which are usually done overnight. When a user makes changes that need to be recalculated to show the correct portfolio, I want to display a button that allows them to trigger a job that recalculates whenever the user requires it. While the recalculation job is running, I want to display a loaded icon beside the portfolio indicating that recalculation is being processed, followed by a check icon when it's done. Recalculation can last 1-2 minutes.

As we have different components working together I am not sure which would be the best way to solve that: What is clear is the button, which makes an axios call to the backend to a controller which triggers a Job for recalculation, and on the corresponding table a mark that the portfolio is being processed and when it's finished.

But what about the front end? How do I inform different frontend components about that? Should I store a pinia state, and how would I update it once the job is processed? I know I can create watchers or reactive params on different components but what is usually the best design or an easy way to have frontend components monitor some backend activities? recurrent axios calls every x seconds?

It is a design question, and though I am a full stack dev, I am weaker on frontend UX stuff:

I am creating a laravel application with Inertia and Vue, where each user has portfolios. Portfolios rely on calculations which are usually done overnight. When a user makes changes that need to be recalculated to show the correct portfolio, I want to display a button that allows them to trigger a job that recalculates whenever the user requires it. While the recalculation job is running, I want to display a loaded icon beside the portfolio indicating that recalculation is being processed, followed by a check icon when it's done. Recalculation can last 1-2 minutes.

As we have different components working together I am not sure which would be the best way to solve that: What is clear is the button, which makes an axios call to the backend to a controller which triggers a Job for recalculation, and on the corresponding table a mark that the portfolio is being processed and when it's finished.

But what about the front end? How do I inform different frontend components about that? Should I store a pinia state, and how would I update it once the job is processed? I know I can create watchers or reactive params on different components but what is usually the best design or an easy way to have frontend components monitor some backend activities? recurrent axios calls every x seconds?

Share Improve this question edited Jan 17 at 22:54 Canelo Digital asked Jan 17 at 15:28 Canelo DigitalCanelo Digital 3922 silver badges14 bronze badges 3
  • Could have a service worker, Websocket, Server Sent Event, long polling, a vue-router guard, you could also offset the time of regeneration during midnight, let the thing build, and swap it with the old version until built etc etc etc... Overall, plenty of solutions are available hence this kind of question is opinionated and not allowed here. – kissu Commented Jan 17 at 20:45
  • Thank you. As mentioned I have a nightly job for that, but I want to have an additional triggered option. I do not see architectural question as opinionated, as I am asking for alternative solutions I actually don't know yet. (the question is not which is the best, but which alternatives exist) – Canelo Digital Commented Jan 17 at 22:45
  • @CaneloDigital Websockets are the way to go indeed, and long polling (aka recurrent calls every x seconds) is the last resort if you can't afford ws or it isn't worth it. After you received data from server side you can use pinia or generic global state vuejs./guide/scaling-up/state-management to store data on client side and make ui react to it – Estus Flask Commented Jan 18 at 0:15
Add a comment  | 

3 Answers 3

Reset to default 1

I'm not sure that using Pinia is appropriate with Inertia, it's a server-side rendered front-end, and although there are packages that allow state persistence after a server-to-client reload via localStorage (https://github/prazdevs/pinia-plugin-persistedstate), it may not be necessary.

And since a server-side call is made with page changes, it's possible to use the middleware proposed in the documentation (https://inertiajs/shared-data).

Ideally, you'd like to use a socket to do this, but it all depends on your need and cost.

Maybe we can simply put the process on hold and process an email or notification as soon as it finishes.

It's tough to pick the best design, but I think using WebSockets could work well here. You can check out Laravel Reverb and Laravel Echo for that. If you look at the official Laravel docs, there's an example that’s pretty similar to what you're working on.

For example, imagine your application is able to export a user's data to a CSV file and email it to them. However, creating this CSV file takes several minutes so you choose to create and mail the CSV within a queued job. When the CSV has been created and mailed to the user, we can use event broadcasting to dispatch an App\Events\UserDataExported event that is received by our application's JavaScript. Once the event is received, we can display a message to the user that their CSV has been emailed to them without them ever needing to refresh the page.

In the question you mention

recurrent axios calls every x seconds?

I think you’re talking about polling, which could help with your issue, but it comes with its challenges. If you decide to go for polling, you can check out the Inetra documentation; there’s a section that covers polling in detail.

WebSockets and polling both have challenges. WebSockets offer real-time updates, which is great, but they can make things a bit complicated on the server side and use up more resources, making it tough to scale for big apps. Polling is easier to set up, but it can be pretty inefficient since it constantly pings the server, leading to more latency and extra load on the server.

Resources -

https://laravel/docs/11.x/broadcasting

Just if anyone stumbles upon a similar issue: I accepted Alexis Gatuingt as best answer, even though skdishansachin gave very helpful info concerning broadcasting.

After reading through requirements and counterweighting different arguments this was my evaluation:

  • polling: Send a request every 30 or 60 seconds to update the state could be acceptable, but in general terms it produces pretty much network overload. As more of such services are needed it's not very viable and anyway a brute solution. So I better not start with that.
  • Inertia Middleware seems a good way inbetween: With every page change some params can be added to the page, and in my actual usecase, page changes or updates are quite possible. Now an OBS: In a SPA (Single Page Apps) and Vue, Inertia middleware is not called until a window reload is triggered, so the param has to be also included additionally on any vue-router change (router.afterEach on global level). inertia middleware by itself would not be enough clean.
  • Broadcasting and Laravel Reverb is without a doubt the architectural cleanest option, nevertheless it has a cost in server management, as every client connected via broadcast opens up a websocket, which in bigger apps needs more personnel, knowledge and eventually more server resources. So it may be quite quick costly and and overkill for example for a MVP (Minimum viable product) or for apps with not too many users or if the usecase allows page-changes between (longer calculations)

So in my specific usecase, long-polling is ugly and I want to avoid network overhead specially if userbase grows. Broadcasting and reverb would force to open up a pandoras box with server config, eventually requiring more server resources, etc. and on long term force much faster to have specialist in that field configuring the server when the userbase grows quickly and probably enforce to upgrade server resources (hosting cost).

So with that in mind, and on that specific use case (long running calculation process which is triggered consciusly by user which probably makes page changes while it updates, low payload, few of these UX cases) Inertia middleware and Vue-router guard will my momentary way to go, nevertheless in mind, that it's not 100% clean from architectural perspective, and if more similar UX cases are required, websockets and broadcasting would become more senseful (less calculation time between page changes, clean UX updates which do not require page changes, clean channel for all such UX updates which can be handled more centrally and do not charge the payload between any request). So as long as these status updates, messages alerts do not raise page load times too high, it will be my way to go, until websockets and broadcasting become necessary.

发布评论

评论列表(0)

  1. 暂无评论