Back in October 2022, we shared exciting news about the version 3.x release of Salesforce Code Analyzer, our free code scanner that brings together multiple open-source code analysis engines under a unified Salesforce CLI experience. In particular, we did a deep-dive on Salesforce Graph Engine, which uses data flow analysis to detect advanced security vulnerabilities in code. Today, we’ll share how, with our version 3.9 release, we’re evolving Graph Engine with new rules to help you boost your code’s performance. So, sit back, relax, and get ready to accelerate your code!

New performance rules in version 3.9

With Code Analyzer version 3.9 we’re introducing a new performance rule, UnimplementedTypeRule, that detects whether you have unused Apex code in your solution. Specifically, it detects unused interfaces and abstract classes. It complements another rule that we introduced in version 3.8, UnusedMethodRule that detects unused methods. You can use these two rules to remove unused code and make your code smaller, more efficient, and therefore more performant (but more on that later).

We added these new rules to Salesforce Graph Engine. As a quick refresher, Graph Engine typically scans code using a path-based approach using something we call “data flow analysis” (DFA). Using this approach, Graph Engine consumes the entire code source simultaneously, and assimilates this information to produce a better understanding of what’s happening in the code. This path-based approach is quite different from the abstract syntax tree (AST), a static analysis approach used by all other engines in Code Analyzer, such as PMD and ESLint.

However, these rules are special. Instead of following a path-based approach, we use Graph Engine’s holistic understanding of how the code is structured and additional dependency information. This graph-based approach still uses static analysis, but it is more effective than a pure AST-based approach at detecting whether those interfaces, abstract classes, and methods are being used or not while maintaining great performance.

Graph-based approach allows you to query information that represents how ASTs of different Apex class files are interconnected.

Given that this graph-based approach is much faster than a path-based approach, we added these rules to the scanner:run command instead of scanner:run:dfa used by other Graph Engine rules.

How unused code impacts your solution’s performance

When your Apex code is deployed to a Salesforce org, it’s compiled and available to be invoked for execution directly or indirectly via multiple entry points. We call these entry points “sources” in Graph Engine. There are many different types of entry points, but examples include Apex code invoked from API calls or Apex code invoked from user interactions with Lightning components.

Importantly, all Apex code gets compiled, regardless of whether there are any sources that invoke it. If over time you’re continuously adding additional functionality, chances are that some of your code is sitting in your org (or your customers’ orgs if you’re an AppExchange partner) without ever getting executed. This is especially relevant if you have an older solution that has been gradually built over the years by different developers and you haven’t had a chance to do significant refactoring.

Now, remember that Salesforce is multi-tenant, and therefore multiple customers run on the same Salesforce instance and — importantly — share computational power, memory usage, and threads to run Apex within that particular instance. While we do have safeguards in place to optimize how we allocate and distribute resources across customers, having smaller, more efficient code is recommended.

There are additional advantages. Having less code means:

  • It’s less likely that you hit governor limits on Apex code character size
  • It’s faster for you to deploy metadata, install, and upgrade packages
  • It’s a lot easier for you to maintain code, including not needing as many unit tests
  • Apex compile time is shorter, accelerating development and deployment

In addition to performance rules, if you leverage the various code quality rules available in Code Analyzer through PMD, you can also make your code more readable and identify opportunities for code refactoring.

Install the latest version of Code Analyzer

Start using these new performance rules in Code Analyzer right away.

Make sure that you update to the latest version of Salesforce CLI:

And, if you haven’t done so already, install the Salesforce Code Analyzer plugin:

If you already had installed Code Analyzer previously, then just run sfdx update to make sure you have the latest version. That’s it!

Let’s clean up unused code

To get started, install our sample app.

Clone the dev branch of the Code Analyzer repo.

Next, open the sample directory, where you’ll find a project for a working app.

Notice that FlsHelperClass.cls contains a method named verifyCreateablePositiveStyle.

Now, look at UnusedInterface.cls, which contains the public interface UnusedInterface.

We don’t use verifyCreateablePositiveStyle anywhere within our sample app, and there are no implementations of UnusedInterface either.

Now run Code Analyzer against the project directory.

Note that we need to use --engine sfge and provide a --projectdir in order to run these rules with Graph Engine.

This will generate an output in CSV format where you see two violations reported by Code Analyzer.

"UnusedMethodRule","Method verifyCreateablePositiveStyle in class FlsHelperClass is never invoked"

and

"UnimplementedTypeRule","Extend, implement, or delete interface UnusedInterface"

If you delete both verifyCreateablePositiveStyle and UnusedInterface, and run Code Analyzer again:

You get:

Executed engines: sfge. No rule violations found.

That’s it! You cleaned up the code in our sample app. This means that if you were to deploy this code to a Salesforce org, we would only compile code that is actually needed and therefore improve the performance of your solution. Congratulations!

Try this out on your own code, and read more about Code Analyzer and Graph Engine in our documentation.

Conclusion

The Salesforce Code Analyzer team is constantly improving Code Analyzer. We’d love to hear your feedback and feature requests.

Resources

About the authors

Josh Feingold is a Senior Engineer with nearly seven years of experience at Salesforce. He began by contributing to the success of CPQ Salesforce as a performant and scalable Configure-Price-Quote solution. Now, as part of the Salesforce Code Analyzer Team, he’s turned his gaze outward to the community of Salesforce customers and partners, working to provide them with the tools to write secure, performant, and maintainable code.

John Belo is Director, Product Management for ISV Platform, focusing on Salesforce Code Analyzer, AppExchange App Analytics, as well as other areas within Packaging. He’s been with Salesforce for over seven years and has always been a part of the AppExchange team. He started by leading a team of ISV Technical Evangelists in EMEA, and is now part of the AppExchange Product Management team, intent on helping ISVs be as successful as they can be.

Get the latest Salesforce Developer blog posts and podcast episodes via Slack or RSS.

Add to Slack Subscribe to RSS