memlab-analysis
Expert skill for JavaScript memory leak detection using Facebook MemLab. Configure MemLab scenarios, execute memory leak detection runs, analyze heap snapshots, identify detached DOM elements, find event listener leaks, and integrate with CI pipelines.
What this skill does
# memlab-analysis
You are **memlab-analysis** - a specialized skill for JavaScript memory leak detection using Facebook's MemLab framework. This skill provides expert capabilities for detecting, analyzing, and fixing memory leaks in web applications.
## Overview
This skill enables AI-powered JavaScript memory analysis including:
- Configuring MemLab test scenarios
- Executing automated memory leak detection runs
- Analyzing heap snapshots for memory growth
- Identifying detached DOM elements
- Finding event listener and closure leaks
- Generating actionable MemLab reports
- Integrating with CI/CD pipelines
## Prerequisites
- Node.js 16+ (18+ recommended)
- MemLab CLI: `npm install -g memlab`
- Chrome/Chromium browser
- Optional: Puppeteer for custom scenarios
## Capabilities
### 1. MemLab Scenario Development
Write comprehensive MemLab test scenarios:
```javascript
// scenario.js - Basic memory leak detection scenario
module.exports = {
// Scenario metadata
name: 'user-dashboard-leak-test',
// Setup - navigate to starting page
async setup(page) {
await page.goto('https://app.example.com/');
await page.waitForSelector('.login-form');
},
// Action - perform the operation that may leak
async action(page) {
// Login
await page.type('#email', '[email protected]');
await page.type('#password', 'password123');
await page.click('#login-button');
await page.waitForSelector('.dashboard');
// Navigate to dashboard
await page.click('[data-testid="analytics-tab"]');
await page.waitForSelector('.analytics-charts');
// Interact with charts (potential leak source)
await page.click('[data-testid="chart-filter"]');
await page.waitForSelector('.chart-updated');
},
// Back - return to a clean state
async back(page) {
// Navigate away from the potentially leaking page
await page.click('[data-testid="home-tab"]');
await page.waitForSelector('.dashboard-home');
},
// Optional: custom leak filter
leakFilter(node, snapshot, leakedNodeIds) {
// Ignore known non-leaks
if (node.name === 'InternalCache') return false;
if (node.retainedSize < 1024) return false; // Ignore small leaks
return true;
}
};
```
### 2. Advanced Scenario Patterns
Complex scenario configurations:
```javascript
// modal-leak-scenario.js - Test modal dialog memory leaks
module.exports = {
name: 'modal-dialog-leak',
// Initial page state
url: () => 'https://app.example.com/products',
async setup(page) {
await page.setViewport({ width: 1920, height: 1080 });
await page.evaluate(() => {
window.memlab = { startTime: Date.now() };
});
},
async action(page) {
// Open modal
await page.click('[data-testid="add-product-btn"]');
await page.waitForSelector('.modal-overlay');
// Fill form
await page.type('[name="productName"]', 'Test Product');
await page.type('[name="description"]', 'Test Description');
// Upload image (potential leak)
const input = await page.$('[type="file"]');
await input.uploadFile('./test-image.png');
await page.waitForSelector('.image-preview');
// Close modal (should clean up)
await page.click('.modal-close');
await page.waitForSelector('.modal-overlay', { hidden: true });
},
async back(page) {
// Force garbage collection opportunity
await page.evaluate(() => {
window.dispatchEvent(new Event('beforeunload'));
});
await page.goto('https://app.example.com/');
},
// Repeat the action multiple times to amplify leaks
repeat: () => 3,
// Custom leak detection
leakFilter(node, snapshot, leakedNodeIds) {
// Focus on specific leak patterns
const suspectTypes = [
'HTMLDivElement',
'HTMLImageElement',
'EventListener',
'Closure'
];
return suspectTypes.includes(node.type);
}
};
```
### 3. SPA Route Navigation Testing
Test memory leaks during route changes:
```javascript
// route-navigation-scenario.js
module.exports = {
name: 'spa-route-navigation',
async setup(page) {
await page.goto('https://app.example.com/');
await page.waitForNetworkIdle();
},
async action(page) {
// Navigate through multiple routes
const routes = [
'/dashboard',
'/products',
'/orders',
'/settings',
'/analytics'
];
for (const route of routes) {
await page.click(`a[href="${route}"]`);
await page.waitForNetworkIdle();
await page.waitForTimeout(500);
}
},
async back(page) {
await page.click('a[href="/"]');
await page.waitForNetworkIdle();
}
};
```
### 4. Event Listener Leak Detection
Detect event listener accumulation:
```javascript
// event-listener-scenario.js
module.exports = {
name: 'event-listener-leak',
async setup(page) {
await page.goto('https://app.example.com/');
// Inject event listener counter
await page.evaluate(() => {
const originalAddEventListener = EventTarget.prototype.addEventListener;
const originalRemoveEventListener = EventTarget.prototype.removeEventListener;
window.__eventListenerCount = 0;
window.__eventListeners = new Map();
EventTarget.prototype.addEventListener = function(type, listener, options) {
window.__eventListenerCount++;
const key = `${this.constructor.name}:${type}`;
window.__eventListeners.set(key, (window.__eventListeners.get(key) || 0) + 1);
return originalAddEventListener.call(this, type, listener, options);
};
EventTarget.prototype.removeEventListener = function(type, listener, options) {
window.__eventListenerCount--;
const key = `${this.constructor.name}:${type}`;
window.__eventListeners.set(key, (window.__eventListeners.get(key) || 0) - 1);
return originalRemoveEventListener.call(this, type, listener, options);
};
});
},
async action(page) {
// Perform actions that add event listeners
await page.click('[data-testid="open-sidebar"]');
await page.waitForSelector('.sidebar');
await page.click('[data-testid="close-sidebar"]');
await page.waitForSelector('.sidebar', { hidden: true });
},
async back(page) {
// Check listener count
const stats = await page.evaluate(() => ({
count: window.__eventListenerCount,
listeners: Object.fromEntries(window.__eventListeners)
}));
console.log('Event listener stats:', stats);
await page.goto('https://app.example.com/');
}
};
```
### 5. Running MemLab Analysis
Execute MemLab commands:
```bash
# Basic leak detection
memlab run --scenario scenario.js
# Run with increased iterations
memlab run --scenario scenario.js --work-dir ./memlab-results
# Run specific phases
memlab snapshot --scenario scenario.js
memlab find-leaks --work-dir ./memlab-results
# Analyze existing heap snapshots
memlab analyze ./memlab-results
# Generate detailed report
memlab report --work-dir ./memlab-results --output-dir ./reports
# Run in headless mode
memlab run --scenario scenario.js --headless
# Custom Chromium path
memlab run --scenario scenario.js --chromium-binary /path/to/chrome
```
### 6. Heap Snapshot Analysis
Analyze heap snapshots for memory issues:
```javascript
// heap-analysis.js - Custom heap analysis
const { takeNodeMinimalHeap, findLeaks } = require('@memlab/api');
async function analyzeHeap() {
// Take heap snapshot
const heap = await takeNodeMinimalHeap();
// Find objects by type
const detachedDOMNodes = heap.nodes.filter(node =>
node.name.startsWith('Detached ') &&
node.type === 'native'
);
// Find large retained objects
const largeObjects = heap.nodes
.filter(node => node.retainedSize > 1024 * 1024) // > 1MB
.sort((a, b) => b.retainedSize - a.retainedSize)
.slice(0, 10);
// Find specific patterns
const closureLeaks = heap.nodes.filter(node =>
node.type === 'closure' &&
node.retainedSize > 10240
);
console.log('AnRelated in Cloud & DevOps
appbuilder-action-scaffolder
IncludedCreate, implement, deploy, and debug Adobe Runtime actions with consistent layout, validation, and error handling. Use this skill whenever the user needs to add actions to an App Builder project, understand action structure (params, response format, web/raw actions), configure actions in the manifest, use App Builder SDKs (State, Files, Events, database), deploy and invoke actions via CLI, debug action issues, or implement patterns such as webhook receivers, custom event providers, journaling consumers, large payload redirects, action sequence pipelines, and Asset Compute workers. Also trigger when users mention serverless functions in Adobe context, action logging, IMS authentication for actions, or cron-style scheduled actions.
orchestrating-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. Use this skill when the user needs a multi-step Data Cloud pipeline, cross-phase troubleshooting, or data space and data kit management. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase sf data360 workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching phase-specific skill), the task is STDM/session tracing/parquet telemetry (use observing-agentforce), standard CRM SOQL (use querying-soql), or Apex implementation (use generating-apex).
github-project-automation
IncludedAutomate GitHub repository setup with CI/CD workflows, issue templates, Dependabot, and CodeQL security scanning. Includes 12 production-tested workflows and prevents 18 errors: YAML syntax, action pinning, and configuration. Use when: setting up GitHub Actions CI/CD, creating issue/PR templates, enabling Dependabot or CodeQL scanning, deploying to Cloudflare Workers, implementing matrix testing, or troubleshooting YAML indentation, action version pinning, secrets syntax, runner versions, or CodeQL configuration. Keywords: github actions, github workflow, ci/cd, issue templates, pull request templates, dependabot, codeql, security scanning, yaml syntax, github automation, repository setup, workflow templates, github actions matrix, secrets management, branch protection, codeowners, github projects, continuous integration, continuous deployment, workflow syntax error, action version pinning, runner version, github context, yaml indentation error
sf-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase `sf data360` workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching sf-datacloud-* skill), the task is STDM/session tracing/parquet telemetry (use sf-ai-agentforce-observability), standard CRM SOQL (use sf-soql), or Apex implementation (use sf-apex).
fabric-cli
IncludedUse this skill for Fabric.so CLI workflows with the `fabric` terminal command: diagnose/install/login, search or browse a Fabric library, save notes/links/files, create folders, ask the Fabric AI assistant, manage tasks/workspaces, generate shell completion, check subscription usage, produce JSON output, and use Fabric as persistent agent memory. Do not use for Microsoft Fabric/Azure/Power BI `fab`, Daniel Miessler's Fabric framework, Python Fabric SSH, Fabric.js, or textile/fashion fabric.
lark
IncludedLark/Feishu CLI skills: lark-cli operations for docs, markdown, sheets, base, calendar, im, mail, task, okr, drive, wiki, slides, whiteboard, apps, approval, attendance, contact, vc, minutes, event. Use when the user needs to operate Lark/Feishu resources via lark-cli, send messages, manage documents, spreadsheets, calendars, tasks, OKRs, deploy web pages, or any Feishu/Lark workspace operations.