How to rescue your Figma file from the depths of hell and live to tell the tale

This pain point almost needs no introduction. Hundreds, if not thousands of designers have faced the horror that is Figma’s memory usage warning banner:

image.png

Unfortunately people who are faced with a resource-strained file get the same flavor of dismissive, vague advice that gets doled out to folks who are struggling auto layout. The difference here is someone’s hard work is at risk of being lost. But it seems to rhyme:

“how do I reduce memory in my file!?”

“just get rid of your hidden layers”

sounds like,

“how do I learn auto layout!?”

“just practice.”

The person in need of help has likely already tried these things! But they’re not seeing results.

And I’ll be honest, before I took the time to really understand this problem, that less-than-helpful one-liner, “just get rid of your hidden layers”, was the best I could offer too! Figma’s own documentation doesn’t go any further either.

So what’s better than a “heard that before”, crumb-size piece of advice that you already tried?

Freaking INSTRUCTIONS.

But not just “step 1, select hidden layers ... step 2, delete them” I’m talking about strategic instructions. Instructions that were designed to get you results as fast as possible.

In this blog post we’re not only going to rescue your memory bloated file from the depths of hell, we’re going to do it in record time. 🏎️ This entire blog post is designed to take you through the highest impact actions first. What this will do is win you back file memory in big chunks at first, getting you back to safety as fast as possible. This means memory usage reduction should get easier with each Milestone you complete.

Okay! Are you ready to get your file back? 🔥 Let’s roll 😎

<h2 id="milestone-1">Milestone 1) Develop a plan of attack</h2>

If we want to knock this out fast it’s vital we tackle this problem strategically. We need to start wherever the highest concentration of memory usage is happening in your file.

Typically folks will use multiple pages to organize their work. To find out which page has the most information on it, keep reading. If you’re only using a single page in your file you can skip ahead and begin on step 4 of Phase 1 below.

<h3 id="m1-phase1">Phase 1) Find the highest concentration of layers.</h3>

  1. Use either quick search <span class="inline-code">command</span> + <span class="inline-code">/</span> or go to <span class="inline-code">File</span> > <span class="inline-code">View</span> > <span class="inline-code">Memory usage</span> to enable Memory Usage.
  2. This will open a new panel at the top of the left-side panel of the interface. Click the button labeled "Memory Usage."
  3. In the side panel that opens up over the canvas, make sure the toggle switch labeled "Show memory usage in layers panel." This not only adds percentages to individual layers, but also adds percentages to your Pages.

    ⚠️ Warning! Doing this may slow down your file. If you flip this switch and the file crashes, freezes, or otherwise becomes unusable, close down Figma. Re-open Figma and start these instructions again, but this time from Step 4.

    If you are successful with this step, continue on to Step 4 but skip steps 7 and 8.
  4. Open up a blank page in your favorite text editor. This will become your detective notes.
  5. Make a list of every page in your file. Refrain from visiting these pages as you go. Rendering the contents could cause a file crash! We're only concerned with the names for now.

    Important! If you were successful with step 3, also write down the percentage of memory each page is using.
  6. Copy and paste the hyperlink for each page beside the page name for safe keeping. You'll want these if the file crashes and prevents you from visiting all the pages in a single session. You may need to clear your cache if you’re having troubles opening a crashed file again. Note that clearing your cache is different if you use Figma's desktop app!
  7. Starting from whatever page you’re currently viewing, select everything that’s on the canvas by pressing <span class="inline-code">command</span> + <span class="inline-code">A</span>.
  8. Use Alex Wang’s free Layer counter plugin to get the total count of layers on that page. The types of layers can be interesting information, but it’s not required to add to your notes. The key thing to capture is the total layer count. Write this number down next to the page name.
  9. OPTIONAL (but immensely useful for the next milestone): Unfortunately the Layer Counter plugin and Figma's memory usage feature don't tell us if any of the layers we selected are hidden. But luckily there’s another free plugin out there by Alex Dyakov called Find hidden layers that only selects hidden layers on the page! Run the Find Hidden Layers plugin, and then with all the hidden layers selected, run Layer Counter. Now you have a count of only the hidden layers. Add this information to your detective notes, we’ll use it again in the next milestone.

