There's also various optimizations on the git side like bitmaps[1] and commit-graphs[2]. If this a bare repo on the server side it shouldn't be a problem to make sure it is in a particular format with receive hooks.
That's just displaying a file listing though. Displaying what GitHub displays with the last change of each file is more complex, maybe the commit graph could be used so the client wouldn't have to fetch everything itself.
[1]: https://git-scm.com/docs/bitmap-format
[2]: https://git-scm.com/docs/commit-graphHowever I never got around to finishing it, mainly because I couldn't decide on where to stop: should I also generate commits from all non-master branches etc.
I flirted with the idea of a browser-side repo viewer too, but re-implementing git packfile parsing in js didn't seem like something I'd want to spend my time on, so I moved on. Glad to see others pondering the same thing though.
That said, JavaScript libgit2 is a thing [1], so doing it "properly" in a client app is totally possible.
[1]: https://github.com/libgit2/libgit2/issues/4376 | https://github.com/petersalomonsen/wasm-git
Hmmm, I might give it a go one day.
Of course, there’s also the argument that if you’re self-hosting a repo, you’re more likely to care about users that have disabled JS (which is a good idea, tbh).
For a repo with thousands of files, it might make sense to limit entry pages to only directories and .md files (and other prose files), which are more likely to be linked to. You can also skip shipping a Markdown renderer this way!