network-speed-js 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -10
- package/dist/core/speed-tester.d.ts +8 -0
- package/dist/core/speed-tester.d.ts.map +1 -1
- package/dist/core/types.d.ts +10 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/network-speed-js.js +74 -59
- package/dist/network-speed-js.umd.js +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -172,6 +172,20 @@ new NetworkSpeedSDK(options?: SpeedTestOptions)
|
|
|
172
172
|
| `autoDetect` | `boolean` | `true` | 是否自动检测内外网 |
|
|
173
173
|
| `timeout` | `number` | `10000` | 超时时间 (ms) |
|
|
174
174
|
| `thresholds` | `object` | `{fast: 10, medium: 2}` | 网速评估阈值 (Mbps) |
|
|
175
|
+
| `resourceType` | `'image' \| 'fetch'` | `'image'` | 资源类型(见下方说明) |
|
|
176
|
+
|
|
177
|
+
**resourceType 说明:**
|
|
178
|
+
|
|
179
|
+
- `'image'`(默认):使用 Image 对象加载
|
|
180
|
+
- ✅ 不受跨域限制
|
|
181
|
+
- ✅ 适用于图片资源(.jpg、.png、.webp 等)
|
|
182
|
+
- ✅ 无需服务器配置 CORS
|
|
183
|
+
- ⚠️ 仅支持图片格式
|
|
184
|
+
|
|
185
|
+
- `'fetch'`:使用 fetch API 加载
|
|
186
|
+
- ✅ 支持任意类型资源(.bin、.json、.txt 等)
|
|
187
|
+
- ⚠️ 需要服务器配置 CORS
|
|
188
|
+
- ⚠️ 受跨域限制
|
|
175
189
|
|
|
176
190
|
#### 方法
|
|
177
191
|
|
|
@@ -265,12 +279,34 @@ interface ResourceSpeedInfo {
|
|
|
265
279
|
|
|
266
280
|
## 💡 使用示例
|
|
267
281
|
|
|
268
|
-
### 1.
|
|
282
|
+
### 1. 使用图片资源测速(默认,推荐)
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
const sdk = new NetworkSpeedSDK({
|
|
286
|
+
internetUrl: 'https://cdn.example.com/test-image.jpg',
|
|
287
|
+
// resourceType: 'image', // 默认值,可省略
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
const result = await sdk.test();
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### 2. 使用非图片资源测速(需要 CORS)
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
const sdk = new NetworkSpeedSDK({
|
|
297
|
+
internetUrl: 'https://cdn.example.com/test-file.bin',
|
|
298
|
+
resourceType: 'fetch', // 使用 fetch API
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
const result = await sdk.test();
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### 3. 内外网自动检测
|
|
269
305
|
|
|
270
306
|
```typescript
|
|
271
307
|
const sdk = new NetworkSpeedSDK({
|
|
272
|
-
intranetUrl: 'https://internal-cdn.company.com/test.
|
|
273
|
-
internetUrl: 'https://public-cdn.example.com/test.
|
|
308
|
+
intranetUrl: 'https://internal-cdn.company.com/test.jpg',
|
|
309
|
+
internetUrl: 'https://public-cdn.example.com/test.jpg',
|
|
274
310
|
autoDetect: true,
|
|
275
311
|
});
|
|
276
312
|
|
|
@@ -278,7 +314,7 @@ const result = await sdk.test();
|
|
|
278
314
|
console.log(result.isIntranet ? '内网环境' : '外网环境');
|
|
279
315
|
```
|
|
280
316
|
|
|
281
|
-
###
|
|
317
|
+
### 4. 首屏加载质量评估
|
|
282
318
|
|
|
283
319
|
```typescript
|
|
284
320
|
const result = await sdk.test();
|
|
@@ -489,16 +525,18 @@ dd if=/dev/urandom of=speed-test.bin bs=1024 count=500
|
|
|
489
525
|
|
|
490
526
|
**测速文件建议:**
|
|
491
527
|
- 文件大小:200KB ~ 1MB
|
|
492
|
-
-
|
|
528
|
+
- 文件类型:
|
|
529
|
+
- 图片格式(推荐):.jpg、.png、.webp(使用默认 `resourceType: 'image'`)
|
|
530
|
+
- 其他格式:.bin、.json、.txt(需设置 `resourceType: 'fetch'` 并配置 CORS)
|
|
493
531
|
- 禁用缓存
|
|
494
|
-
- 启用 CORS
|
|
532
|
+
- 启用 CORS(仅 fetch 模式需要)
|
|
495
533
|
- 使用 CDN 分发
|
|
496
534
|
|
|
497
535
|
**支持的资源类型:**
|
|
498
|
-
- ✅
|
|
499
|
-
- ✅
|
|
500
|
-
- ✅ 文本文件(.txt、.json
|
|
501
|
-
- ✅ 任何可通过 HTTP 访问的资源
|
|
536
|
+
- ✅ 图片文件(.jpg、.png、.webp)- 默认模式,无需 CORS
|
|
537
|
+
- ✅ 二进制文件(.bin)- 需要 fetch 模式和 CORS
|
|
538
|
+
- ✅ 文本文件(.txt、.json)- 需要 fetch 模式和 CORS
|
|
539
|
+
- ✅ 任何可通过 HTTP 访问的资源 - 需要 fetch 模式和 CORS
|
|
502
540
|
|
|
503
541
|
### 配置项详解
|
|
504
542
|
|
|
@@ -18,6 +18,14 @@ export declare class SpeedTester {
|
|
|
18
18
|
* 测试单个URL
|
|
19
19
|
*/
|
|
20
20
|
private testSingleUrl;
|
|
21
|
+
/**
|
|
22
|
+
* 使用 Image 对象加载资源(默认方式,不受跨域限制)
|
|
23
|
+
*/
|
|
24
|
+
private loadWithImage;
|
|
25
|
+
/**
|
|
26
|
+
* 使用 fetch API 加载资源(需要 CORS 支持)
|
|
27
|
+
*/
|
|
28
|
+
private loadWithFetch;
|
|
21
29
|
/**
|
|
22
30
|
* 监听特定资源的性能数据
|
|
23
31
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"speed-tester.d.ts","sourceRoot":"","sources":["../../src/core/speed-tester.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,QAAQ,CAAoC;gBAExC,OAAO,GAAE,gBAAqB;
|
|
1
|
+
{"version":3,"file":"speed-tester.d.ts","sourceRoot":"","sources":["../../src/core/speed-tester.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,QAAQ,CAAoC;gBAExC,OAAO,GAAE,gBAAqB;IAW1C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,eAAe,CAAC;IAQtC;;OAEG;YACW,kBAAkB;IAehC;;OAEG;IACH,OAAO,CAAC,aAAa;IA0DrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAqBrB;;OAEG;IACH,OAAO,CAAC,aAAa;IA4BrB;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI;IAkBnF;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAIvD;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -32,6 +32,10 @@ export interface ResourceSpeedInfo {
|
|
|
32
32
|
/** 传输大小 (bytes) */
|
|
33
33
|
transferSize: number;
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* 资源类型
|
|
37
|
+
*/
|
|
38
|
+
export type ResourceType = 'image' | 'fetch';
|
|
35
39
|
/**
|
|
36
40
|
* SDK配置选项
|
|
37
41
|
*/
|
|
@@ -49,6 +53,12 @@ export interface SpeedTestOptions {
|
|
|
49
53
|
fast: number;
|
|
50
54
|
medium: number;
|
|
51
55
|
};
|
|
56
|
+
/**
|
|
57
|
+
* 资源类型
|
|
58
|
+
* - 'image': 使用 Image 对象加载(默认,不受跨域限制,适用于图片资源)
|
|
59
|
+
* - 'fetch': 使用 fetch API 加载(需要服务器支持 CORS,适用于任意资源)
|
|
60
|
+
*/
|
|
61
|
+
resourceType?: ResourceType;
|
|
52
62
|
}
|
|
53
63
|
/**
|
|
54
64
|
* Performance Observer 回调参数
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACpD,YAAY;IACZ,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB;IACpB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IACpD,YAAY;IACZ,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB;IACpB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAC1C"}
|
package/dist/network-speed-js.js
CHANGED
|
@@ -1,42 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
var h = (t, e, r) => e in t ? m(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
|
|
3
|
-
var a = (t, e, r) => h(t, typeof e != "symbol" ? e + "" : e, r);
|
|
4
|
-
function d(t) {
|
|
1
|
+
function l(t) {
|
|
5
2
|
const e = t.responseEnd - t.responseStart;
|
|
6
3
|
if (e <= 0 || t.transferSize === 0)
|
|
7
4
|
return null;
|
|
8
|
-
const
|
|
5
|
+
const s = t.transferSize * 8 / e / 1e3, n = t.transferSize / e;
|
|
9
6
|
return {
|
|
10
7
|
name: t.name,
|
|
11
|
-
speedMbps: Number(
|
|
8
|
+
speedMbps: Number(s.toFixed(2)),
|
|
12
9
|
speedKBps: Number(n.toFixed(2)),
|
|
13
10
|
downloadTime: Number(e.toFixed(2)),
|
|
14
11
|
transferSize: t.transferSize
|
|
15
12
|
};
|
|
16
13
|
}
|
|
17
|
-
function
|
|
14
|
+
function p() {
|
|
18
15
|
return performance.getEntriesByType("resource").filter(
|
|
19
16
|
(e) => e instanceof PerformanceResourceTiming && e.transferSize > 0
|
|
20
|
-
).map(
|
|
17
|
+
).map(l).filter((e) => e !== null);
|
|
21
18
|
}
|
|
22
|
-
function
|
|
19
|
+
function h(t) {
|
|
23
20
|
performance.getEntriesByName(t).forEach(() => {
|
|
24
21
|
performance.clearResourceTimings();
|
|
25
22
|
});
|
|
26
23
|
}
|
|
27
|
-
function
|
|
24
|
+
function m(t, e = { fast: 10, medium: 2 }) {
|
|
28
25
|
return t >= e.fast ? "fast" : t >= e.medium ? "medium" : t > 0 ? "slow" : "unknown";
|
|
29
26
|
}
|
|
30
|
-
class
|
|
27
|
+
class T {
|
|
28
|
+
options;
|
|
29
|
+
observer = null;
|
|
31
30
|
constructor(e = {}) {
|
|
32
|
-
a(this, "options");
|
|
33
|
-
a(this, "observer", null);
|
|
34
31
|
this.options = {
|
|
35
32
|
intranetUrl: e.intranetUrl || "",
|
|
36
33
|
internetUrl: e.internetUrl || "",
|
|
37
34
|
timeout: e.timeout || 1e4,
|
|
38
35
|
autoDetect: e.autoDetect ?? !0,
|
|
39
|
-
thresholds: e.thresholds || { fast: 10, medium: 2 }
|
|
36
|
+
thresholds: e.thresholds || { fast: 10, medium: 2 },
|
|
37
|
+
resourceType: e.resourceType || "image"
|
|
40
38
|
};
|
|
41
39
|
}
|
|
42
40
|
/**
|
|
@@ -60,57 +58,74 @@ class y {
|
|
|
60
58
|
/**
|
|
61
59
|
* 测试单个URL
|
|
62
60
|
*/
|
|
63
|
-
testSingleUrl(e,
|
|
64
|
-
return new Promise((n,
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
for (const
|
|
69
|
-
if (
|
|
70
|
-
const i =
|
|
61
|
+
testSingleUrl(e, s) {
|
|
62
|
+
return new Promise((n, o) => {
|
|
63
|
+
const r = `${e}?t=${Date.now()}`;
|
|
64
|
+
h(r);
|
|
65
|
+
const c = new PerformanceObserver((d) => {
|
|
66
|
+
for (const u of d.getEntries())
|
|
67
|
+
if (u.entryType === "resource" && u.name.includes(e)) {
|
|
68
|
+
const i = l(u);
|
|
71
69
|
if (i) {
|
|
72
|
-
const
|
|
70
|
+
const f = {
|
|
73
71
|
speedMbps: i.speedMbps,
|
|
74
72
|
speedKBps: i.speedKBps,
|
|
75
|
-
networkType:
|
|
73
|
+
networkType: m(
|
|
76
74
|
i.speedMbps,
|
|
77
75
|
this.options.thresholds
|
|
78
76
|
),
|
|
79
|
-
isIntranet:
|
|
77
|
+
isIntranet: s,
|
|
80
78
|
duration: i.downloadTime,
|
|
81
79
|
transferSize: i.transferSize,
|
|
82
80
|
resourceUrl: e
|
|
83
81
|
};
|
|
84
|
-
|
|
82
|
+
c.disconnect(), n(f);
|
|
85
83
|
}
|
|
86
84
|
}
|
|
87
85
|
});
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
86
|
+
c.observe({ entryTypes: ["resource"] });
|
|
87
|
+
const a = setTimeout(() => {
|
|
88
|
+
c.disconnect(), o(new Error(`测速超时: ${e}`));
|
|
91
89
|
}, this.options.timeout);
|
|
92
|
-
fetch(o,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
90
|
+
this.options.resourceType === "fetch" ? this.loadWithFetch(r, a, c, o) : this.loadWithImage(r, a, c, o);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 使用 Image 对象加载资源(默认方式,不受跨域限制)
|
|
95
|
+
*/
|
|
96
|
+
loadWithImage(e, s, n, o) {
|
|
97
|
+
const r = new Image();
|
|
98
|
+
r.onload = () => {
|
|
99
|
+
clearTimeout(s);
|
|
100
|
+
}, r.onerror = () => {
|
|
101
|
+
clearTimeout(s), n.disconnect(), o(new Error(`资源加载失败: ${e}`));
|
|
102
|
+
}, r.src = e;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* 使用 fetch API 加载资源(需要 CORS 支持)
|
|
106
|
+
*/
|
|
107
|
+
loadWithFetch(e, s, n, o) {
|
|
108
|
+
fetch(e, {
|
|
109
|
+
method: "GET",
|
|
110
|
+
cache: "no-store"
|
|
111
|
+
// 禁用缓存
|
|
112
|
+
}).then((r) => {
|
|
113
|
+
if (!r.ok)
|
|
114
|
+
throw new Error(`HTTP error! status: ${r.status}`);
|
|
115
|
+
return r.blob();
|
|
116
|
+
}).then(() => {
|
|
117
|
+
clearTimeout(s);
|
|
118
|
+
}).catch((r) => {
|
|
119
|
+
clearTimeout(s), n.disconnect(), o(new Error(`资源加载失败: ${r.message}`));
|
|
105
120
|
});
|
|
106
121
|
}
|
|
107
122
|
/**
|
|
108
123
|
* 监听特定资源的性能数据
|
|
109
124
|
*/
|
|
110
|
-
observeResource(e,
|
|
111
|
-
const n = new PerformanceObserver((
|
|
112
|
-
for (const
|
|
113
|
-
|
|
125
|
+
observeResource(e, s) {
|
|
126
|
+
const n = new PerformanceObserver((o) => {
|
|
127
|
+
for (const r of o.getEntries())
|
|
128
|
+
r.entryType === "resource" && r.name.includes(e) && s(r);
|
|
114
129
|
});
|
|
115
130
|
return n.observe({ entryTypes: ["resource"] }), () => n.disconnect();
|
|
116
131
|
}
|
|
@@ -127,10 +142,10 @@ class y {
|
|
|
127
142
|
this.observer && (this.observer.disconnect(), this.observer = null);
|
|
128
143
|
}
|
|
129
144
|
}
|
|
130
|
-
class
|
|
145
|
+
class y {
|
|
146
|
+
tester;
|
|
131
147
|
constructor(e = {}) {
|
|
132
|
-
|
|
133
|
-
this.tester = new y(e);
|
|
148
|
+
this.tester = new T(e);
|
|
134
149
|
}
|
|
135
150
|
/**
|
|
136
151
|
* 执行网速测试
|
|
@@ -142,13 +157,13 @@ class T {
|
|
|
142
157
|
* 获取所有已加载资源的速度信息
|
|
143
158
|
*/
|
|
144
159
|
getAllResourcesSpeeds() {
|
|
145
|
-
return
|
|
160
|
+
return p();
|
|
146
161
|
}
|
|
147
162
|
/**
|
|
148
163
|
* 监听特定资源的性能数据
|
|
149
164
|
*/
|
|
150
|
-
observeResource(e,
|
|
151
|
-
return this.tester.observeResource(e,
|
|
165
|
+
observeResource(e, s) {
|
|
166
|
+
return this.tester.observeResource(e, s);
|
|
152
167
|
}
|
|
153
168
|
/**
|
|
154
169
|
* 更新配置
|
|
@@ -163,13 +178,13 @@ class T {
|
|
|
163
178
|
this.tester.destroy();
|
|
164
179
|
}
|
|
165
180
|
}
|
|
166
|
-
function
|
|
167
|
-
return new
|
|
181
|
+
function b(t) {
|
|
182
|
+
return new y(t);
|
|
168
183
|
}
|
|
169
184
|
export {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
185
|
+
y as NetworkSpeedSDK,
|
|
186
|
+
l as calcSpeedByResource,
|
|
187
|
+
b as createNetworkSpeedSDK,
|
|
188
|
+
m as evaluateNetworkType,
|
|
189
|
+
p as getAllResourcesSpeeds
|
|
175
190
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(n,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(n=typeof globalThis<"u"?globalThis:n||self,c(n.NetworkSpeedJS={}))})(this,(function(n){"use strict";function c(t){const e=t.responseEnd-t.responseStart;if(e<=0||t.transferSize===0)return null;const s=t.transferSize*8/e/1e3,o=t.transferSize/e;return{name:t.name,speedMbps:Number(s.toFixed(2)),speedKBps:Number(o.toFixed(2)),downloadTime:Number(e.toFixed(2)),transferSize:t.transferSize}}function d(){return performance.getEntriesByType("resource").filter(e=>e instanceof PerformanceResourceTiming&&e.transferSize>0).map(c).filter(e=>e!==null)}function m(t){performance.getEntriesByName(t).forEach(()=>{performance.clearResourceTimings()})}function f(t,e={fast:10,medium:2}){return t>=e.fast?"fast":t>=e.medium?"medium":t>0?"slow":"unknown"}class S{options;observer=null;constructor(e={}){this.options={intranetUrl:e.intranetUrl||"",internetUrl:e.internetUrl||"",timeout:e.timeout||1e4,autoDetect:e.autoDetect??!0,thresholds:e.thresholds||{fast:10,medium:2},resourceType:e.resourceType||"image"}}async test(){return this.options.autoDetect?this.testWithAutoDetect():this.testSingleUrl(this.options.internetUrl,!1)}async testWithAutoDetect(){if(this.options.intranetUrl)try{return await this.testSingleUrl(this.options.intranetUrl,!0)}catch{console.log("内网测速失败,切换到外网测速")}return this.testSingleUrl(this.options.internetUrl,!1)}testSingleUrl(e,s){return new Promise((o,i)=>{const r=`${e}?t=${Date.now()}`;m(r);const a=new PerformanceObserver(T=>{for(const l of T.getEntries())if(l.entryType==="resource"&&l.name.includes(e)){const u=c(l);if(u){const w={speedMbps:u.speedMbps,speedKBps:u.speedKBps,networkType:f(u.speedMbps,this.options.thresholds),isIntranet:s,duration:u.downloadTime,transferSize:u.transferSize,resourceUrl:e};a.disconnect(),o(w)}}});a.observe({entryTypes:["resource"]});const h=setTimeout(()=>{a.disconnect(),i(new Error(`测速超时: ${e}`))},this.options.timeout);this.options.resourceType==="fetch"?this.loadWithFetch(r,h,a,i):this.loadWithImage(r,h,a,i)})}loadWithImage(e,s,o,i){const r=new Image;r.onload=()=>{clearTimeout(s)},r.onerror=()=>{clearTimeout(s),o.disconnect(),i(new Error(`资源加载失败: ${e}`))},r.src=e}loadWithFetch(e,s,o,i){fetch(e,{method:"GET",cache:"no-store"}).then(r=>{if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);return r.blob()}).then(()=>{clearTimeout(s)}).catch(r=>{clearTimeout(s),o.disconnect(),i(new Error(`资源加载失败: ${r.message}`))})}observeResource(e,s){const o=new PerformanceObserver(i=>{for(const r of i.getEntries())r.entryType==="resource"&&r.name.includes(e)&&s(r)});return o.observe({entryTypes:["resource"]}),()=>o.disconnect()}updateOptions(e){this.options={...this.options,...e}}destroy(){this.observer&&(this.observer.disconnect(),this.observer=null)}}class p{tester;constructor(e={}){this.tester=new S(e)}async test(){return this.tester.test()}getAllResourcesSpeeds(){return d()}observeResource(e,s){return this.tester.observeResource(e,s)}updateOptions(e){this.tester.updateOptions(e)}destroy(){this.tester.destroy()}}function y(t){return new p(t)}n.NetworkSpeedSDK=p,n.calcSpeedByResource=c,n.createNetworkSpeedSDK=y,n.evaluateNetworkType=f,n.getAllResourcesSpeeds=d,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "network-speed-js",
|
|
3
3
|
"private": false,
|
|
4
4
|
"description": "A framework-agnostic network speed testing SDK based on Performance API with intranet/internet auto-detection support",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.3",
|
|
6
6
|
"author": "Sunny-117",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"keywords": [
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
],
|
|
29
29
|
"exports": {
|
|
30
30
|
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
31
32
|
"import": "./dist/network-speed-js.js",
|
|
32
|
-
"require": "./dist/network-speed-js.umd.js"
|
|
33
|
-
"types": "./dist/index.d.ts"
|
|
33
|
+
"require": "./dist/network-speed-js.umd.js"
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/node": "^25.0.10",
|
|
54
|
-
"@vitejs/plugin-vue": "^
|
|
55
|
-
"typescript": "^5.
|
|
56
|
-
"vite": "^
|
|
57
|
-
"vue-tsc": "^
|
|
54
|
+
"@vitejs/plugin-vue": "^6.0.3",
|
|
55
|
+
"typescript": "^5.9.3",
|
|
56
|
+
"vite": "^7.3.1",
|
|
57
|
+
"vue-tsc": "^3.2.3"
|
|
58
58
|
},
|
|
59
59
|
"repository": {
|
|
60
60
|
"type": "git",
|