npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

x3test

v2.0.0

Published

Comprehensive automated performance benchmarking framework for X3D/X3DOM web scenes with FPS monitoring, node count tracking, and dual output formats

Readme

X3Test

X3Test is a comprehensive automated performance benchmarking framework for X3D/X3DOM web scenes. It uses Puppeteer to simulate user interactions and collect detailed performance metrics including FPS and node count data from X3DOM's runtime.

✨ Features

  • 🎯 Dual Output Formats: Choose between detailed per-second data or compact summary format
  • 📊 FPS Monitoring: Real-time frame rate collection every second
  • 🔢 Node Count Tracking: Extract actual scene complexity from X3DOM runtime
  • 🖥️ CLI & API: Full command-line interface and JavaScript API
  • 🚀 Zero Configuration: Works with any X3DOM-based web page without modification
  • 📈 Rich Metrics: Average FPS, render time, and scene statistics
  • 🎮 Interactive Testing: Support for animation triggers and user interactions

📦 Installation

Global Installation (CLI)

npm install -g x3test

Local Installation (API)

npm install x3test

🚀 Quick Start

Command Line Interface

Basic usage:

x3test -u https://example.com/scene.html

With custom options:

x3test -u https://example.com/scene.html -d 15 -o results.json -f summary

View all options:

x3test --help

JavaScript API

import { runX3Test } from 'x3test';

await runX3Test({
  url: 'https://example.com/scene.html',
  duration: 10,
  outputFile: 'results.json',
  triggerSelector: '#startButton',
  format: 'detailed'
});

📋 CLI Options

| Option | Short | Description | Default | |--------|-------|-------------|---------| | --url | -u | URL of the page with X3D scene | Required | | --duration | -d | Duration of test in seconds | 20 | | --output | -o | Output file path | fps-log.json | | --trigger | -t | CSS selector for animation trigger | #beginTest | | --format | -f | Output format: detailed or summary | detailed | | --help | -h | Display help information | - |

📊 Output Formats

Detailed Format (detailed)

Per-second data with FPS and node count for each measurement:

[
  {
    "second": 1,
    "fps": 59.87,
    "nodeCount": 2386
  },
  {
    "second": 2,
    "fps": 60.12,
    "nodeCount": 2390
  }
]

Use cases:

  • Frame-by-frame analysis
  • Performance debugging
  • Detailed timeline visualization
  • Identifying performance drops

Summary Format (summary)

Compact overview with aggregated statistics:

{
  "scene": "AnimatedModel",
  "duration": 15,
  "fpsLog": [60, 60, 59, 57, 60, 60, 58, 59, 60, 60, 60, 59, 60, 58, 60],
  "averageFPS": 59.3,
  "nodeCount": 2322,
  "renderTimeMs": 16.7
}

Use cases:

  • Performance benchmarking
  • Comparative analysis
  • Automated testing pipelines
  • Quick performance overviews

🔧 JavaScript API Reference

runX3Test(options)

Parameters:

| Parameter | Type | Description | Default | |-----------|------|-------------|---------| | url | string | URL of the X3D scene page | Required | | duration | number | Test duration in seconds | 20 | | outputFile | string | Path for results file | fps-log.json | | triggerSelector | string | CSS selector to trigger animation | #beginTest | | format | string | Output format: detailed or summary | detailed |

Returns: Promise<void>

Example:

import { runX3Test } from 'x3test';

// Detailed analysis
await runX3Test({
  url: 'https://mysite.com/3d-scene.html',
  duration: 30,
  outputFile: 'performance-detailed.json',
  triggerSelector: '.start-animation',
  format: 'detailed'
});

// Quick benchmark
await runX3Test({
  url: 'https://mysite.com/3d-scene.html',
  duration: 10,
  outputFile: 'benchmark.json',
  format: 'summary'
});

📈 Metrics Explained

FPS (Frames Per Second)

  • Real-time frame rate measurement
  • Calculated using requestAnimationFrame timing
  • Measured every second during the test duration

Node Count

  • Extracted from X3DOM runtime: x3d.runtime.states.infos.valueOf()["#NODES:"]
  • Represents actual scene complexity
  • Updates dynamically as scene changes
  • Includes all X3D nodes in the scene graph

