Did I say I love a good experiment?
I created an empty void world and wrote a few functions to generate a bunch of blocks and entities (and reposition my player consistently each time) to roughly benchmark their effect on performance. I waited a few seconds after each command and then screencapped to get the average frame rate.
21x11x1 stone wall with 0 item frames →
1000+ fps https://i.imgur.com/170sWSw.jpg
21x11x1 stone wall with 241 item frames →
48 fps https://i.imgur.com/WsO30UT.jpg
21x21x31 block of
stone →
1000+ fps https://i.imgur.com/BYLituU.jpg
21x21x31 block of
furnace →
1000+ fps https://i.imgur.com/JjqR1U3.jpg
21x21x31 block of
glass pane →
550 fps https://i.imgur.com/PaRGND3.jpg
21x21x31 block of
oak fence →
410 fps https://i.imgur.com/dPP5w8F.jpg
21x21x31 block of
oak fence gate →
380 fps https://i.imgur.com/oVlfWYn.jpg
21x21x31 block of
hopper →
380 fps https://i.imgur.com/pvlINEt.jpg
21x21x31 block of
shulker box →
6 fps https://i.imgur.com/gHKHur4.jpg
21x21x31 block of
chest →
6 fps https://i.imgur.com/Jht0yTo.jpg
Those last two aren't typos.
I forgot to screencap barrels, but they behaved consistently like other full opaque blocks like stone with 1000+ FPS.
Keep in mind that other than the blocks you see, this world is literally
empty with no blocks, no entities, no mobs, the daylight and weather cycles stopped, and my player in spectator mode. As
nothing as you can get in Minecraft.
Why the differences? Full opaque blocks that are touching have their touching faces culled before rendering, and that means the only thing the game has to display is their most exterior surfaces. One giant cube of blocks just has its six sides no matter how many blocks are in it. If this same volume were spread out over a landscape with mountains and caves, that would be a totally different story since a much higher surface area of the blocks would be exposed and rendered. That's effectively what you see here with the glass panes and fences; they have many more faces that have to be rendered since they aren't culling all the interior faces.
The shulker box and chest
hypothetically should be no more complex to render than fences, but as that Reddit discussion mentions, blocks that animate are handled very differently from blocks that are static. Not sure how exactly that is, but the evidence speaks for itself. ¯\_(ツ)_/¯
I couldn't create as many item frames as I could the blocks like chests because they have to be placed individually even programmatically (I spammed out 241 commands for them in my function script)
and they have to align with a block (or else they'll pop off in a second), but you can see how the relatively tiny number of item frames crushes FPS compared to an order of magnitude more chests.