@be-link/cls-logger 1.0.1-beta.24 → 1.0.1-beta.26

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/dist/web.js CHANGED
@@ -3,7 +3,6 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var tencentcloudClsSdkJsWeb = require('tencentcloud-cls-sdk-js-web');
6
- var webVitals = require('web-vitals');
7
6
 
8
7
  function _interopNamespaceDefault(e) {
9
8
  var n = Object.create(null);
@@ -1488,10 +1487,14 @@ function getPagePath() {
1488
1487
  return '';
1489
1488
  }
1490
1489
  }
1491
- /**
1492
- * 安装浏览器性能监控
1493
- * 使用 Google web-vitals 库实现 Core Web Vitals 指标采集
1494
- */
1490
+ function reportMetric(report, reportType, metric, value, extra = {}) {
1491
+ report(reportType, {
1492
+ pagePath: getPagePath(),
1493
+ metric,
1494
+ value,
1495
+ ...extra,
1496
+ });
1497
+ }
1495
1498
  function installBrowserPerformanceMonitor(report, options) {
1496
1499
  if (typeof window === 'undefined')
1497
1500
  return;
@@ -1500,100 +1503,145 @@ function installBrowserPerformanceMonitor(report, options) {
1500
1503
  return;
1501
1504
  w.__beLinkClsLoggerPerfInstalled__ = true;
1502
1505
  const ignoreUrls = [...DEFAULT_IGNORE, ...(options.ignoreUrls ?? [])];
1503
- // Web Vitals: 使用 Google web-vitals 库
1504
- // 这个库会自动处理:
1505
- // - LCP 在用户交互后停止观察
1506
- // - firstHiddenTime 过滤(页面隐藏后的数据不计入)
1507
- // - CLS 5秒会话窗口算法
1508
- // - BFCache 恢复时自动重置指标
1509
- if (options.webVitals) {
1510
- // FCP
1506
+ // Navigation timing: TTFB
1507
+ if (options.navigationTiming) {
1511
1508
  try {
1512
- webVitals.onFCP((metric) => {
1513
- report(options.reportType, {
1514
- pagePath: getPagePath(),
1515
- metric: 'FCP',
1516
- value: metric.value,
1517
- unit: 'ms',
1518
- rating: metric.rating,
1519
- id: metric.id,
1520
- navigationType: metric.navigationType,
1521
- });
1522
- });
1509
+ const navEntries = performance.getEntriesByType?.('navigation');
1510
+ const nav = Array.isArray(navEntries) ? navEntries[0] : undefined;
1511
+ if (nav && typeof nav === 'object') {
1512
+ const ttfb = typeof nav.responseStart === 'number' && typeof nav.requestStart === 'number'
1513
+ ? nav.responseStart - nav.requestStart
1514
+ : -1;
1515
+ if (ttfb >= 0 && sampleHit(options.sampleRate))
1516
+ reportMetric(report, options.reportType, 'TTFB', ttfb, { unit: 'ms' });
1517
+ }
1523
1518
  }
1524
1519
  catch {
1525
1520
  // ignore
1526
1521
  }
1527
- // LCP(自动处理用户交互后停止)
1522
+ }
1523
+ // Web Vitals: FCP/LCP/CLS/FID
1524
+ if (options.webVitals && typeof globalThis.PerformanceObserver === 'function') {
1525
+ // FCP
1528
1526
  try {
1529
- webVitals.onLCP((metric) => {
1530
- report(options.reportType, {
1531
- pagePath: getPagePath(),
1532
- metric: 'LCP',
1533
- value: metric.value,
1534
- unit: 'ms',
1535
- rating: metric.rating,
1536
- id: metric.id,
1537
- navigationType: metric.navigationType,
1538
- });
1527
+ const po = new PerformanceObserver((list) => {
1528
+ try {
1529
+ if (!sampleHit(options.sampleRate))
1530
+ return;
1531
+ for (const entry of list.getEntries()) {
1532
+ if (entry?.name === 'first-contentful-paint' && typeof entry.startTime === 'number') {
1533
+ reportMetric(report, options.reportType, 'FCP', entry.startTime, { unit: 'ms' });
1534
+ }
1535
+ }
1536
+ }
1537
+ catch {
1538
+ // ignore
1539
+ }
1539
1540
  });
1541
+ po.observe({ type: 'paint', buffered: true });
1540
1542
  }
1541
1543
  catch {
1542
1544
  // ignore
1543
1545
  }
1544
- // CLS(自动处理会话窗口)
1546
+ // LCP(最后一次为准)
1547
+ let lastLcp = null;
1545
1548
  try {
1546
- webVitals.onCLS((metric) => {
1547
- report(options.reportType, {
1548
- pagePath: getPagePath(),
1549
- metric: 'CLS',
1550
- value: metric.value,
1551
- unit: 'score',
1552
- rating: metric.rating,
1553
- id: metric.id,
1554
- navigationType: metric.navigationType,
1555
- });
1549
+ const po = new PerformanceObserver((list) => {
1550
+ try {
1551
+ const entries = list.getEntries();
1552
+ if (entries && entries.length)
1553
+ lastLcp = entries[entries.length - 1];
1554
+ }
1555
+ catch {
1556
+ // ignore
1557
+ }
1556
1558
  });
1559
+ po.observe({ type: 'largest-contentful-paint', buffered: true });
1560
+ const flushLcp = () => {
1561
+ try {
1562
+ if (!lastLcp)
1563
+ return;
1564
+ if (!sampleHit(options.sampleRate))
1565
+ return;
1566
+ if (typeof lastLcp.startTime === 'number')
1567
+ reportMetric(report, options.reportType, 'LCP', lastLcp.startTime, { unit: 'ms' });
1568
+ lastLcp = null;
1569
+ }
1570
+ catch {
1571
+ // ignore
1572
+ }
1573
+ };
1574
+ window.addEventListener('pagehide', flushLcp, { once: true });
1575
+ document.addEventListener('visibilitychange', () => {
1576
+ if (document.visibilityState === 'hidden')
1577
+ flushLcp();
1578
+ }, { once: true });
1557
1579
  }
1558
1580
  catch {
1559
1581
  // ignore
1560
1582
  }
1561
- // INP(替代 FID,2024年3月起成为核心指标)
1583
+ // CLS
1562
1584
  try {
1563
- webVitals.onINP((metric) => {
1564
- report(options.reportType, {
1565
- pagePath: getPagePath(),
1566
- metric: 'INP',
1567
- value: metric.value,
1568
- unit: 'ms',
1569
- rating: metric.rating,
1570
- id: metric.id,
1571
- navigationType: metric.navigationType,
1572
- });
1585
+ let clsValue = 0;
1586
+ const po = new PerformanceObserver((list) => {
1587
+ try {
1588
+ for (const entry of list.getEntries()) {
1589
+ if (entry && entry.hadRecentInput)
1590
+ continue;
1591
+ if (typeof entry.value === 'number')
1592
+ clsValue += entry.value;
1593
+ }
1594
+ }
1595
+ catch {
1596
+ // ignore
1597
+ }
1573
1598
  });
1599
+ po.observe({ type: 'layout-shift', buffered: true });
1600
+ const flushCls = () => {
1601
+ try {
1602
+ if (!sampleHit(options.sampleRate))
1603
+ return;
1604
+ reportMetric(report, options.reportType, 'CLS', clsValue, { unit: 'score' });
1605
+ }
1606
+ catch {
1607
+ // ignore
1608
+ }
1609
+ };
1610
+ window.addEventListener('pagehide', flushCls, { once: true });
1611
+ document.addEventListener('visibilitychange', () => {
1612
+ if (document.visibilityState === 'hidden')
1613
+ flushCls();
1614
+ }, { once: true });
1574
1615
  }
1575
1616
  catch {
1576
1617
  // ignore
1577
1618
  }
1578
- // TTFB
1619
+ // FID
1579
1620
  try {
1580
- webVitals.onTTFB((metric) => {
1581
- report(options.reportType, {
1582
- pagePath: getPagePath(),
1583
- metric: 'TTFB',
1584
- value: metric.value,
1585
- unit: 'ms',
1586
- rating: metric.rating,
1587
- id: metric.id,
1588
- navigationType: metric.navigationType,
1589
- });
1621
+ const po = new PerformanceObserver((list) => {
1622
+ try {
1623
+ if (!sampleHit(options.sampleRate))
1624
+ return;
1625
+ for (const entry of list.getEntries()) {
1626
+ const startTime = typeof entry.startTime === 'number' ? entry.startTime : -1;
1627
+ const processingStart = typeof entry.processingStart === 'number' ? entry.processingStart : -1;
1628
+ if (startTime >= 0 && processingStart >= 0) {
1629
+ reportMetric(report, options.reportType, 'FID', processingStart - startTime, { unit: 'ms' });
1630
+ break;
1631
+ }
1632
+ }
1633
+ }
1634
+ catch {
1635
+ // ignore
1636
+ }
1590
1637
  });
1638
+ po.observe({ type: 'first-input', buffered: true });
1591
1639
  }
1592
1640
  catch {
1593
1641
  // ignore
1594
1642
  }
1595
1643
  }
1596
- // Resource timing:资源加载耗时(web-vitals 不包含此功能,保留原有实现)
1644
+ // Resource timing:资源加载耗时
1597
1645
  if (options.resourceTiming && typeof globalThis.PerformanceObserver === 'function') {
1598
1646
  try {
1599
1647
  const po = new PerformanceObserver((list) => {
@@ -1678,6 +1726,7 @@ function installWebPerformanceMonitor(report, opts = {}) {
1678
1726
  sampleRate: raw.sampleRate ?? 1,
1679
1727
  ignoreUrls: raw.ignoreUrls ?? [],
1680
1728
  webVitals: raw.webVitals ?? true,
1729
+ navigationTiming: raw.navigationTiming ?? true,
1681
1730
  resourceTiming: raw.resourceTiming ?? true,
1682
1731
  maxTextLength: raw.maxTextLength ?? 2000,
1683
1732
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@be-link/cls-logger",
3
- "version": "1.0.1-beta.24",
3
+ "version": "1.0.1-beta.26",
4
4
  "description": "@be-link cls-logger - 腾讯云 CLS 日志上报封装",
5
5
  "homepage": "https://github.com/snowmountain-top/be-link",
6
6
  "author": "zhuiyi",
@@ -45,8 +45,7 @@
45
45
  ],
46
46
  "dependencies": {
47
47
  "tencentcloud-cls-sdk-js-web": "^1.0.11",
48
- "tencentcloud-cls-sdk-js-mini": "^1.0.3",
49
- "web-vitals": "^5.1.0"
48
+ "tencentcloud-cls-sdk-js-mini": "^1.0.3"
50
49
  },
51
50
  "devDependencies": {
52
51
  "rimraf": "^5.0.0",