At this point you could get really fancy with your detective notes and turn it into a spreadsheet, but it’s not necessary. We’re on a rescue mission after all! This detective work helps us understand where our time and energy is best spent first. We want to win back memory from the biggest, gnarliest parts first so we can get as far away from the danger-zone and back to safety as fast as possible.

Take a look at your notes. Whichever page has the most layers that allows you to navigate to it without crashing the file is where you should navigate to in Figma. This page is where the next milestone kicks off.

<h2 id="milestone-2">Milestone 2) Reduce as many layers as possible.</h2>

Okay, so your detective notes from Milestone 1 led you to the biggest page in your file. Let’s dive in.

<h3 id="m2-phase1">Phase 1) Remove draft material</h3>

You probably thought we were going to start with hidden layers. That’s fair. It’s the one-liner piece of advice folks throw out to those of us trying to revive a file that’s choking on its layers. But I want to be clear: there’s nothing special about hidden layers that make them use more memory than visible layers. If you duplicate a layer and hide it, they both should cost the same amount of memory.

The reason people suggest you start with hidden layers because visible layers are probably visible for a reason! You’re using them!

But what about all those old drafts and iterations? The inspiration you swiped from other files? The beautiful clutter! The stuff that shows you’ve spent time experimenting and trying things. This material usually floats around or beside actual mockups and prototyping screens.

If this stuff is present on the page you’re looking at in Figma, the only step here is to:

  1. Turn on the resource use panel so you can see how much impact removing this has on your file.
  2. Get any old draft or inspiration material out of your file. You can either delete it entirely, or cut and paste it into a new file.

If you don’t have draft material or removed some and are still not back to a safe amount of memory usage, don’t panic! There’s still work to be done here. Next we move on to hidden layers:

<h3 id="m2-phase2">Phase 2) Remove unnecessary hidden layers from regular frames</h3>

The first place to look is hidden layers is in non-instances, or “regular frames.” Now, in the last phase I had that whole preamble about hidden layers not being any more expensive than visible layers, but I do have a strong hunch that non-componentized hidden layers are the more expensive than componentized hidden layers. I’ve asked for someone to validate or correct this theory in the community forum, but until I get a reply, let’s assume I’m right (if I’m wrong that’s okay, it wouldn’t affect this guide).

This means the most valuable hidden layers to start with are the ones in regular, non-instance frames.

But the tricky thing with hidden layers is... they’re hidden! We have to find them before we can remove them. Here are the steps:

  1. Make sure the resource use panel is on so you can see your progress quantified in real time.
  2. Double check your notes to ensure you’re on the page in your file with the most hidden layers (we collected this information from step 6 in Phase 1 of Milestone 1).
  3. Zoom out so you can see every object on the page, and run the Find Hidden Layers plugin. Depending on how things are arranged on your page and how many hidden layers you have, you may want to take a screenshot so you have a “map” to reference. I suggest adding this screenshot to your detective notes rather than to your Figma file.
  4. To get a sense of which hidden layers to start evaluating, view the file in outline mode using the keyboard shortcut <span class="inline-code">command</span> + <span class="inline-code">Y</span>. This can help you find larger clusters of hidden layers. Look for lots of grey lines. When you find a cluster, zoom in on it.
  5. Investigate the cluster of hidden layers further by referencing the layers panel. If you determine these layers are not critical to keep in your designs, either delete them, or cut and paste them into a separate file for safe keeping.
  6. You’ll naturally come across hidden layers that you don’t want to remove. Leave comments on these ones explaining why you’re keeping them. This will help you know what you have already investigated and made a decision on so you don’t duplicate the effort again.

In cases where taking a screenshot in step 2 wasn’t appropriate, you should re-run the Find hidden layers plugin any time you need a reminder of where the hidden layers are.

⚠️ Important note! Repeat phase 1 and phase 2 of this milestone for every page of your file before proceeding to phase 3 below.

Phase 3) Remove all unnecessary hidden layers from main components in your local file.

Now we’ll be examining the hidden layers in your main components. Unless you’re the author and sole-consumer of any library components you’re using, it’s best to begin with local components that are under your jurisdiction: the ones ones you’ve created for yourself in your local file.

