Tuesday 3 September 2013

Performance & Organization - Part 1

Having the ability to write HTML and CSS with a solid understanding is a great expertise to have. As a website’s code base and traffic grows, a new skill set comes into play, one that is extremely important to both development time and user experience. Knowing the fundamentals of website performance and organization can go a long way.
The organization and architecture of a code base can greatly affect not only the speed of development, but also the speed at which pages render. Both of which can be sizeable concerns not only for developers but also users. Taking the time to design the right structure for a code base, and identify how all of the different components will work together, can speed up production and make for a better experience all around.
Additionally, taking a few small steps to improve the performance of a website can pay off in dividends. Website performance greatly resembles the 80/20 rule, where 20% of the optimizations will speed up roughly 80% of the website.

Strategy & Structure

The first part to improving a website’s performance and organization revolves around identifying a good strategy and structure for developing the code base. Specifically, building a strong directory architecture, outlining design patterns, and finding ways to reuse common code.

Style Architecture

Exactly how to organize styles boils down to personal preference and what is best for a given website but generally speaking there are best practices to follow. One practice includes separating styles based on intent, which includes creating directories for common base styles, user interface components, and business logic modules.
  1. # Base
  2. normalize.css
  3. layout.css
  4. typography.css
  5. # Components
  6. alerts.css
  7. buttons.css
  8. forms.css
  9. list.css
  10. nav.css
  11. tables.css
  12. # Modules
  13. aside.css
  14. footer.css
  15. header.css
The architecture outlined above includes three directories, all with individual groups of styles. The goal here is to start thinking of websites as systems rather than individual pages, and the code architecture should reflect this mindset. Notice how there aren’t any page specific styles here.
The base directory includes common styles and variables to be used across the entire website, layout and typography styles for example. The components directory includes styles for specific user interface elements which are broken down into different component files such as alerts and buttons. Lastly, the modules directory includes styles for different sections of a page, which are determined by business needs.
The component styles are purely interface driven and have nothing to do with the core business logic of the website. Modules then include styles specific to the business logic. When marking up a module in HTML it is common to use different user interface components within it. For example, the sidebar of a page may have list and button styles that are defined within component styles while other styles needed for the sidebar are inherited from the module style. The separation of style encourages well thought out presets and the ability for styles to be widely shared and reused.
The strategy of organizing styles this way isn’t exactly new, and has been previously mentioned in different CSS methodologies including Object Oriented CSS, OOCSS, and the Scalable and Modular Architecture for CSS, SMACSS. These methodologies have their own opinions on structure, as well as on how to use styles.

Object Oriented CSS

The Object Oriented CSS methodology was pioneered by Nicole Sullivan in her work with writing styles for larger websites. Object Oriented CSS identifies two principles that will help build scalable websites with a strong architecture and a reasonable amount of code. These two principles include:
  • Separate structure from skin
  • Separate content from container
Overall separating structure from skin includes abstracting the layout of an element away from the theme of a website. The structure of a module should be transparent, allowing other styles to be inherited and displayed without conflict. Most commonly this requires a solid grid and layout structure, along with well crafted modules.
Separating content from the container involves removing the dependency of a parent element nesting children elements. A heading should look the same regardless of its parent container. To accomplish this, elements need to inherent default styles, then be extended with multiple classes as necessary.
HTML
  1. <div class="alert alert-error">
  2. <p class="msg">...</p>
  3. </div>
CSS
  1. .alert {...}
  2. .alert-error {...}
  3. .msg {...}
Object Oriented CSS advocates building a component library, staying flexible, and utilizing a grid. These are good ground rules, and they can help you avoid the need to add additional styles every time you add a new page or feature to a website.

Scalable & Modular Architecture for CSS

Along the same line of Object Oriented CSS is the Scalable and Modular Architecture for CSS methodology developed by Jonathan Snook. The Scalable and Modular Architecture for CSS promotes breaking up styles into five core categories, including:
  • Base
  • Layout
  • Module
  • State
  • Theme
The base category includes core element styles, covering the general defaults. The layout category then identifies the sizing and grid styles of different elements, determining their layout. Module styles are more specific styles targeting individual parts of the page, such as navigation or feature styles. The state styles are then used to augment or override other styles in the event that a module includes an alternate state, an active tab for example. Lastly, the theme category may be added which could include styles based around the skin, or look and feel, of different modules.
HTML
  1. SCALABLE & MODULAR CSS<div class="alert is-error">
  2. <p>...</p>
  3. </div>
CSS
  1. SCALABLE & MODULAR CSS.alert {...}
  2. .alert.is-error {...}
  3. .alert p {...}
  4. .alert.is-error p {...}
In the example above the alert class falls into the module category while the is-error class falls into the state category. Styles from each of these categories are then inherited as necessary.

Choosing a Methodology

Choosing which methodology to use, if any, is completely up to you and what you feel is best for a given website. Generally speaking, a solid mix of both OOCSS and SMACSS works well, borrowing principles from each methodology as you prefer.

Performance Driven Selectors

One functionality of CSS often abused without awareness are selectors. Much of the attention within CSS is given to properties and values. So long as these styles are applied to the correct element, everything looks to be fine. This is a very poor assumption. How elements are selected within CSS affects performance, including how fast a page renders as well as how practical and modular the styles are in the overall site architecture.

Keep Selectors Short

There are a handful of benefits to keeping CSS selectors as short as possible. These include minimizing specificity, allowing for better inheritance and portability, and improving efficiency. Long, over qualified selectors reduce performance because they force the browser to render each individual selector type from right to left. They also put a burden on all other selectors to be more specific.
  1. <!-- Bad -->
  2. header nav ul li a {...}
  3. <!-- Good -->
  4. .primary-link {...}
  5. <!-- Bad -->
  6. button strong span {...}
  7. button strong span .callout {...}
  8. <!-- Good -->
  9. button span {...}
  10. button .callout {...}
In the code above, the first selector is extremely specific and could be identified, and rendered, much quicker with the use of a class. Additionally, using a class in this case greatly reduces the need to identify an element’s parent, allowing that elements location to change over time without breaking any styles.
The second example includes selectors shorter than the first example but it can be improved by providing the same level of specificity to each selector. Avoid using overly specific selectors, in return they are less likely to break should the order of elements change. Cutting out some of the individual selector units, and giving all of the selectors the same strength, allows them to better cooperate.
The overall goal with short selectors is to decrease specificity, creating cleaner, more charitable code.

Favor Classes

Classes are great, they render quickly, allow for styles to be reused, and are already commonly used in building a website. When using classes though, there are common practices to observe in order to see that they are leveraged properly.
Since selectors are rendered from right to left it is important to keep an eye on the key selector. The key selector is the selector unit at the end, furthest to the right. The key selector is crucial as it identifies the first element a browser is going to find. Having a poor key selector can send the browser on a wild goose hunt. Don’t be afraid to use a class to be more unique simply for the benefit of performance.
Additionally, do not prefix class selectors with an element. Doing so prohibits those styles from easily being applied to a different element and increases the overall specificity of the selector.
  1. <!-- Bad -->
  2. #container header nav {...}
  3. <!-- Good -->
  4. .primary-nav {...}
  5. <!-- Bad -->
  6. article.feat-post {...}
  7. <!-- Good -->
  8. .feat-post {...}
It is also worth noting, stay away from ID selectors where possible as they are overly specific and do not allow for any repetition. At the end of the day using an ID isn’t a whole lot different than using !important.