It is unnecessary to recalculate block headers regularly. Whenever a new block is announced, the block header’s hash must meet the difficulty requirement to be acceptable. The combination of committing to the preceding block’s hash and the new block’s hash meeting the difficulty requirement, translates to an inductive commitment to all prior blocks in the best chain, as well as a proof of work. After this cheap check, the block is also tested to adhere to all other consensus requirements.
When a new block arrives, it checks whether this block extends its best chain or it constitutes an alternative chaintip with more work. If so, the node extends its best chain, or reorganizes to the new best chain’s tip.
If instead a block is published, that "changes a predecessor of the best chain tip", this would produce a distinct block header from the original, and the new block would constitute an alternative chaintip at a lower height than the best chaintip. (And the attacker would have to spend the same amount of proof of work to make the changed block pass the difficulty requirement.) As the successor of the original block commits to the hash of the best chain, and all further successors each inductively commit to the original block by committing to a successor of the original block, the best chaintip would have more work than the alternative chaintip, unless the attacker builds more blocks on top of their alternative block to outpace the prior best chaintip.
Anyway, we only need to check each block once, and then simply keep the block header chain in memory and extend from there, and it is unnecessary to revalidate blocks later, because we already know that anything that is part of our best chain has been checked before and cannot be changed without changing the header’s hash.