Earlier quoted context omitted.
Why write the transaction ids in the tuples at all? In most production cases, transactions in flight are going to affect a small amount of rows overall, so you can just keep the data in memory, and store it to disk in a separate table if it gets large.
You need to access that data from different connections, so it needs to be correctly locked etc. Looking purely at the tuple you need to know where to look for the tuple visibility information. Accessing data stored in some datastructure off to the side will also have drastically worse cache locality then just storing it alongside with the data. E.g. for a sequential scan these checks need to be done for every tuple,…
It's only a tiny fraction of tuples which are recently committed and visibility rules come into play. That can be a special-cased slow-path