Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

detect-gpu

pmndrs2.1mMIT5.0.70TypeScript support: included

Classify GPU's based on their benchmark score in order to provide an adaptive experience.

gpu, detect, webgl, webgl2, three.js, babylonjs, three, babylon, 3d, typescript, javascript

readme

Detect GPU

npm version gzip size install size

Classifies GPUs based on their 3D rendering benchmark score allowing the developer to provide sensible default settings for graphically intensive applications. Think of it like a user-agent detection for the GPU but more powerful.

Demo

Live demo

Installation

By default we use the UNPKG CDN to host the benchmark data. If you would like to serve the benchmark data yourself download the required benchmarking data from benchmarks.tar.gz and serve it from a public directory.

Make sure you have Node.js installed.

 $ npm install detect-gpu

Usage

import { getGPUTier } from 'detect-gpu';

(async () => {
  const gpuTier = await getGPUTier();

  // Example output:
  // {
  //   "tier": 1,
  //   "isMobile": false,
  //   "type": "BENCHMARK",
  //   "fps": 21,
  //   "gpu": "intel iris graphics 6100"
  // }
})();

detect-gpu uses rendering benchmark scores (framerate, normalized by resolution) in order to determine what tier should be assigned to the user's GPU. If no WebGLContext can be created, the GPU is blocklisted or the GPU has reported to render on less than 15 fps tier: 0 is assigned. One should provide a fallback to a non-WebGL experience.

Based on the reported fps the GPU is then classified into either tier: 1 (>= 15 fps), tier: 2 (>= 30 fps) or tier: 3 (>= 60 fps). The higher the tier the more graphically intensive workload you can offer to the user.

API

getGPUTier({
  /**
   * URL of directory where benchmark data is hosted.
   *
   * @default https://unpkg.com/detect-gpu@{version}/dist/benchmarks
   */
  benchmarksURL?: string;
  /**
   * Optionally pass in a WebGL context to avoid creating a temporary one
   * internally.
   */
  glContext?: WebGLRenderingContext | WebGL2RenderingContext;
  /**
   * Whether to fail if the system performance is low or if no hardware GPU is
   * available.
   *
   * @default false
   */
  failIfMajorPerformanceCaveat?: boolean;
  /**
   * Framerate per tier for mobile devices.
   *
   * @defaultValue [0, 15, 30, 60]
   */
  mobileTiers?: number[];
  /**
   * Framerate per tier for desktop devices.
   *
   * @defaultValue [0, 15, 30, 60]
   */
  desktopTiers?: number[];
  /**
   * Optionally override specific parameters. Used mainly for testing.
   */
  override?: {
    renderer?: string;
    /**
     * Override whether device is an iPad.
     */
    isIpad?: boolean;
    /**
     * Override whether device is a mobile device.
     */
    isMobile?: boolean;
    /**
     * Override device screen size.
     */
    screenSize?: { width: number; height: number };
    /**
     * Override how benchmark data is loaded
     */
    loadBenchmarks?: (file: string) => Promise<ModelEntry[]>;
  };
})

Support

Special care has been taken to make sure all browsers that support WebGL are also supported by detect-gpu including IE 11.

Changelog

Changelog

Licence

My work is released under the MIT license.

detect-gpu uses both mobile and desktop benchmarking scores from https://gfxbench.com.

changelog

CHANGELOG

Patch version updates, unless noted otherwise, are automated benchmark updates ran weekly by our CI.

4.0.0

3.1.3

  • Build files included the wrong benchmark version number
  • Removed unused Travis build file

3.1.2 (IGNORE)

  • iPhone 12 Pro Max was being reported as iPhone 11 Pro Max due to wrong resolution in scripts/internalBenchmarkResults.ts

3.1.1

  • Return raw renderer string if WebGL renderer has been found but is not included in the benchmarks

3.1.0

  • Update README.md
  • Update benchmarks (added support for RTX 3060 / RTX 3070)
  • Fixed test suite

3.0.0

  • Fixed SSR functionality
  • Changed 'IS_SRR' tier type to 'SSR' BREAKING CHANGE
  • Fixed issue where errors were being thrown when running in non-browser environments
  • Removed undefined from return type of loadBenchmarks override

2.0.4

  • Update package.json to provide more information when published on NPM

2.0.3

  • Update README.md

2.0.2

  • Fixed package publishing issue

2.0.1

  • Fixed issue with wrong path to types in package.json

2.0.0

API

import { getGPUTier } from 'detect-gpu';

const GPUTier = getGPUTier({
  glContext: gl, // Optionally pass in a WebGL context to avoid creating a temporary one internally
  mobileBenchmarkPercentages: [0, 50, 30, 20], // (Default) [TIER_0, TIER_1, TIER_2, TIER_3]
  desktopBenchmarkPercentages: [0, 50, 30, 20], // (Default) [TIER_0, TIER_1, TIER_2, TIER_3]
  failIfMajorPerformanceCaveat: true, // (Default) Fail to detect if the WebGL implementation determines the performance would be dramatically lower than the equivalent OpenGL implementation
  forceRendererString: 'Apple A11 GPU', // (Development) Force a certain renderer string
  forceMobile: true, // (Development) Force the use of mobile benchmarking scores
});

// Example output:
// {
//   "tier": GPU_DESKTOP_TIER_1,
//   "type": "BENCHMARK - intel iris graphics 6100",
// }

turns into

import { getGPUTier } from 'detect-gpu';

(async () => {
  const gpuTier = await getGPUTier({
    benchmarksURL?: string; // (Default, "https://unpkg.com/detect-gpu@${PKG_VERSION}/dist/benchmarks") Provide location of where to access benchmark data
    failIfMajorPerformanceCaveat?: boolean; // (Default, false) Fail to detect if the WebGL implementation determines the performance would be dramatically lower than the equivalent OpenGL
    glContext?: WebGLRenderingContext | WebGL2RenderingContext; // (Default, undefined) Optionally pass in a WebGL context to avoid creating a temporary one internally
    desktopTiers?: number[]; // (Default, [0, 15, 30, 60]) Framerate per tier
    mobileTiers?: number[]; // (Default, [0, 15, 30, 60]) Framerate per tier
    override?: { // (Default, false) Override specific functionality, useful for development
      renderer?: string; // Manually override reported GPU renderer string
      isIpad?: boolean; // Manually report device as being an iPad
      isMobile?: boolean; // Manually report device as being a mobile device
      screenSize?: { width: number; height: number }; // Manually adjust reported screenSize
      loadBenchmarks?: (file: string) => Promise<TModelEntry[] | undefined>; // Optionally modify method for loading benchmark data
    };
  })

  // Example output:
  // {
  //   "tier": 1,
  //   "isMobile": false,
  //   "type": "BENCHMARK",
  //   "fps": 21,
  //   "gpu": "intel iris graphics 6100"
  // }
})();

Please note that getGPUTier now returns a Promise, this wasn't the case before.

Please note that the benchmark tier is now picked based on a resolution normalized fps instead of dividing the benchmark list into % chuncks and determining it that way.

Benchmark data

Previously the benchmark data was included inside of the detect-gpu bundle. By default we now use the benchmark data served on https://unpkg.com/detect-gpu@${pkg.version}/dist/benchmarks but you can also serve the benchmark data yourself.

This is possible by downloading benchmarks.tar.gz and serving it from a public directory on your webserver (optimal, prevents loading of redundant benchmarks) like this:

// Application
import { getGPUTier } from '../src';

(async () => {
  const data = await getGPUTier({
    benchmarksURL: '/benchmarks',
  });
})();