My first attempt was with an unordered list and a separate content area where the user is sent once he clicks on a tab. This can be seen very often with different tab implementations. I took some data from Wikipedia to populate the contents for a couple of tabs. But I noticed some imperfections. First, when the tabs are placed next to each other, they could easily exceed the length of the tab list area, which meant that they needed to flow to another line without breaking the layout or be hidden with the help of some horizontal scrolling mechanism. Second, this version lacked keyboard support, which meant that only users with a mouse can use it. Third, hidden contents are still completely loaded which isn't always good with heavy websites. Lazy loading can prevent this, but it probably has its own implementation cost. At the same time, if the tab content is loaded on-demand every time, the site may be perceived to be a bit slower. I decided that to keep everything as simple as possible.
My second attempt was slightly different. It uses a definition list, because I think that it better describes the relationship between a tab and its content. The terms resemble the tabs and the descriptions the contents for each individual tab. The list is a single element, which makes it easier to use it as a component in other contexts. I have slightly changed the initial script. One difference is that I have chosen to load the tab contents only in the last <dd> element, as this fixes the floating behavior of the tabs, who would be otherwise torn apart because of the alternations between the terms and descriptions. A better way would have been to achieve this with CSS only.
Ideally, a component would be included on a page as many times as possible without impacting its performance. In practice, this is rarely achievable, but we still need to strive for it. The more efficient a single, small component is, the more efficient the site as a whole. In other words, performance is affected by the smallest of details. We can easily take the markup for a single component and multiply it with the help of our server-side language of choice (e.g. PHP). Here are some measurements I did on my local machine:
As we can see, using 10 tab areas with 5 tabs each (for a total of 50 tabs) weights 10kB without any content inside of these tabs. Even 100 tab areas have a weight of 34.4kB, which is an average of 344bytes per tab area! As the number of tab areas grows, the full load time grows exponentially and this is mostly because of the DOM.
We need to consider that each tab content area will contain many other DOM elements, and then the number of tab areas we can show will shrink accordingly. It's still possible to have 50 thousand empty tabs on a page, but we'll need to wait 40.49s seconds. This is not ok when on the web every millisecond counts.
Tabs, although widely spread, aren't the solution to everything and should not be overused. But they can complement different means of presenting site content. We can see their usefulness when we consider how the average content size has grown in recent years. When tabs respond fast, they can hide more content than what the user is able to perceive at once. The screen space is always limited and tabs can multiply its efficiency. But they create a possible usability problem, because every time a user wants to see more, he needs to point and click. Human operations are much slower compared to those of a machine, so at the end a user that has to click too often to reach smaller and smaller pieces of content (in a tiled screen of tab lists) will perceive the site as being slow.
You probably know of much better ways to implement tabs, sliders and other UI components. I'll be glad to hear your opinion.