Revamping Figma Components for Enhanced Efficiency and Usability
Written on
Oxygen, the design system developed by Doctolib, has evolved significantly over the past three years, growing increasingly sophisticated. This period has involved the introduction of new components, processes, and updates, alongside adjustments resulting from Figma's advancements, such as auto-layout and other features. Unfortunately, these changes led to a Figma library that resembled a disjointed collection more than the streamlined system we aspired to create.
Simultaneously, we received consistent feedback from our Product Designers indicating that Figma files were cumbersome and slow, creating a frustrating work environment. This is particularly critical as Product Designers spend a considerable portion of their day working in Figma.
Through our analysis, we discovered several issues within the Design System:
- Numerous component properties were either unused or intentionally bypassed by designers, with some feedback indicating that components were overly complicated.
- There was a lack of a standardized nomenclature for properties, resulting in inconsistent naming conventions across different components.
- We also encountered "ghost components," which are instances lacking associated source components.
Recognizing the need for a major overhaul, we embarked on developing version two of our Design System.
The Unpleasant Reality
To tackle the pressing issue of file weight, we began using the Layer Counter plugin, which allowed us to evaluate the heaviness of our components and track our improvements.
What we uncovered was alarming: our components weren't just heavy; they were enormous! The sheer size was shocking.
For instance, consider the Pill component, which boasts numerous variants, various color themes, and includes nested components from our Design System (like Icon buttons, Avatars, Icons, Spinner Loaders, Badges) along with multiple size options.
The Pill component utilized a staggering 8,684 layers. Note: The Layer Counter results may vary slightly based on whether a source component or an instance is selected.
This raised a critical question: How do we create lightweight, resource-efficient components while maximizing functionality without compromising quality?
After brainstorming and conducting research, we concentrated on three key strategies:
Eliminate Unnecessary Nested Components
In the Pill component and similar instances, we found that semantic icons should remain unchanged. Therefore, we replaced the nested Icon component with SVG icons from our icon library. This adjustment helped us to:
- Remove unnecessary flexibility for Product Designers that didn’t exist in the development component, thereby reducing misunderstandings during handoffs.
- Significantly decrease the number of layers.
- Hide irrelevant properties on the sidebar, streamlining the properties panel.
Streamline Component Structure
Simultaneously, we had a library named Helper Components, which contained frequently used elements not considered part of the Design System. This included UI Kits (mobile OS keyboards, notifications), mouse cursors, and tools for file management (handoff cards, project covers, etc.). The Pill component previously relied on a Helper component for padding management using boolean properties, namely the Grid Spacer. We replaced Grid Spacers with a more intelligent structure utilizing auto-layouts.
For components that might have an undefined number of values, such as Dropdowns or Menus, we previously offered a default of ten rows or items. This meant that if a designer only required two, the remaining eight would become hidden layers, unnecessarily adding weight. To address this, we developed Helper components called Swappers, allowing Product Designers to choose the number of required rows or items using vertical or horizontal auto-layouts.
Deconstruct Components
Previously, the Alert component combined three families of variants:
- Banner (full width)
- Card (card style)
- Hint alert (low emphasis)
Initially, we believed it was simpler to import one component and adjust properties as needed. However, this resulted in numerous unnecessary layers for every instance, contributing to file weight.
This example illustrates a standalone component, but consider a Table cell utilized multiple times within a Table that appears in numerous layouts; the file size can quickly become unmanageable.
In summary, we drastically reduced the weight of components while still providing the same functionality and eliminating excessive customization that was not feasible on the development side.
Overall, our library of 64 components previously contained over 130,000 layers; after the overhaul, this number dropped to 21,700, resulting in an impressive reduction of 83% in layers.
Since implementing these changes, we've received no further complaints from Product Designers, and files are now significantly faster.
Standardizing Properties
Over three years of developing a Design System involving multiple stakeholders with shifting processes on both the development and design sides has resulted in inconsistencies in properties and usage. Initially, the approach was more intuitive than structured, leading to a lack of standardized nomenclature.
For example: - Text properties could be: label, description, label, title. - Theme colors could be: UI style, Color, Label color.
We seized the opportunity during the re-crafting process to establish a glossary of properties aligned with coding terminology.
Key highlights include: - Text properties are consistently marked with a emoji. - Boolean properties or variants are labeled as they are in the code, such as has Left asset, has Title, is Closable, is Disabled. - Standardized variant terms include straightforward labels like position, size, state, style, and type.
We also strive to maintain the same order of properties across all components.
In Figma, aligning components ensures that when swapping one for another, the overrides remain intact. For us, as maintainers of the design system, this simplifies the process of selecting property names and types.
Making Components User-Friendly
Previously, all nested components were official components (e.g., a List Item used the official Avatar). In the recent rework, we shifted to using only private nested components with a dedicated nomenclature. This approach allows us to: - Display only the properties that are actively in use, eliminating edge cases. - Validate which properties should be exposed for each component, reducing clutter in the properties panel. - Simplify boards by removing unnecessary framing around source components, preventing extra clicks when importing.
This not only enhances the daily workflow for users of the Design System but also allows for a more rational impact. For example, an evolution of the Dropdown may not necessarily require changes to the Combobox that utilizes it, reducing the burden on Designers from endless updates.
Addressing Ghost Components
The final, and perhaps most challenging, step was launching the new library. We identified two primary risks: - Removing the older library could create ghost components—instances without source components, typically indicating that the original source has been deleted. - Significant breaking changes might arise, meaning if a designer swapped a version 1 component for a version 2, all overrides would be reset due to structural changes.
To mitigate these issues, we chose to: - Retain access to the version 1 library but remove import capabilities, labeling them with [V1 DO NOT USE]. This way, designers can still identify and utilize version 1 components without the ability to import them. - Launch the version 2 library with components maintaining the same nomenclature.
One month post-release, the usage of version 1 components has declined notably, with plans to permanently remove them in the near future.
Component Versioning and Branching
We also decided to implement a branching feature for any component updates, establishing versioning using the format vX.Y.Z: - X [Major] denotes a version involving major updates affecting the entire component structure, resulting in breaking changes and loss of overrides. - Y [Minor] signifies improvements or minor bug fixes that will not impact existing instance overrides. - Z [Patch] refers to updates with no effect on designers’ files.
Conclusion
Overall, we estimated that addressing these issues required three months of full-time work, representing a significant investment. However, considering the time Product Designers spend in Figma, the financial savings from improved load times could be substantial!
Moving forward, we will: - Continuously assess the impact of our component design using the Layer Counter. - Validate the properties used to ensure alignment with our glossary. - Remain vigilant about new features or updates on components, avoiding the pitfalls of ghost components or introducing breaking changes.
Our next steps involve applying these improvements to our Figma guidelines.
Special thanks to Michael Blancon Tardi for his invaluable contributions to making Oxygen a top-tier Design System embraced by our designers and developers. Additional appreciation goes to my UX writing teammates, Hannah Sheeran and Mike Winnington, for their proofreading efforts, and to Lyne Dang Recalt for the beautiful cover illustration.