[TS] Optimizing Repeated Logic with Lazy Functions
What is a Lazy Function?
A lazy function is an advanced programming pattern where a function initializes itself during the first call and dynamically modifies its implementation based on runtime needs. This optimization improves performance for subsequent calls.
Purpose of Lazy Functions
Lazy functions help avoid unnecessary repeated checks or initialization logic, improving code efficiency. For instance, if a condition needs to be checked only once, subsequent calls can directly reuse the already-determined logic. This is precisely what lazy functions aim to achieve.
Use Case
Suppose we need to copy a string to the clipboard in JavaScript (or TypeScript). A typical implementation might look like this:
const copyTextToClipboard = (text: string) => {
if (navigator.clipboard) {
// Use the Clipboard API
navigator.clipboard.writeText(text);
} else {
// Fallback for older browsers
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed'; // Prevent the textarea from being visible
textarea.style.top = '-9999px';
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
try {
document.execCommand('copy');
console.log('Text copied to clipboard successfully (fallback)!');
} catch (err) {
console.error('Fallback: Failed to copy text: ', err);
}
document.body.removeChild(textarea);
}
};
// Function call
copyTextToClipboard('Text to copy');
In this implementation, the function checks whether the browser supports the navigator.clipboard API each time it is called. However, this check only needs to be performed once because the browser’s capabilities remain constant. Repeating this check for every call is redundant.
This is where lazy functions shine.
Optimized Code Using a Lazy Function
By dynamically rewriting the function, we can ensure the check only happens once. Here’s the optimized implementation:
let copyToClipboard = (text: string) => {
if (navigator.clipboard) {
// Function rewrite
copyToClipboard = (text: string) => {
navigator.clipboard.writeText(text);
};
} else {
// Function rewrite
copyToClipboard = (text: string) => {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed'; // Prevent the textarea from being visible
textarea.style.top = '-9999px';
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
try {
document.execCommand('copy');
console.log('Text copied to clipboard successfully (fallback)!');
} catch (err) {
console.error('Fallback: Failed to copy text: ', err);
}
document.body.removeChild(textarea);
};
}
// Initial call logic
copyToClipboard(text);
};
How the Optimized Code Works
- First Call:
- Determines if the browser supports
navigator.clipboard. - Dynamically rewrites the copyToClipboard function based on the result.
- Executes the logic for the first call.
- Subsequent Calls:
- Directly execute the rewritten function without re-checking.
Advantages
- Performance Optimization: Avoids repeated checks, improving runtime efficiency.
- Code Simplicity: After the first call, the function is optimized for the specific use case, eliminating unnecessary branching logic.
- Maintainability: The logic is clear and extensible. Future requirements for additional branches can be easily handled by modifying the initialization logic.
Conclusion
Lazy functions are an elegant and efficient programming pattern, especially suited for scenarios involving one-time initialization checks. By adopting this approach, we can make our code more efficient, concise, and maintainable. If you encounter similar repeated logic checks in your project, consider implementing lazy functions!