One of the goals of fabric is to be fast. That means designing features with speed in mind.
Some of the things that make fabric fast are:
2 absolutely-positioned overlaying canvases. One for group selection (top canvas), another one for object rendering (bottom canvas). This keeps group selection fast no matter how many objects are currently rendered on canvas.
Using prototypal inheritance to implement object hierarchy in order to stay memory efficient, since we can be dealing with hundreds of thousands of "instances".
Keeping underlying code simple and using as little abstraction as possible (e.g. avoiding array extras in frequently-executed paths).
Static canvases for cases when interactivity is not needed (lighter version which consumes less memory and is more efficient overall).