Here’s how to proceed:

  1. First identify all components that are using variants to create a show/hide property. Start with the ones where the most layers are being hidden (e.g. a big section in an organism-size component will buy you back more memory than a single icon in a button component). You can eyeball this, but remember you have the Layer Counter plugin at your disposal too.
  2. Delete the “false” value variants. After all are deleted, remove the variant boolean property you used to show/hide that chunk of layers.  
  3. On the remaining variants, set up a boolean component property to show/hide the appropriate layers. Component property’s boolean is always going to be mathematically more efficient than variants' boolean because they don’t require us to repeat the hidden layer’s parent layers.

    But Alice, what about all the instances of those variants I deleted? And the overrides I made on them?

    Don’t you worry, I’ll be covering that in the next step!

    If the deleted variants kept the hidden layers (and just hid them) you can skip ahead to step 7.

    If the deleted variants had the hidden layers removed from their structure to mimic hiding, then proceed with the next step:
  4. Copy the nested layer that will be hidden/shown using boolean properties from a remaining variant to your clipboard.
  5. Next, find an instance of one of the variants you deleted. Use Idan Arbel’s free Instance Finder plugin to track down every instance of this variant in your file.
  6. For each instance in the returned list:
    1. Detach it
    2. Paste in the layer copied to your clipboard.
    3. Make sure it’s in the correct position so the layer structure matches the instances of the main component. This is important for preserving your overrides (handled by the next step) when you re-link it to the main component!
  7. Use Gleb’s Master plugin to re-associate what you have selected to the enhanced main component. First, select the variant you want to apply to the detached frames/instances and run the <span class="inline-code">Pick Target Component</span> action.
  8. Finally select the detached frames/instances and use Master’s <span class="inline-code">Link objects to target components</span> action. As long as they have the same layer structure (which should be achieved by the previous step) then the plugin will run successfully. Your overrides will be preserved, and you can use the new boolean property to hide the layers you need hidden!

    If you ran the plugin and lost overrides, undo the action using <span class="keyboard-key">command</span> + <span class="keyboard-key">Z</span> and re-examine the layer structure of the detached frames/instances.

    If you originally skipped steps 3-6 but are finding Master is not preserving overrides when you link the instances to the new target variants, return to step 3 and execute the process from there.

⚠️ Important note: Repeat this process with each local main component across your entire file.

After cleaning up your local components, you may find yourself raring to do the same in your component library. If it’s fast and easy for you to run through that file and make this kind of enhancement, more power to you! But if you need permission from teammates to edit and publish from the library, then the process might take too long. In those situations, I suggest moving on to the next milestone.

<h2 id="milestone-3">Milestone 3) Reduce variant count</h2>

Good news, if you made progress in the last phase of Milestone 2, Phase 2, then you’ve technically already made some progress here! That doesn’t mean we’re done though. It can be taken even further.

Much like hidden layers, Figma renders each variant in the background when instances of that component are placed. This is what allows for instantaneous swapping using properties in the design panel.

My rule of thumb is that if you have a variant set with over 50 variants, it's worth taking a critical eye to it. Here’s the most efficient order to do this in:

<h3 id="m3-phase1">Phase 1) Introduce exposed nested instances.</h3>

Are you using ⍚ base components? If so, these tend to be a big clue for components that can be enhanced with this feature. Often nested ⍚ base component’s properties will be repeated downstream in the main components they support. But by using the expose nested instances feature, we no longer have to manually re-make those properties! Here’s how to execute this:

  1. Identify all components using ⍚ base components who’s properties get repeated by the components that consume them.
  2. Pick a property that the main component repeats from its nested ⍚ base component.
  3. Remove any variants related to that repeated property.
  4. Select the variant set frame of the main component and opt to expose nested instances of the nested ⍚ base component.
  5. Remember to do micro-QA with every property you remove to ensure everything still works after being enhanced.

Repeat this process for each property on each component using ⍚ bases.

<h3 id="m3-phase2">Phase 2) Eliminate “faux-repeater property” in favor of using ✎ content carriers</h3>

