Contract logs are queried by address, topics and block range. Providers cap the range, so page through it, and handle reorgs by re-reading recent blocks.
const logs = await c.queryFilter(c.filters.Staked(user), fromBlock, toBlock);
For anything beyond a few thousand blocks, index into your own store rather than querying the chain on every page load.