18 Best Practices to Develop Secure, Performant Web Applications with Low Code
After deciding which low-code platform you'll use to build and power your apps, you need to focus on how to use it effectively. While low code drastically speeds up your web application development, there are still some best practices you should follow to build performant and secure apps.
In this post, we cover the eighteen best practices you need to build performant and secure apps with low code so that you can take full advantage of low-code platforms by building your business's infrastructure on top of one.
Low code is powerful, but the same rules of development still apply
Building applications with low-code platforms offers significant freedom and flexibility, but, like any tool, there's a right way to use it. Developers must understand that while low code can accelerate and simplify the development process, you still need to carefully plan your app so it is well designed and efficient.
Because of the flexibility offered by low-code app development, it's much easier to avoid (or fix) common pitfalls like overloading your user interfaces with too much data, creating overly complex pages, writing faulty code, and connecting to insecure back ends. Rather than having to refactor complex code to solve a problem, you can just tweak your app to resolve issues and test your changes as you make them.
Of course, the best solution to performance issues and future-proofing is to have a plan — you don't need to fix problems that never occur. That’s why developers and software architects should be mindful of architecture and design principles when using low code, just like when building traditional applications.
Best practices for developing low-code applications
The key best practices for building applications with low code are the same as the best practices for building with any programming environment: split and organize functionality intelligently, consider the performance impacts of how you load and display data, and follow the standard DevOps best practices for efficient development.
These optimizations need to be implemented on both the client side and server side of your application, as well as throughout your development process.
Client-side and user interface optimizations
The client side is where you’ll usually have the most control over your app’s performance, especially when building apps that rely on third-party APIs. When designing and building your client-side logic and user interfaces, you should recognize these best practices to ensure the best performance:
Limit the number of user interface widgets on each page
Each widget or UI element that your application loads will use CPU and memory (even if those widgets aren’t currently in the view window). While it's tempting to put everything relating to a task on one page, it’s important to understand how your low-code platform loads widgets and how you can structure your application to only load the minimum number of required widgets at any given time.
For example, in Appsmith, each application is split into multiple pages, and it only loads widgets for the current page. This means you can split functionality and user interface elements across separate pages to improve performance and give each page a well-defined purpose that is clear to your users.
When you build with a low-code platform, make sure you understand exactly how it loads widgets to make sure you won’t run into scaling issues as your application grows. This also helps the user experience — user interfaces that have been thoughtfully designed and split into sections are much easier for users to understand.
Optimize JavaScript code
Support for programming languages that developers already know (like JavaScript) is a bare minimum for a low-code platform. In our experience, there are just too many downstream problems from relying on a proprietary language when building low-code apps: it’s harder to find developers who already know it, there’s a higher learning curve for developers to learn it, and when developers inevitably run into trouble, there are fewer resources (like AI) that can answer their questions.
Assuming your platform natively supports JavaScript, you have roughly the same control over your code’s performance as you would with traditional programming. That means it’s important to pay attention to building efficient data structures and algorithms just as you do for your other apps.
It’s also a best practice to leverage reputable JavaScript libraries so that you don’t have to spend time reinventing the wheel. The code in well-established libraries will already be optimized and more secure. For example, lodash provides utility functions for common programming tasks and significantly improves performance when working with large arrays of data.
JavaScript functions like performance.now() and console.time() can be used to profile your code in the browser console so that you can analyze its performance. This shows you exactly which sections of your code are responsible for most of the latency so that you can prioritize them when optimizing your application.
Make efficient use of key-value stores
JavaScript’s local storage functions to persist data (localStorage and sessionStorage) can be used to cache data and reduce the amount of traffic to your back end. Most low-code platforms will have their own key-value stores that let you store ephemeral data, which should be utilized to reduce the number of back-end and API calls.
Regularly review functions and queries that run on page load
When building browser-based apps from scratch, it’s usually clear which functions are being called during your application’s startup by looking through the trace of function calls. However, low-code apps can be difficult to profile when using your web browser’s debugging tools, as your functions may be mixed in with the underlying platform's own code.
Make sure your low-code platform provides you with some kind of interface to easily tell whether or not an API or JavaScript function runs automatically on page load or not. As an example, the interface should look something like this:
Offload heavy client-side computation to the server
It’s important to pay attention to the specs of the devices that your app will potentially run on. If those clients are less powerful or have limited bandwidth, you should consider whether it's practical to perform some of your processing server-side instead.
A prime candidate here is database queries for filtering. Most back-end technologies and SaaS APIs support complex filtering, allowing you to offload work to the server and directly use the response on the client, rather than having to download the entire data set and waste resources on the client sorting and filtering through it. Server-side pagination is another key technique to limit the data that the client has to load at any one time when dealing with large datasets.
Disable unnecessary browser extensions
While you can’t control your end users’ browser environment, you can control your own and make your development experience smoother. If you find your app unexpectedly sluggish, identify any browser plugins that might be consuming resources and disable them. Debugging tools are often big resource drains (and often aren’t required since low-code platforms already have good debugging tools built in), so turning them off can solve a lot of performance problems.
Server-side strategies for efficient, cost-effective hosting
While you generally have less control over the server side of your low-code applications, if you do maintain your own back-end code, it should also be optimized for reliability and performance.
Profile server calls
In order to fix a problem with your app, you need to first identify what is causing it, or you may waste time optimizing a function or query that isn't even responsible for the latency you’re experiencing.
The starting point for optimizing your server side is usually to profile your server calls from the client side. Make sure your low-code platform makes this easy. As an example, here’s how Appsmith profiles API and database queries to the server:
Optimize queries
After you identify which query is introducing unexpected latency, you can use specialized tools like MongoDB database profiler and the SQL Server profiler to further dig down into which step of the query or API call is causing the latency on the server.
There are some common optimizations that can greatly improve database performance, such as implementing indexes on commonly searched columns in SQL databases and using schema stitching when querying multiple GraphQL endpoints. However, depending on your back end, you’ll likely need to do some research to find optimizations beyond the basic ones.
Upgrade server specifications
If you've optimized every facet of your back-end code and are still experiencing problems, you might just need more powerful hardware. If you're hosting your own infrastructure, you could upgrade your on-premises hardware or allocate more resources to your cloud instances.
If you're relying on a third-party API or SaaS platform, you can try raising a support ticket to see if the developers are aware that their current level of service is lacking. If they can’t meet your requirements, you might have to switch providers. If you go this route, make sure that you’ve tested the latency for your new provider as well before permanently switching.
In order to avoid this, it’s a good idea to put more effort into choosing the right integrations the first time. It’s helpful to check which integrations your low-code platform supports by default. These are usually more heavily tested, so you’re less likely to run into performance issues.
Low-code app development workflows that get the most out of your team and technology
A strong priority after app performance is an efficient development workflow. Low-code platforms are supposed to make development easier. That means you shouldn’t have to throw out all of your other libraries and DevOps tools that are already making traditional development easier.
Here are some of our key recommendations for development workflow features to look for in a low-code platform:
Develop with Git
There’s a reason that Git is ubiquitous in software development: it lets you easily track changes to your application, collaborate with team members, and integrate with a CI/CD pipeline for automatic code testing and deployment. The fact that you’re building low-code applications doesn’t change any of these facts. Git is critical to all of these, so it’s important to make sure your low-code platform supports it out of the box.
Keep it DRY and leverage libraries and modules
DRY (don't repeat yourself) is a core tenet of programming that makes it faster to write code while keeping it maintainable (as bugs only need to be fixed in one spot). In traditional programming, this is possible mainly through the ability to write your own functions and libraries that can be reused infinitely across your app.
However, the ability to build your own libraries and modules has been lacking in the low-code space for a long time. For that reason, it’s important to verify that your low-code supports packaging the UI widgets and queries that you build through low code to be reused across all of your applications. On Appsmith, this is what the Appsmith Modules feature is responsible for.
Choose open source
It’s not necessary to choose an open-source low-code platform, but it's strongly recommended. For one, you don’t have to worry about vendor lock-in, which might artificially restrict you as your application scales. Open-source projects often have strong communities, documentation, opportunities, and enthusiasm for self service that are hard to replicate in a closed-source model.
It’s also safer to build on top of open-source platforms: if an app platform is 100% proprietary, anything you build with it may be in jeopardy if the company is bought out or goes bankrupt (or just decides to change their product offering). You don’t want the platform that your business continuity relies on disappearing unexpectedly!
Lean on third-party libraries
Why write, test, and maintain code yourself when someone else has already done it for you? Third-party libraries allow you to integrate much more complicated functionality into your apps without having to build everything from scratch.
If your low-code platform supports importing JavaScript libraries out of the box, you can leverage the work of others to perform complicated yet common tasks like creating charts, handling more complicated dates and times, authentication, and more.
Low-code, high security: web application security best practices
When developing web applications, performance may be the first thing discussed, but security is always the most important. Make sure you fully leverage the following security technologies and features:
Self-host your applications
The most important security feature for your low-code platform is the ability to self-host. If you control the infrastructure where your instance is hosted (for example, in your VPC behind a firewall), you have far greater control over who can access it as you don’t have to expose your data externally. One other side benefit of this is that you’ll also have reduced latency for database queries since the two instances will be physically close.
Enforce granular access control
You should only grant the necessary users and services access to the specific resources they require to avoid exposing a larger attack surface area than necessary. And ideally, you’ll also be able to manage this from one centralized dashboard.
Look for a low-code platform that implements standard role-based access control and gives you full visibility into which parts of your application users have access to. As an example, you can check out the documentation for how Appsmith implements granular access control to limit access to workspaces, applications, and pages.
Implement industry standard encryption
It’s critical to make sure the low-code platform you’re using, as well as the back ends and APIs you connect to, support industry-standard encryption. Some of the most important features are full encryption for data in transit and at rest, secure secrets management and SQL injection protection, as well as many other security measures.
Use safe, secure authentication and authorization
Make sure you correctly configure and fully utilize your low-code platform’s authentication and authorization tools. This will avoid the need to implement your own (it's too easy to get something wrong!), and it provides a convenient, secure way for your users to access your application. Plus, it’s one less thing to worry about when developing apps. Some of the most common features to look for are standard login all the way to SSO options like Google Auth, GitHub Auth, SAML, and OIDC.
Set up logging (and pay attention to logs)
Wherever possible, you should also enable logging. That way, there's an audit trail of who did what and when that can be analyzed for suspicious activity or in a cybersecurity event. Ideally, your low-code platform will support logging automatically so that all of the critical applications across your company’s infrastructure automatically track relevant usage information.
Best practices make the best apps. Low code helps.
When building low-code applications, think about the client-side optimizations, server-side optimizations, development workflows, and security features that you rely on in a standard development workflow. Then, make sure your low-code platform supports each of these best practices. Otherwise, sooner or later, you're going to run into a performance, security, or functionality problem you can't solve.
All of these features and workflows are there for a reason, so you shouldn’t be forced to give them up just to get the other benefits of switching to low code. In fact, these are some of the key features that we focused on when building the Appsmith low-code platform.
If you’re interested in trying out Appsmith, you can reach out to discuss your use case and see if any of our self-hosting options would fit your needs.