This post is already long enough that I won’t get into the specifics of what content carriers are, but here’s a quick summary: I believe there’s 7 unique types of components out there that many designers use (or should be using). The problem is they just don’t have widely known names, or have been nameless! And it's hard, if not impossible, to leverage a technique if you don't know what to call it. We do have names for a couple, like “bases” and “slots.” But the other 5 have yet to be adopted by the wider design community. ✎ Content carriers is one of them.

Okay. What the heck is a “faux-repeater property”? It’s where you use variants or boolean component properties to mimic repeater functionality. Here’s an example that appears to be using variants to offer 5 rows and 3 columns in a table component:

What folks are missing in Figma that tools like Adobe XD and Axure have is what’s known as a “repeater.” Repeaters allows you componentize a limitless list of objects. Here’s what it looks like in Adobe XD:

Repeat-Grid--Source-(Updated)2.gif
demo of Adobe XD's grid-repeat feature

While we can mimic repeaters in Figma using variants or component properties, it requires tons of extra layers.

I believe the better solution is to allow designers to swap out a ✂ slot or small example of what populated content would look like with their own custom local component that’s suited to their mockup or prototype. That local component would be considered a ✎ content carrier.

If you’re interested in making this enhancement in your library, here are the steps to follow:

  1. Identify any components that have faux-repeater properties. Generally these are things that often show up in a list-like form:
    1. Table cells
    2. Rows or columns in a table
    3. Dropdown select list menus
    4. Lists of cards
    5. Tabs, Carousels / galleries / sliders
  2. Prioritize fixing up the components that are using variants for their repeaters over ones using component properties. Remember, component properties show/hide boolean is always more layer-efficient than variants, and the goal of this milestone is to reduce variant count! Narrow it down even further to the component that’s using the most variants. Again, leverage the Layer Counter plugin if you want to make decisions using precise numbers.
  3. With your a component identified, remove all its variants that contribute to the faux-repeater property (the property might be named “Number of rows” if it’s a table or simply “Count”) except for one. Which one? I suggest one that feels like a sensible default, erring on the small side (remember, we’re here to slash our layer count). For example, if it’s a table component that had a property letting you show anywhere between 1 - 10 rows, I’d pick the variant that displays 3 rows.
  4. Click into the variant you kept and select the nested layers that make up the list objects. Wrap them in an auto layout frame and name it <span class="figma-frame">[parent component name] content.</span>
  5. If you have Gleb’s Master plugin, finish with this step, then skip ahead to step 8 after completing it. If you don’t have Master, skip this step and complete steps 6 - 7.

    With the  new auto layout frame selected, run Master’s <span class="inline-code">Create component from objects</span> action.
  6. Drag the auto layout frame you created and named
  7. <span class="figma-frame">[parent component name] content.</span> out of the variant and onto the canvas.
  8. Turn it into a main component, and place an instance of it back inside the variant(s) of the component you were working with before.
  9. OPTIONAL: Prefix a ✎ glyph in front of the name of the <span class="figma-component">✎ [parent component name] content</span> main component. This is just a visual indication that this is a content carrier component.
  10. Go back to your original component. Select the nested instance of <span class="figma-component">✎ [parent component name] content</span> and create a component property that allows you to swap this with other components. Name the property <span class="inline-code">Content</span> or <span class="inline-code">Rows</span> or <span class="inline-code">Items</span>—whatever makes the most sense based on the piece of interface that component represents.

Now when you or other designers use instances of the component, they have a sensible starting place to begin with (e.g. a table with 3 rows), and if they need more or fewer nested objects, they can make a local copy of <span class="figma-component">✎ [parent component name] content</span>, detach it, turn it into a local main component, and then swap it into their instance!

Congratulations! This is as far as we can go to slash the layer count, which is the highest impact action we can have in reducing memory usage. But if you’re still looking for ways to speed up your file, continue on to phase 3:

<h3 id="m3-phase3">Phase 3) Consider divesting from variants altogether!</h3>

If you’ve gone as far as you can go enhancing your components with component properties, but your instances and files feel laggy, there are two options:

  1. Split a variant set into separate components
    or
  2. Turn a variant property into a variable collection

How do you know which to do when? Well, I've got an entire other blog post dedicated to that. But to save you time, here's the quick version:

