Optimizing Script Architecture and Code
Use SuiteScript 2.1
For the latest changes and improvements, use SuiteScript 2.1 instead of an earlier SuiteScript version for your scripts.
Avoid Slow I/O
When you develop SuiteScripts that interact with the NetSuite application UI, such as user event scripts and client scripts, it is imporant to minimize the use of I/O operations. Slow I/O may significantly impact the responsiveness of your application and may lead to longer page load times for users.
Examples of slow I/O include:
-
Database queries that retrieve large amounts of data
-
Loading files from the File Cabinet
-
Requests to external applications or web services
-
Updating related records within a script
Best Practices:
-
Avoid requesting large amounts of data to be returned from the database to the UI. Instead, calculate values within the script or use cached data if available.
-
Use asynchronous, non-interactive scripts, such as scheduled scripts or map/reduce scripts, to process slow I/O operations.
-
Optimize queries to ensure they return only the data needed for the current operation.
-
Use the N/cache module to cache data that is used multiple times within a script.
Avoid Synchronous Re-edits
When you develop user event scripts, avoid synchronously editing the same record within the script. Do not reload or edit the same record synchronously in the beforeSubmit event. The record is already loaded and available for modification in this context. Attempting to reload the record in beforeSubmit will result in a "Record has been changed" error.
If you need to update the record after it has been saved, use asynchronous processing methods:
-
Where possible, set field values directly on the record in the beforeSubmit event.
-
Use scheduled scripts or map/reduce scripts to avoid errors, long loading times, or blocking user actions.
-
While you may edit the record in the afterSubmit event, you should offload any additional processing to asynchronous scripts instead to maintain optimal performance and user experience.
Use a Single Synchronous Entry Point
Deploy only one user event script and one client script for each record or transaction type. Adding multiple synchronous scripts may slow page-load time.
Best Practices:
-
Merge logic into one file where possible. Keep all synchronous work in a single script file. Break out tasks into helper modules and call them from your main entry point.
-
Keep the entry point light. Offload the most resource-intensive tasks to a scheduled script, map/reduce script, or RESTlet.
-
Review deployments regularly. If you see more than one synchronous script on the same record, consolidate them to reduce initialization overhead and simplify debugging.
A single entry point ensures predictable execution order, minimizes record reloads, and keeps governance consumption under control.
Run Independent Logic in Parallel
If two or more of your tasks do not depend on each other, do not run them back to back in the same uder event script or client script flow. Instead, process them simultaneously with promise.all(), or run them in separate asynchronous tasks, the join the results with a short promise chain.
This approach may trim total run time an cause the page to be more responsive.
Batch API Calls
For any script that contains several NetSuite calls, fetch or update records in bulk before processing them in your script when possible. Placing several NetSuite API calls inside a for loop multiplies latency and may noticeably decrease performance.
Avoid Loading Records in Dynamic Mode
When possible, use the default mode to load simple records, and avoid dynamic mode when possible. Dynamic mode may be slower for loading records and may be unnecessary for certain record loads.
Only Load Modules that are Needed
Use lazy loading for modules used in your script to avoid unnecessary overhead processing.
Avoid Empty Entry Points
Do not deploy scripts with blank entry functions. They still load and may affect performance without doing any work.
Read Line Data Directly
When you need to read line data in your client scripts, use getSublistValue(), or getCurrentSublistValue(), instead of selectLine(). Using a direct read avoids UI refreshes and speeds up execution.
Write One Time, Not Repeatedly
Read necessary values one time, compute your result in memory on your script, and call setCurrentSublistValue(). Multiple writes in your script add avoidable overhead processing.
Use the Header + Child Record Pattern
If you create many records of the same type, follow the header + child pattern rather than using separate record.create() calls for each time. Instead, create one header record and add child lines in a single save operation to conserve resources and improve performance.