Average FPS

  • Arithmetic mean of all FPS measurements
  • Provides overall performance indicator
  • Useful for comparing different scenes or optimizations

Render Time (ms)

  • Calculated as 1000 / averageFPS
  • Time in milliseconds to render one frame
  • Lower values indicate better performance

🎯 Use Cases

Performance Testing

# Quick performance check
x3test -u https://mysite.com/scene.html -d 10 -f summary

# Detailed analysis
x3test -u https://mysite.com/scene.html -d 60 -f detailed

Automated CI/CD

// In your test suite
import { runX3Test } from 'x3test';

describe('3D Scene Performance', () => {
  it('should maintain 30+ FPS', async () => {
    await runX3Test({
      url: 'http://localhost:3000/scene.html',
      duration: 10,
      outputFile: 'ci-results.json',
      format: 'summary'
    });
    
    const results = JSON.parse(fs.readFileSync('ci-results.json'));
    expect(results.averageFPS).toBeGreaterThan(30);
  });
});

Comparative Analysis

# Test different scenes
x3test -u https://site.com/scene-v1.html -o v1-results.json -f summary
x3test -u https://site.com/scene-v2.html -o v2-results.json -f summary

# Compare results programmatically

🛠️ Advanced Usage

Custom Animation Triggers

Many X3D scenes require user interaction to start animations:

# Trigger with button click
x3test -u https://example.com/scene.html -t "#playButton"

# Trigger with custom selector
x3test -u https://example.com/scene.html -t ".animation-start"

# No trigger needed
x3test -u https://example.com/scene.html -t ""

Long-running Tests

For comprehensive performance analysis:

# 5-minute detailed test
x3test -u https://example.com/scene.html -d 300 -f detailed -o long-test.json

Batch Testing

const scenes = [
  'https://example.com/scene1.html',
  'https://example.com/scene2.html',
  'https://example.com/scene3.html'
];

for (const [index, url] of scenes.entries()) {
  await runX3Test({
    url,
    duration: 15,
    outputFile: `scene-${index + 1}-results.json`,
    format: 'summary'
  });
}

🔍 Troubleshooting

Common Issues

Scene not loading:

  • Ensure the URL is accessible
  • Check if the page contains <x3d> elements
  • Verify X3DOM is properly loaded

No animation trigger found:

  • Check if the trigger selector exists: -t "#yourSelector"
  • Use browser dev tools to verify the selector
  • Some scenes auto-start and don't need triggers

Low FPS readings:

  • This might be accurate - check scene complexity
  • Ensure hardware acceleration is enabled
  • Consider the test environment (headless browser limitations)

Node count is null:

  • X3DOM runtime might not be fully initialized
  • Try increasing the wait time before measurement
  • Verify X3DOM version compatibility

Debug Mode

For troubleshooting, you can modify the source to run in non-headless mode:

// In your local copy, modify the browser launch options
const browser = await puppeteer.launch({
  headless: false, // Set to false for debugging
  args: ["--enable-webgl", "--no-sandbox"],
});

📝 Requirements

  • Node.js: 14.0.0 or higher
  • X3DOM: Any version (tested with 1.8+)
  • Browser: Chromium-based (automatically handled by Puppeteer)

🤝 Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

Development Setup

git clone https://github.com/niknarra/X3Test.git
cd X3Test
npm install
npm test

📄 License

MIT License - see LICENSE file for details.

🔗 Links

📊 Example Outputs

Detailed Format Example

[
  {
    "second": 1,
    "fps": 59.87,
    "nodeCount": 2386
  },
  {
    "second": 2,
    "fps": 60.12,
    "nodeCount": 2390
  },
  {
    "second": 3,
    "fps": 58.94,
    "nodeCount": 2386
  }
]

Summary Format Example

{
  "scene": "AnimatedModel",
  "duration": 15,
  "fpsLog": [60, 60, 59, 57, 60, 60, 58, 59, 60, 60, 60, 59, 60, 58, 60],
  "averageFPS": 59.3,
  "nodeCount": 2322,
  "renderTimeMs": 16.7
}

Made with ❤️ for the X3D/X3DOM community