Split these variant properties into separate components:

  • Hierarchy (e.g. “Primary”, “Secondary”, “Tertiary”)
  • Major composition changes (e.g. “Landscape”, “Portrait”, “Full screen”)

Replace these variant properties with variable modes:

  • Validation feedback (e.g. “Success”, “Warning”, “Error”)
  • Breakpoints (e.g. “<= 756px”, “757px - 1020px”, “=> 1021px”)
  • Device/operating system (e.g. “iOS”, “Android”). This is something you should definitely be using separate components or even separate libraries for. And not even for resource-use reasons, but for instance usability. Why? Because variants force you to choose defaults, and in my opinion it’s not fair to the folks who work on the non-default operating system or device to have to do extra work to get to the variant they need.
  • Theme (e.g. “Dark mode”). For the same reason as Device/operating system, I advise folks to treat this as a separate component if your product supports true dark mode and you’re not using a misnomer for inverted.

If you're interested in the tradeoffs that come with making these changes, check out my other blog post.

Reducing the size of your variant sets will lighten up the cost of each instance from that set. This makes those instances more snappy and responsive to changes. Speed is part of what makes a good user experience, and Figma components are tiny products, so it’s important to think about the experience of using your instances!

<h2 id="milestone-4">Milestone 4) Compress images.</h2>

If you still have memory issues, the next most valuable place to look would be high resolution images weighing down your Figma file.

You may be using Styles to handle repeated imagery (like profile pictures, logos, product images etc.) In this case, I recommend using a free app like ImageOptim to compress your images externally from Figma. After compressing your images, edit the styles and upload the newly compressed imagery. This will be applied everywhere that style is being used, saving you time.

For places you’re not using Styles to handle imagery, use Alex Einarsson’s free plugin called Downsize. Alex includes some really good tips on the plugin’s page in the Figma community to get you the best results possible! Figma even recommends this plugin in their own file memory reduction documentation.

If your image is larger than 4,000px on any size, Figma will automatically downsample it upon load in an effort to maintain good performance. But this can result in pixelated images. If you must have an image of that size, use Yuan Qing Lim’s free plugin called Insert Big Image, which splits up the image into multiple smaller images to retain the size and resolution to avoid Figma’s auto downsampling.

<h2 id="milestone-5">Milestone 5) Simplify complex vectors</h2>

I personally don’t see this much in product designers files, and don’t have a lot of experience working with vectors in Figma. But according to Figma’s documentation, complicated vectors with many points is another type of asset (similar to big, high-res images) that can slow down a file. Figma’s documentation suggests importing big, complicated SVGs as multiple, smaller SVGs.

If you know other strategies for slimming vector shapes without sacrificing quality, please send them my way!

<div class="horizontal-rule"></div>

I wrote this post after helping a talented designer named Sedat troubleshoot why his file was suffering memory issues. He kindly gave me view access, and as I explored the file and saw the percentage of used memory climb with every new page I visited. I remembered when I was in this same situation in 2019 on a very high profile project.

That was the most stressful experience I had ever had in Figma. We carefully moved our work into the safe harbors of a new file, but there were times I thought we were doomed to lose it all. I remember being worried about my job. This completely changed the way I worked in Figma. I avoided hidden layers like the plague. Having the opportunity to help someone out of the same tough spot is the least I can do.

Unfortunately I can’t scale personalized, one-on-one help like that. So I sincerely hope the guidance and instructions in this post have helped you rescue your Figma file from Hades’ clutches,Orpheus and Eurydice style. I hope you never looked over your shoulder on the journey out, trusting your file was right behind you. ❤️

More than my other posts, I’d love to know if there’s anything erroneous, unclear, or unhelpful in this one. People looking for instructions like this are under immense stress. I’d love your help making this post the best it can be. Folks who read this deserve an easy journey back to calm waters.

<h2 id="change-log">Change log</h2>

  • Current version
    Noticed a chunk of content missing in Milestone 3, Phase 3. Must've accidentally deleted it during the last edit
  • April 28, 2024
    Updated Milestone 3, Phase 3 to account for variables.
  • May 13, 2023
    Unknown changes, sorry!
  • January 7, 2023
    First published.