Process Memory Management
Main Process Memory Optimization
// Memory leak detection example
const { app, BrowserWindow } = require ( ' electron ' );
const heapdump = require ( ' heapdump ' );
app. on ( ' ready ' , () => {
// Periodically generate heap snapshots (development environment)
if (process.env. NODE_ENV === ' development ' ) {
setInterval (() => {
const filename = `heapdump- ${ Date. now () } .heapsnapshot` ;
heapdump. writeSnapshot (filename);
}, 60000 ); // Generate every minute
}
// Window management optimization
const windows = new Set ();
function createWindow () {
const win = new BrowserWindow ({ /* ... */ });
windows. add (win);
win. on ( ' closed ' , () => {
windows. delete (win); // Explicitly release window reference
win = null ; // Aid garbage collection
});
}
});
Renderer Process Memory Optimization
// Renderer process memory management example
class ResourceManager {
constructor () {
this .cache = new Map ();
this .maxCacheSize = 100 ;
}
loadImage ( url ) {
if ( this .cache. has (url)) {
return this .cache. get (url);
}
const img = new Image ();
img.src = url;
this .cache. set (url, img);
// LRU cache strategy
if ( this .cache.size > this .maxCacheSize) {
const firstKey = this .cache. keys (). next ().value;
const firstImg = this .cache. get (firstKey);
firstImg.src = '' ; // Release resource
this .cache. delete (firstKey);
}
return img;
}
}
Virtual List Implementation
// Large dataset virtual list component
class VirtualList {
constructor ( container , itemHeight , totalItems , renderItem ) {
this .container = container;
this .itemHeight = itemHeight;
this .totalItems = totalItems;
this .renderItem = renderItem;
this .visibleItems = [];
this .scrollTop = 0 ;
this . init ();
}
init () {
// Set container height
this .container.style.height = ` ${ this .totalItems * this .itemHeight } px` ;
// Create placeholder for visible area
this .placeholder = document. createElement ( ' div ' );
this .placeholder.style.height = ' 100% ' ;
this .container. appendChild ( this .placeholder);
// Bind scroll event
this .container. addEventListener ( ' scroll ' , () => {
this . handleScroll ();
});
// Initial render
this . handleScroll ();
}
handleScroll () {
const newScrollTop = this .container.scrollTop;
if (Math. abs (newScrollTop - this .scrollTop) < this .itemHeight) return ;
this .scrollTop = newScrollTop;
this . renderVisibleItems ();
}
renderVisibleItems () {
const visibleCount = Math. ceil ( this .container.clientHeight / this .itemHeight);
const startIndex = Math. floor ( this .scrollTop / this .itemHeight);
const endIndex = Math. min (startIndex + visibleCount, this .totalItems);
// Reuse existing DOM elements
this .visibleItems. forEach (( item , index ) => {
const actualIndex = startIndex + index;
if (actualIndex < endIndex) {
this . updateItem (item, actualIndex);
} else {
this .container. removeChild (item.element);
}
});
// Add new elements
for ( let i = this .visibleItems.length; i < endIndex - startIndex; i ++ ) {
const actualIndex = startIndex + i;
const element = document. createElement ( ' div ' );
element.style.position = ' absolute ' ;
element.style.top = ` ${ actualIndex * this .itemHeight } px` ;
element.style.height = ` ${ this .itemHeight } px` ;
this .container. appendChild (element);
this .visibleItems. push ({
element,
index : actualIndex
});
this . renderItem (element, actualIndex);
}
// Remove excess elements
while ( this .visibleItems.length > endIndex - startIndex) {
const lastItem = this .visibleItems. pop ();
this .container. removeChild (lastItem.element);
}
}
updateItem ( item , index ) {
// Update existing element content
this . renderItem (item.element, index);
}
}
Startup Speed Optimization
Preload Script Optimization
// preload.js - On-demand loading strategy
const { contextBridge, ipcRenderer } = require ( ' electron ' );
// Expose only necessary APIs
contextBridge. exposeInMainWorld ( ' electronAPI ' , {
// Basic functionality
readFile : ( path ) => ipcRenderer. invoke ( ' read-file ' , path),
// Deferred loading API
getAdvancedAPI : () => {
return new Promise (( resolve ) => {
// Load heavy module on demand
import ( ' ./heavyModule ' ). then ( module => {
resolve ( module . createAdvancedAPI (ipcRenderer));
});
});
}
});
Deferred Loading Strategy
// Main process deferred loading example
let heavyModule = null ;
ipcMain. handle ( ' heavy-operation ' , async ( event , data ) => {
if ( ! heavyModule) {
// Dynamically load heavy module
heavyModule = await import ( ' ./heavyModule ' );
}
return heavyModule. processData (data);
});
// Renderer process deferred loading example
async function loadHeavyComponent () {
// Show loading indicator
showLoadingIndicator ();
// Dynamically import component
const HeavyComponent = await import ( ' ./HeavyComponent ' );
// Hide loading indicator
hideLoadingIndicator ();
// Render component
renderComponent (HeavyComponent);
}
Resource Compression and Caching
Resource Compression Configuration
// webpack.config.js - Production environment optimization
const TerserPlugin = require ( ' terser-webpack-plugin ' );
const CssMinimizerPlugin = require ( ' css-minimizer-webpack-plugin ' );
module . exports = {
mode : ' production ' ,
optimization : {
minimizer : [
new TerserPlugin ({
parallel : true , // Multi-threaded compression
terserOptions : {
compress : {
drop_console : true // Remove console logs
}
}
}),
new CssMinimizerPlugin ()
],
splitChunks : {
chunks : ' all ' , // Code splitting
cacheGroups : {
vendors : {
test : / [ \\/ ] node_modules [ \\/ ] / ,
priority : - 10
}
}
}
},
performance : {
hints : ' warning ' ,
maxEntrypointSize : 512000 , // Entry file size limit
maxAssetSize : 512000 // Asset file size limit
}
};
Caching Strategy Implementation
// Service Worker caching strategy
// sw.js
const CACHE_NAME = ' electron-app-cache-v1 ' ;
const ASSETS = [
' / ' ,
' /index.html ' ,
' /styles/main.css ' ,
' /scripts/main.js '
];
self. addEventListener ( ' install ' , (event) => {
event. waitUntil (
caches. open (CACHE_NAME)
. then (cache => cache. addAll (ASSETS))
);
});
self. addEventListener ( ' fetch ' , (event) => {
event. respondWith (
caches. match (event.request)
. then (response => {
// Return cached response if hit
if (response) return response;
// Otherwise fetch from network
return fetch (event.request)
. then (response => {
// Cache cachable resources
if (event.request.url. match ( / \.(js | css | png | jpg | jpeg | gif | ico)$ / )) {
const clone = response. clone ();
caches. open (CACHE_NAME)
. then (cache => cache. put (event.request, clone));
}
return response;
});
})
);
});
GPU and Hardware Acceleration
Hardware Acceleration Configuration
// Main process hardware acceleration configuration
const { app } = require ( ' electron ' );
app. disableHardwareAcceleration (); // Disable hardware acceleration (for debugging)
// Or control via command-line arguments
// electron --enable-features=HardwareAcceleration
// Renderer process CSS hardware acceleration
.optimized - element {
transform: translateZ ( 0 ); // Trigger GPU acceleration
will - change: transform; // Hint browser for optimization
}
// WebGL hardware acceleration verification
const canvas = document. getElementById ( ' webgl-canvas ' );
const gl = canvas. getContext ( ' webgl ' );
if ( ! gl) {
console. error ( ' WebGL unavailable, hardware acceleration may be disabled ' );
} else {
console. log ( ' WebGL context created successfully, hardware acceleration available ' );
}
Native Module Development
Node.js Native Module Development
C++ Addon Example
// hello.cc - Basic C++ addon
#include < node_api.h >
napi_value Hello ( napi_env env , napi_callback_info info ) {
napi_value greeting;
napi_create_string_utf8 (env, " Hello from C++ " , NAPI_AUTO_LENGTH, & greeting);
return greeting;
}
NAPI_MODULE_INIT () {
napi_value fn;
napi_create_function (env, nullptr , 0 , Hello, nullptr , & fn);
napi_set_named_property (env, exports, " hello " , fn);
return exports;
}
Build Configuration
# binding.gyp - Build configuration
{
"targets" : [
{
"target_name" : " hello " ,
"sources" : [ " hello.cc " ],
"include_dirs" : [ " <!@(node -p \" require('node-addon-api').include \" ) " ],
"dependencies" : [ " <!(node -p \" require('node-addon-api').gyp \" ) " ],
"cflags_cc" : [ " -std=c++17 " ]
}
]
}
Precompiled Native Module Integration
Using prebuild-install
# Install precompiled module
npm install prebuild-install
# Add install script to package.json
{
"scripts" : {
"install" : " prebuild-install || node-gyp rebuild "
}
}
// package.json configuration example
{
" name " : " native-addon " ,
" version " : " 1.0.0 " ,
" binary " : {
" module_name " : " nativeAddon " ,
" module_path " : " ./lib/binding/{configuration}/{node_abi}-{platform}-{arch} " ,
" host " : " https://github.com/username/native-addon/releases/download " ,
" remote_path " : " ./{version} " ,
" package_name " : " {node_abi}-{platform}-{arch}.tar.gz "
},
" scripts " : {
" install " : " prebuild-install || node-gyp rebuild " ,
" rebuild " : " node-gyp rebuild --build-from-source "
}
}
#!/bin/bash
# build-all.sh - Cross-platform compilation script
# Clean old builds
rm -rf build/
# Compile Windows version
npm run rebuild -- --arch=x64 --platform=win32
# Compile macOS version
npm run rebuild -- --arch=x64 --platform=darwin
# Compile Linux version
npm run rebuild -- --arch=x64 --platform=linux
# Package binaries for all platforms
mkdir -p dist/
cp -r build/Release/ * .node dist/
Conditional Compilation Example
// platform_utils.cc - Platform-specific code
#include < node_api.h >
#include < string >
napi_value GetPlatformInfo ( napi_env env , napi_callback_info info ) {
napi_value result;
napi_create_string_utf8 (env, GetPlatformString (). c_str (), NAPI_AUTO_LENGTH, & result);
return result;
}
std :: string GetPlatformString () {
#if defined ( _WIN32 )
return " Windows " ;
#elif defined (__APPLE__)
return " macOS " ;
#elif defined (__linux__)
return " Linux " ;
#else
return " Unknown " ;
#endif
}
NAPI_MODULE_INIT () {
napi_value fn;
napi_create_function (env, nullptr , 0 , GetPlatformInfo, nullptr , & fn);
napi_set_named_property (env, exports, " getPlatform " , fn);
return exports;
}
Native Module Security and Permissions
Secure Communication Example
// secure_addon.cc - Secure communication example
#include < node_api.h >
#include < string >
napi_value SafeOperation ( napi_env env , napi_callback_info info ) {
size_t argc = 1 ;
napi_value args[ 1 ];
napi_get_cb_info (env, info, & argc, args, nullptr , nullptr );
// Validate input parameters
char buffer[ 256 ];
size_t buffer_size = sizeof (buffer);
napi_get_value_string_utf8 (env, args[ 0 ], buffer, buffer_size, nullptr );
// Parameter safety check
if ( strlen (buffer) > 100 ) {
napi_throw_error (env, nullptr , " Input too long " );
return nullptr ;
}
// Perform secure operation
std :: string result = " Processed: " + std :: string (buffer);
napi_value output;
napi_create_string_utf8 (env, result. c_str (), NAPI_AUTO_LENGTH, & output);
return output;
}
NAPI_MODULE_INIT () {
napi_value fn;
napi_create_function (env, nullptr , 0 , SafeOperation, nullptr , & fn);
napi_set_named_property (env, exports, " safeOperation " , fn);
return exports;
}
Efficient Memory Management
// memory_efficient.cc - Efficient memory management example
#include < node_api.h >
#include < vector >
napi_value ProcessLargeData ( napi_env env , napi_callback_info info ) {
// Get input data
size_t argc = 1 ;
napi_value args[ 1 ];
napi_get_cb_info (env, info, & argc, args, nullptr , nullptr );
// Use direct buffer access
void* data;
size_t length;
napi_get_arraybuffer_info (env, args[ 0 ], & data, & length);
// Directly process binary data (avoid copying)
unsigned char* buffer = static_cast<unsigned char*> (data);
for ( size_t i = 0 ; i < length; i ++ ) {
buffer[i] = buffer[i] ^ 0x FF ; // Simple data processing example
}
// Return input buffer directly (zero-copy)
napi_value result;
napi_create_external_arraybuffer (
env,
data,
length,
nullptr , // No finalizer callback
nullptr ,
& result
);
return result;
}
NAPI_MODULE_INIT () {
napi_value fn;
napi_create_function (env, nullptr , 0 , ProcessLargeData, nullptr , & fn);
napi_set_named_property (env, exports, " processLargeData " , fn);
return exports;
}
Advanced IPC Communication
Structured Data Transmission
Protocol Buffers Integration
// message.proto
syntax = " proto3 " ;
message DataMessage {
int32 id = 1 ;
string content = 2 ;
repeated float values = 3 ;
map < string, string > metadata = 4 ;
}
// Protocol Buffers integration example
const protobuf = require ( ' protobufjs ' );
const path = require ( ' path ' );
// Load proto file
protobuf. load (path. join (__dirname, ' message.proto ' ), ( err , root ) => {
if (err) throw err;
// Get message type
const DataMessage = root. lookupType ( ' DataMessage ' );
// Encode message
const payload = { id : 1 , content : ' test ' , values : [ 1.1 , 2.2 ], metadata : { key : ' value ' } };
const errMsg = DataMessage. verify (payload);
if (errMsg) throw Error (errMsg);
const message = DataMessage. create (payload);
const buffer = DataMessage. encode (message). finish ();
// Send binary data via IPC
window.electronAPI. sendData (buffer);
// Decode at receiver
window.electronAPI. onDataReceived (( buffer ) => {
const message = DataMessage. decode (buffer);
const object = DataMessage. toObject (message, {
longs : String,
enums : String,
bytes : String
});
console. log ( ' Received: ' , object);
});
});
Inter-Process Event Broadcasting
Event Broadcasting System
// Main process event broadcasting
const { ipcMain, BrowserWindow } = require ( ' electron ' );
// Store all window references
const windows = new Set ();
function createWindow () {
const win = new BrowserWindow ({ /* ... */ });
windows. add (win);
win. on ( ' closed ' , () => {
windows. delete (win);
});
}
// Broadcast event to all windows
ipcMain. on ( ' broadcast-event ' , ( event , eventName , ... args ) => {
windows. forEach ( win => {
if ( ! win. isDestroyed ()) {
win.webContents. send (eventName, ... args);
}
});
});
// Renderer process listening for broadcasts
window.electronAPI. onBroadcastEvent (( eventName , ... args ) => {
console. log ( `Received broadcast: ${ eventName } ` , args);
});
Shared Memory and Efficient Transmission
Shared Memory Implementation
// shared_memory.cc - Shared memory example
#include < node_api.h >
#include < sys/mman.h >
#include < fcntl.h >
#include < unistd.h >
napi_value CreateSharedMemory ( napi_env env , napi_callback_info info ) {
// Create shared memory object
int shm_fd = shm_open ( " /electron_shm " , O_CREAT | O_RDWR, 0 666 );
ftruncate (shm_fd, 4096 ); // 4KB shared memory
void* ptr = mmap ( 0 , 4096 , PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0 );
// Return file descriptor to JS layer (via Node.js addon)
napi_value result;
napi_create_int32 (env, shm_fd, & result);
return result;
}
napi_value WriteToSharedMemory ( napi_env env , napi_callback_info info ) {
size_t argc = 2 ;
napi_value args[ 2 ];
napi_get_cb_info (env, info, & argc, args, nullptr , nullptr );
int shm_fd;
size_t data_size;
napi_get_value_int32 (env, args[ 0 ], & shm_fd);
napi_get_value_uint32 (env, args[ 1 ], & data_size);
void* ptr = mmap ( 0 , data_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0 );
// Write data to shared memory...
return nullptr ;
}
NAPI_MODULE_INIT () {
napi_value create_fn, write_fn;
napi_create_function (env, nullptr , 0 , CreateSharedMemory, nullptr , & create_fn);
napi_create_function (env, nullptr , 0 , WriteToSharedMemory, nullptr , & write_fn);
napi_value exports;
napi_get_named_property (env, exports, " createSharedMemory " , & create_fn);
napi_set_named_property (env, exports, " writeToSharedMemory " , & write_fn);
return exports;
}
Secure Communication and Validation
IPC Data Validation
// Main process secure validation
const { ipcMain } = require ( ' electron ' );
// Whitelist validation
const allowedCommands = new Set ([ ' read-file ' , ' write-file ' ]);
ipcMain. handle ( ' secure-command ' , async ( event , command , ... args ) => {
// 1. Validate command against whitelist
if ( ! allowedCommands. has (command)) {
throw new Error ( `Command ${ command } is not allowed` );
}
// 2. Validate argument types
if (command === ' read-file ' ) {
if ( typeof args[ 0 ] !== ' string ' ) {
throw new Error ( ' Invalid argument type for read-file ' );
}
// Path safety checks...
}
// 3. Execute operation
return await performOperation (command, ... args);
});
// Renderer process secure call
async function safeCommand ( command , ... args ) {
try {
return await window.electronAPI. secureCommand (command, ... args);
} catch (error) {
console. error ( ' Secure command failed: ' , error.message);
throw error;
}
}
Batch Data Processing
// Batch data transmission optimization
class DataBatcher {
constructor ( sendFn , batchSize = 100 , flushInterval = 100 ) {
this .sendFn = sendFn;
this .batchSize = batchSize;
this .flushInterval = flushInterval;
this .batch = [];
this .timer = null ;
}
add ( data ) {
this .batch. push (data);
// Send immediately if batch size reached
if ( this .batch.length >= this .batchSize) {
this . flush ();
return ;
}
// Start timer if not already started
if ( ! this .timer) {
this .timer = setTimeout (() => this . flush (), this .flushInterval);
}
}
flush () {
if ( this .batch.length === 0 ) return ;
// Send batch data
this . sendFn ( this .batch);
// Reset state
this .batch = [];
if ( this .timer) {
clearTimeout ( this .timer);
this .timer = null ;
}
}
}
// Usage example
const batcher = new DataBatcher (( batch ) => {
window.electronAPI. sendBatchData (batch);
});
// Add data
batcher. add ({ id : 1 , value : ' test ' });
Zero-Copy Data Transmission
// Zero-copy transmission implementation
const { ipcRenderer } = require ( ' electron ' );
// Send large binary data (zero-copy)
function sendLargeData ( buffer ) {
// Use Transferable object to avoid copying
ipcRenderer. postMessage ( ' large-data ' , buffer, [buffer.buffer]);
}
// Receiver handling
ipcRenderer. on ( ' large-data ' , ( event , buffer ) => {
// Directly use received buffer
console. log ( ' Received buffer: ' , buffer.byteLength);
});
// Main process counterpart
ipcMain. on ( ' large-data ' , ( event , buffer ) => {
// Directly access buffer data
const dataView = new DataView (buffer);
// Process data...
});