Skip to content

Commit 32a56ba

Browse files
Update and rebrand WASM Benchmark 1.5.0. (#35)
* Update WASM benchmark dependencies. * Update some wording. * Update some links. * Update caniuse db. * Rebranding. * Update package.json for Vite TS migration. * Some initial CRA -> Vite TS migration. * Complete migration to Vite + TS * Final tweaks. * Fix TS issue. * Remove obsolete comment. * Update document. * Update vulnerable deps (audit fix). * Remove redundant lock file. * Pin patched vulnerability. * Fix building with PUBLIC_URL.
1 parent a55be7b commit 32a56ba

31 files changed

+2414
-31615
lines changed

examples/wasm-benchmark/LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
The PSPDFKit for Web component is under a commercial license.
1+
The Nutrient Web SDK component is under a commercial license.
22
Ping [email protected] for details.
33

44
The remaining benchmark code is under MIT:

examples/wasm-benchmark/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ You can build an optimized version using the following command:
5454
PUBLIC_URL="/webassembly-benchmark/" npm run build
5555
```
5656

57-
Where `PUBLIC_URL` must be set according to the final URL, where the application is hosted.
57+
Where `PUBLIC_URL` must be set according to the final URL, where the application is hosted, so the benchmark will be available at `http://your-domain.com/webassembly-benchmark/`.
5858

5959
## Optimizations
6060

examples/wasm-benchmark/config/license-key

Whitespace-only changes.

examples/wasm-benchmark/public/index.html renamed to examples/wasm-benchmark/index.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="utf-8">
55
<title>WebAssembly Benchmark by Nutrient</title>
66
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600" rel="stylesheet">
7-
<script src="%PUBLIC_URL%/vendor/nutrient/nutrient-viewer.js"></script>
7+
<script src="%BASE_URL%/vendor/nutrient/nutrient-viewer.js"></script>
88
</head>
99
<body>
1010
<noscript>
@@ -18,8 +18,9 @@
1818
You can add webfonts, meta tags, or analytics to this file.
1919
The build step will place the bundled scripts into the <body> tag.
2020
21-
To begin the development, run `npm start` or `yarn start`.
21+
To begin the development, run `npm run dev` or `yarn dev`.
2222
To create a production bundle, use `npm run build` or `yarn build`.
2323
-->
24-
</body>
24+
<script type="module" src="/src/index.ts"></script>
25+
</body>
2526
</html>

examples/wasm-benchmark/package-lock.json

Lines changed: 2092 additions & 27919 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/wasm-benchmark/package.json

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,19 @@
22
"name": "nutrient-webassembly-benchmark",
33
"version": "1.0.0",
44
"private": true,
5+
"type": "module",
56
"engines": {
67
"npm": ">=8.3.0"
78
},
89
"dependencies": {
9-
"@nutrient-sdk/viewer": "^1.1.0",
10-
"details-polyfill": "^1.1.0",
11-
"react": "^16.4.1",
12-
"react-dom": "^16.4.1",
13-
"react-scripts": "^5.0.1"
10+
"@nutrient-sdk/viewer": "^1.5.0",
11+
"react": "^19.1.0",
12+
"react-dom": "^19.1.0"
1413
},
1514
"scripts": {
16-
"start": "react-scripts start",
17-
"build": "react-scripts build",
18-
"test": "react-scripts test --env=jsdom",
19-
"eject": "react-scripts eject"
15+
"start": "vite",
16+
"build": "tsc && vite build",
17+
"serve": "vite preview"
2018
},
2119
"browserslist": [
2220
"Firefox ESR",
@@ -28,22 +26,12 @@
2826
"safari >= 15.4",
2927
"ios_saf >= 15.4"
3028
],
31-
"overrides": {
32-
"colors": "^1.4.0",
33-
"minimist": "^1.2.6",
34-
"nth-check": "^2.0.1",
35-
"url-parse": "^1.5.9",
36-
"handlebars": "^4.7.7",
37-
"async@>= 3.0.0 < 3.2.2": "^3.2.2",
38-
"async@< 2.6.4": "^2.6.4",
39-
"loader-utils": "^2.0.4",
40-
"json5": "^2.2.2",
41-
"postcss": "^8.4.31",
42-
"rollup": "^3.29.5",
43-
"cross-spawn": "^7.0.5",
44-
"path-to-regexp": "^0.1.12",
45-
"cookie": "^0.7.0",
46-
"http-proxy-middleware": "^2.0.9",
47-
"webpack-dev-server": "^5.2.2"
29+
"devDependencies": {
30+
"@types/react": "^19.1.6",
31+
"@types/react-dom": "^19.1.6",
32+
"@vitejs/plugin-react": "^4.7.0",
33+
"typescript": "^5.0.0",
34+
"vite": "^7.0.5",
35+
"vite-tsconfig-paths": "^5.1.4"
4836
}
4937
}
Binary file not shown.

examples/wasm-benchmark/src/index.js renamed to examples/wasm-benchmark/src/index.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
1-
import "details-polyfill";
2-
31
import { createBenchmark } from "./lib/tests";
42
import { getConfigOptionsFromURL } from "./lib/utils";
53
import render from "./ui/render";
64

5+
import type NutrientViewer from "@nutrient-sdk/viewer";
6+
7+
export const NutrientWindow = window as unknown as Window & {
8+
NutrientViewer: typeof NutrientViewer,
9+
ga: any
10+
}
11+
712
// PDF to benchmark against.
8-
const PDF = "./assets/default.pdf";
13+
const PDF = import.meta.env.BASE_URL + "assets/default.pdf";
914

10-
const state = {
15+
export type AppState = {
16+
tests: Record<string, { state: string; progress: number }>;
17+
error: Error | unknown | null;
18+
state: string;
19+
nutrientScore: number;
20+
loadTimeInNutrientScore: number;
21+
document: ArrayBuffer | null;
22+
licenseKey: string | null;
23+
};
24+
25+
const state: AppState = {
1126
tests: {
1227
// We set the first test to running so we avoid a state where all is idle.
1328
"Test-Initialization": { state: "running", progress: 0 },
@@ -30,11 +45,13 @@ render(state);
3045
await fetch("./license-key").then((response) => response.text()),
3146
]);
3247

48+
console.log(licenseKey)
49+
3350
const { nutrientConfig } = getConfigOptionsFromURL();
3451

3552
const benchmark = createBenchmark(pdf, licenseKey, nutrientConfig);
3653

37-
state.pdf = pdf;
54+
state.document = pdf;
3855
state.licenseKey = licenseKey;
3956
render(state);
4057

@@ -48,7 +65,7 @@ render(state);
4865

4966
await Promise.all(preFetchAssets);
5067

51-
const score = await benchmark.run((updatedTests) => {
68+
const score = await benchmark.run((updatedTests: Record<string, { state: string; progress: number }>) => {
5269
state.tests = updatedTests;
5370
render(state);
5471
});
@@ -60,16 +77,16 @@ render(state);
6077
);
6178
render(state);
6279

63-
if (window.ga) {
64-
window.ga(
80+
if (NutrientWindow.ga) {
81+
NutrientWindow.ga(
6582
"send",
6683
"event",
6784
"wasmbench",
6885
"score",
6986
"wasm-score",
7087
state.nutrientScore,
7188
);
72-
window.ga(
89+
NutrientWindow.ga(
7390
"send",
7491
"event",
7592
"wasmbench",

examples/wasm-benchmark/src/lib/runner.js renamed to examples/wasm-benchmark/src/lib/runner.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@ import {
55
median,
66
} from "./utils";
77

8-
export function createRunner(licenseKey) {
9-
const tests = {};
8+
type TestData = {
9+
benchmarkFn: () => Promise<any>;
10+
opts: Record<string, any>;
11+
state: string;
12+
progress: number;
13+
totalTime: number;
14+
medians: Array<{ name: string; median: number }>;
15+
};
16+
17+
export function createRunner(licenseKey: string) {
18+
const tests = {} as Record<string, TestData>;
1019

1120
// Register a benchmark to test
12-
function bench(id, benchmarkFn, opts) {
13-
if (typeof opts === "undefined") {
14-
opts = {};
15-
}
16-
21+
function bench(id: string, benchmarkFn: () => Promise<any>, opts: Record<string, any> = {}) {
1722
tests[id] = {
1823
benchmarkFn,
1924
opts,
@@ -26,7 +31,7 @@ export function createRunner(licenseKey) {
2631

2732
// Run the test suite. The `onChange` callback will fire whenever the progress
2833
// of a single test is changed.
29-
async function run(onChange) {
34+
async function run(onChange: (tests: Record<string, TestData>) => void) {
3035
function notify() {
3136
onChange(tests);
3237
}
@@ -47,7 +52,7 @@ export function createRunner(licenseKey) {
4752

4853
notify();
4954

50-
const measurements = {};
55+
const measurements: Record<string, Array<{ name: string; duration: number }>> = {};
5156

5257
for (let i = 0; i < totalRuns; i++) {
5358
clearAllTimings();
@@ -56,7 +61,7 @@ export function createRunner(licenseKey) {
5661

5762
// benchmarkFn returns an array of performance measurement objects. In
5863
// a first step, we filter those results.
59-
results.forEach((result) => {
64+
results.forEach((result: any) => {
6065
const { name } = result;
6166

6267
if (!measurements[name]) {
@@ -83,7 +88,7 @@ export function createRunner(licenseKey) {
8388
// Collect all relevant timings.
8489
const medians = Object.keys(measurements).map((name) => ({
8590
name,
86-
median: median(measurements[name].map((m) => m.duration)),
91+
median: median(measurements[name].map((m: any) => m.duration)),
8792
}));
8893
const totalTime = Math.round(
8994
medians.reduce((sum, { median }) => sum + median, 0),
@@ -92,7 +97,7 @@ export function createRunner(licenseKey) {
9297
// Add the total time of the test to the final score.
9398
if (score.hasOwnProperty(opts.bucket)) {
9499
if (opts.bucket !== "load" || score.load === 0) {
95-
score[opts.bucket] += totalTime;
100+
(score as any)[opts.bucket] += totalTime;
96101
}
97102
}
98103

@@ -109,7 +114,7 @@ export function createRunner(licenseKey) {
109114
return score;
110115
}
111116

112-
function load(pdf, conf = {}) {
117+
function load(pdf: any, conf: any = {}) {
113118
const defaultConf = getConfigOptionsFromURL().nutrientConfig;
114119
const configuration = Object.assign(
115120
{
@@ -121,10 +126,10 @@ export function createRunner(licenseKey) {
121126
conf,
122127
);
123128

124-
return window.NutrientViewer.load(configuration).then((instance) => ({
129+
return (window as any).NutrientViewer.load(configuration).then((instance: any) => ({
125130
instance,
126131
unload: () => {
127-
window.NutrientViewer.unload(instance);
132+
(window as any).NutrientViewer.unload(instance);
128133
instance = null;
129134
pdf = null;
130135
},

examples/wasm-benchmark/src/lib/tests.js renamed to examples/wasm-benchmark/src/lib/tests.ts

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import { NutrientWindow } from "..";
12
import { createRunner } from "./runner";
23
import { clearAllTimings, isMobileOS, isWasmSupported } from "./utils";
34

4-
export function createBenchmark(pdf, licenseKey, conf) {
5+
export function createBenchmark(pdf: any, licenseKey: any, conf: any) {
56
// Factory to create our test suite. It will register all tests in the runner.
67
const isWasm = isWasmSupported()
78

@@ -11,13 +12,13 @@ export function createBenchmark(pdf, licenseKey, conf) {
1112
"Test-Rendering",
1213
async () => {
1314
const instance = await prepareInstance();
14-
const totalPageCount = instance.totalPageCount;
15+
const totalPageCount = (instance as any).totalPageCount;
1516

1617
const promises = [];
1718

1819
for (let pageIndex = 0; pageIndex < totalPageCount; pageIndex++) {
1920
promises.push(
20-
instance.renderPageAsArrayBuffer({ height: 1024 }, pageIndex),
21+
(instance as any).renderPageAsArrayBuffer({ height: 1024 }, pageIndex),
2122
);
2223
}
2324

@@ -47,7 +48,7 @@ export function createBenchmark(pdf, licenseKey, conf) {
4748
const promises = [];
4849

4950
for (let i = 0; i < 50; i++) {
50-
promises.push(instance.search("the"));
51+
promises.push((instance as any).search("the"));
5152
}
5253

5354
performance.mark("searchStart");
@@ -71,12 +72,12 @@ export function createBenchmark(pdf, licenseKey, conf) {
7172

7273
performance.mark("exportStart");
7374
await Promise.all([
74-
instance.exportPDF(),
75-
instance.exportPDF(),
76-
instance.exportPDF({ flatten: true }),
77-
instance.exportPDF({ flatten: true }),
78-
instance.exportXFDF(),
79-
instance.exportXFDF(),
75+
(instance as any).exportPDF(),
76+
(instance as any).exportPDF(),
77+
(instance as any).exportPDF({ flatten: true }),
78+
(instance as any).exportPDF({ flatten: true }),
79+
(instance as any).exportXFDF(),
80+
(instance as any).exportXFDF(),
8081
]);
8182
performance.mark("exportEnd");
8283

@@ -95,10 +96,10 @@ export function createBenchmark(pdf, licenseKey, conf) {
9596
async () => {
9697
const instance = await prepareInstance();
9798

98-
const annotation = new window.NutrientViewer.Annotations.TextAnnotation({
99+
const annotation = new NutrientWindow.NutrientViewer.Annotations.TextAnnotation({
99100
pageIndex: 0,
100101
text: { format: "plain", value: "test" },
101-
boundingBox: new window.NutrientViewer.Geometry.Rect({
102+
boundingBox: new NutrientWindow.NutrientViewer.Geometry.Rect({
102103
width: 200,
103104
height: 30,
104105
}),
@@ -108,15 +109,15 @@ export function createBenchmark(pdf, licenseKey, conf) {
108109
performance.mark("createAnnotationStart");
109110

110111
const annotations = (
111-
await Promise.all(range.map(() => instance.create(annotation)))
112-
).map((createdAnnotations) => createdAnnotations[0]);
112+
await Promise.all(range.map(() => (instance as any).create(annotation)))
113+
).map((createdAnnotations: any) => createdAnnotations[0]);
113114

114115
// Nutrient Web SDK will only write annotations back to the PDF when it
115116
// has to. To make sure this is happening, we profile the exportPDF
116117
// endpoint.
117-
await instance.exportPDF();
118+
await (instance as any).exportPDF();
118119

119-
await Promise.all(annotations.map((a) => instance.delete(a.id)));
120+
await Promise.all(annotations.map((a: any) => (instance as any).delete(a.id)));
120121

121122
performance.mark("createAnnotationEnd");
122123

@@ -158,8 +159,8 @@ export function createBenchmark(pdf, licenseKey, conf) {
158159

159160
// We want to reuse the instance in the following tests. To achieve this, we
160161
// store it in the function closure.
161-
let instance;
162-
let unload;
162+
let instance: any | null = null;
163+
let unload: any | null = null;
163164

164165
async function prepareInstance(canReuseLastOne = true, clearTimings = true) {
165166
if (!canReuseLastOne) {
@@ -184,13 +185,15 @@ export function createBenchmark(pdf, licenseKey, conf) {
184185
// regular.
185186
//
186187
// This will always return at least one.
187-
function scaleRuns(runs) {
188-
const params = {};
188+
function scaleRuns(runs: number) {
189+
const params = {} as Record<string, string>;
189190

190-
window.location.search
191+
NutrientWindow.location.search
191192
.substring(1)
192-
.replace(/([^=&]+)=([^&]*)/g, (m, key, value) => {
193+
.replace(/([^=&]+)=([^&]*)/g, (m: string, key: string, value: string) => {
193194
params[decodeURIComponent(key)] = decodeURIComponent(value);
195+
196+
return "";
194197
});
195198

196199
let runsScaleFactor = 1;

0 commit comments

Comments
 (0)