",
+ "nodeLabel": "div.css-0 > div.css-0 > div.css-or7k2a > div.css-wp059z"
+ }
+ ]
+ },
+ "guidanceLevel": 3,
+ "replacesAudits": [
+ "largest-contentful-paint-element"
+ ]
+ },
+ "lcp-discovery-insight": {
+ "id": "lcp-discovery-insight",
+ "title": "LCP request discovery",
+ "description": "Optimize LCP by making the LCP image [discoverable](https://web.dev/articles/optimize-lcp#1_eliminate_resource_load_delay) from the HTML immediately, and [avoiding lazy-loading](https://web.dev/articles/lcp-lazy-loading)",
+ "score": 0,
+ "scoreDisplayMode": "numeric",
+ "metricSavings": {
+ "LCP": 0
+ },
+ "details": {
+ "type": "list",
+ "items": [
+ {
+ "type": "checklist",
+ "items": {
+ "priorityHinted": {
+ "label": "fetchpriority=high should be applied",
+ "value": false
+ },
+ "requestDiscoverable": {
+ "label": "Request is discoverable in initial document",
+ "value": false
+ },
+ "eagerlyLoaded": {
+ "label": "lazy load not applied",
+ "value": true
+ }
+ }
+ },
+ {
+ "type": "node",
+ "lhId": "page-0-DIV",
+ "path": "2,HTML,1,BODY,1,DIV,0,DIV,0,DIV,1,DIV,0,DIV,0,DIV,0,DIV",
+ "selector": "div.css-0 > div.css-0 > div.css-or7k2a > div.css-wp059z",
+ "boundingRect": {
+ "top": 65,
+ "bottom": 1965,
+ "left": 206,
+ "right": 412,
+ "width": 206,
+ "height": 1900
+ },
+ "snippet": "
",
+ "nodeLabel": "div.css-0 > div.css-0 > div.css-or7k2a > div.css-wp059z"
+ }
+ ]
+ },
+ "guidanceLevel": 3,
+ "replacesAudits": [
+ "prioritize-lcp-image",
+ "lcp-lazy-loaded"
+ ]
+ },
+ "legacy-javascript-insight": {
+ "id": "legacy-javascript-insight",
+ "title": "Legacy JavaScript",
+ "description": "Polyfills and transforms enable older browsers to use new JavaScript features. However, many aren't necessary for modern browsers. Consider modifying your JavaScript build process to not transpile [Baseline](https://web.dev/articles/baseline-and-polyfills) features, unless you know you must support older browsers. [Learn why most sites can deploy ES6+ code without transpiling](https://philipwalton.com/articles/the-state-of-es5-on-the-web/)",
+ "score": 1,
+ "scoreDisplayMode": "metricSavings",
+ "metricSavings": {
+ "FCP": 0,
+ "LCP": 0
+ },
+ "details": {
+ "type": "table",
+ "headings": [
+ {
+ "key": "url",
+ "valueType": "url",
+ "subItemsHeading": {
+ "key": "location",
+ "valueType": "source-location"
+ },
+ "label": "URL"
+ },
+ {
+ "key": null,
+ "valueType": "code",
+ "subItemsHeading": {
+ "key": "signal"
+ },
+ "label": ""
+ },
+ {
+ "key": "wastedBytes",
+ "valueType": "bytes",
+ "label": "Wasted bytes"
+ }
+ ],
+ "items": [],
+ "debugData": {
+ "type": "debugdata",
+ "wastedBytes": 0
+ }
+ },
+ "guidanceLevel": 2
+ },
+ "modern-http-insight": {
+ "id": "modern-http-insight",
+ "title": "Modern HTTP",
+ "description": "HTTP/2 and HTTP/3 offer many benefits over HTTP/1.1, such as multiplexing. [Learn more about using modern HTTP](https://developer.chrome.com/docs/lighthouse/best-practices/uses-http2/).",
+ "score": 0.5,
+ "scoreDisplayMode": "metricSavings",
+ "metricSavings": {
+ "FCP": 0,
+ "LCP": 0
+ },
+ "details": {
+ "type": "table",
+ "headings": [
+ {
+ "key": "url",
+ "valueType": "url",
+ "label": "URL"
+ },
+ {
+ "key": "protocol",
+ "valueType": "text",
+ "label": "Protocol"
+ }
+ ],
+ "items": [
+ {
+ "url": "https://app.valuefrontier.cn/embed.min.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/chatbot/DwN8qAKtYFQtWskM?",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/64f9f179dbdcd998.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/a01885eb9d0649e5.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/bf38d9b349c92e2b.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/9e90e05c5cca6fcc.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/054994666d6806c5.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/webpack-38776d00203f938f.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/7b1f872c-c7e4e33c66cbdc9b.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/86480-b7209753f46ad59b.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/main-app-376f7cb43c26ed4c.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/77ab3b1e-92323a26522690cf.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/26423-9886dec07285c629.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/25552-24c21834bb9ce7f8.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/37008-dd800aa6e6be46e0.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/78639-954f132e09b0bd1d.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/app/(shareLayout)/layout-c7f89e27cf4215d6.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/1ae6eb87-095b6bb2b10e3fd4.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/bda40ab4-465678c6543fde64.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/fc43f782-c8f021bc75fb0f3a.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/75146d7d-fa11a4a6b704c1e9.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/f707c8ea-09423c24a938b7e9.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/adeb31b9-c8c57fad1a5d9920.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/1471f7b3-e1e02f7c4f787f79.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/05417924-0ecf2eadee09cca3.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/4701-3e6d8f235ac58458.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/42776-f08ceab89e5c9f79.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/67178-7738e8785ac3bf1d.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/82427-2c350ac2f33216e0.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/94575-56ee7d594c07f3ac.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/3365-667dcbd31ae8d940.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/75355-3adda07b8a231ae7.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/62632-8f174dd809645249.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/94486-db318921118f62c7.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/67800-076894cf02c647d3.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/19077-e5953bb35a9231eb.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/7895-7e94e2390e12ae57.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/43853-cd3a8ce8f61ef955.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/2360-5fce6327abc41446.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/83879-ddb8796acc954a33.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/88313-976b1a7475221924.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/72247-0f896dd1b92db30f.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/80172-6a3bd1d0c5fa7c8f.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/7451-86904548ba9339ca.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/57349-e362f628f036d21a.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/12011-b60a150a91df71b2.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/26408-fbf397c3ba35f15f.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/98615-99a419845e7d310e.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/64713-66ed16203b06a50a.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/81709-f648d574ebc3712f.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/29946-4716e565c15a4b42.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/69872-0946d84d22ddfeca.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/1504-d278e1a5d4d3c34c.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/15836-9828ebd31169edd1.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/34876-f521aa67cccbe648.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/59440-5c0ebe08cb85eb15.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/70346-1dd9d11dd0937896.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/2462-613d5ea523a1e5b0.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/62579-0a9996c02bc9fd5a.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/40630-e341f8f01b43f98e.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/29412-f2e28fe1350bde1b.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/21797-e76fe60bb4637732.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/49856-077719ab20996c3f.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/52360-8e10f445240de61a.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/82723-4056891612c8cfbd.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/app/(shareLayout)/chatbot/%5Btoken%5D/page-dcc37d69b6429671.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/0b8e744a-9783aef562d7021e.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/77220-4cbfba5a4b531158.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/chunks/app/layout-fa922e5f2d3ab09d.js",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/220a772cfe3c95f4.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/2f7a6ecf4e344b75.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/2da23e89afd44708.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/c31a5eb4ac1ad018.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/b7247e8b4219ed3e.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/5bb43505df05adfe.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/_next/static/css/a031600822501d72.css",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/console/api/system-features",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/api/webapp/access-mode?appCode=DwN8qAKtYFQtWskM",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/api/passport?",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/api/parameters",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/api/site",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/api/meta",
+ "protocol": "http/1.1"
+ },
+ {
+ "url": "https://app.valuefrontier.cn/logo/logo.svg",
+ "protocol": "http/1.1"
+ }
+ ]
+ },
+ "guidanceLevel": 3
+ },
+ "network-dependency-tree-insight": {
+ "id": "network-dependency-tree-insight",
+ "title": "Network dependency tree",
+ "description": "[Avoid chaining critical requests](https://developer.chrome.com/docs/lighthouse/performance/critical-request-chains) by reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load.",
+ "score": 0,
+ "scoreDisplayMode": "numeric",
+ "metricSavings": {
+ "LCP": 0
+ },
+ "details": {
+ "type": "list",
+ "items": [
+ {
+ "type": "list-section",
+ "value": {
+ "type": "network-tree",
+ "chains": {
+ "E16586C47343422178C1012FC3029684": {
+ "url": "http://localhost:3000/home",
+ "navStartToEndTime": 55,
+ "transferSize": 2536,
+ "isLongest": true,
+ "children": {
+ "96081.8": {
+ "url": "http://49.232.185.254:5001/api/auth/session",
+ "navStartToEndTime": 5848,
+ "transferSize": 585,
+ "isLongest": true,
+ "children": {}
+ },
+ "96081.9": {
+ "url": "http://49.232.185.254:5001/api/auth/session",
+ "navStartToEndTime": 4226,
+ "transferSize": 585,
+ "children": {}
+ }
+ }
+ }
+ },
+ "longestChain": {
+ "duration": 5848
+ }
+ }
+ },
+ {
+ "type": "list-section",
+ "title": "Preconnected origins",
+ "description": "[preconnect](https://developer.chrome.com/docs/lighthouse/performance/uses-rel-preconnect/) hints help the browser establish a connection earlier in the page load, saving time when the first request for that origin is made. The following are the origins that the page preconnected to.",
+ "value": {
+ "type": "text",
+ "value": "no origins were preconnected"
+ }
+ },
+ {
+ "type": "list-section",
+ "title": "Preconnect candidates",
+ "description": "Add [preconnect](https://developer.chrome.com/docs/lighthouse/performance/uses-rel-preconnect/) hints to your most important origins, but try to use no more than 4.",
+ "value": {
+ "type": "text",
+ "value": "No additional origins are good candidates for preconnecting"
+ }
+ }
+ ]
+ },
+ "guidanceLevel": 1,
+ "replacesAudits": [
+ "critical-request-chains",
+ "uses-rel-preconnect"
+ ]
+ },
+ "render-blocking-insight": {
+ "id": "render-blocking-insight",
+ "title": "Render blocking requests",
+ "description": "Requests are blocking the page's initial render, which may delay LCP. [Deferring or inlining](https://web.dev/learn/performance/understanding-the-critical-path#render-blocking_resources) can move these network requests out of the critical path.",
+ "score": 1,
+ "scoreDisplayMode": "metricSavings",
+ "metricSavings": {
+ "FCP": 0,
+ "LCP": 0
+ },
+ "details": {
+ "type": "table",
+ "headings": [
+ {
+ "key": "url",
+ "valueType": "url",
+ "label": "URL"
+ },
+ {
+ "key": "totalBytes",
+ "valueType": "bytes",
+ "label": "Transfer Size"
+ },
+ {
+ "key": "wastedMs",
+ "valueType": "timespanMs",
+ "label": "Duration"
+ }
+ ],
+ "items": []
+ },
+ "guidanceLevel": 3,
+ "replacesAudits": [
+ "render-blocking-resources"
+ ]
+ },
+ "third-parties-insight": {
+ "id": "third-parties-insight",
+ "title": "3rd parties",
+ "description": "3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/) to prioritize your page's content.",
+ "score": null,
+ "scoreDisplayMode": "error",
+ "errorMessage": "Maximum call stack size exceeded",
+ "errorStack": "RangeError: Maximum call stack size exceeded\n at getRelatedEvents (file:///usr/local/lib/node_modules/lighthouse/node_modules/@paulirish/trace_engine/models/trace/insights/ThirdParties.js:35:27)\n at Module.generateInsight (file:///usr/local/lib/node_modules/lighthouse/node_modules/@paulirish/trace_engine/models/trace/insights/ThirdParties.js:59:24)\n at #computeInsightSet (file:///usr/local/lib/node_modules/lighthouse/node_modules/@paulirish/trace_engine/models/trace/Processor.js:391:33)\n at #computeInsightsForNavigation (file:///usr/local/lib/node_modules/lighthouse/node_modules/@paulirish/trace_engine/models/trace/Processor.js:533:32)\n at #computeInsights (file:///usr/local/lib/node_modules/lighthouse/node_modules/@paulirish/trace_engine/models/trace/Processor.js:467:47)\n at TraceProcessor.parse (file:///usr/local/lib/node_modules/lighthouse/node_modules/@paulirish/trace_engine/models/trace/Processor.js:122:38)\n at async TraceEngineResult.runTraceEngine (file:///usr/local/lib/node_modules/lighthouse/core/computed/trace-engine-result.js:42:5)\n at async TraceEngineResult.compute_ (file:///usr/local/lib/node_modules/lighthouse/core/computed/trace-engine-result.js:254:7)",
+ "guidanceLevel": 3,
+ "replacesAudits": [
+ "third-party-summary"
+ ]
+ },
+ "viewport-insight": {
+ "id": "viewport-insight",
+ "title": "Optimize viewport for mobile",
+ "description": "Tap interactions may be [delayed by up to 300 ms](https://developer.chrome.com/blog/300ms-tap-delay-gone-away/) if the viewport is not optimized for mobile.",
+ "score": 1,
+ "scoreDisplayMode": "numeric",
+ "metricSavings": {
+ "INP": 0
+ },
+ "details": {
+ "type": "table",
+ "headings": [
+ {
+ "key": "node",
+ "valueType": "node",
+ "label": ""
+ }
+ ],
+ "items": [
+ {
+ "node": {
+ "type": "node",
+ "lhId": "page-2-META",
+ "path": "2,HTML,0,HEAD,1,META",
+ "selector": "head > meta",
+ "boundingRect": {
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ },
+ "snippet": "
",
+ "nodeLabel": "head > meta"
+ }
+ }
+ ]
+ },
+ "guidanceLevel": 3,
+ "replacesAudits": [
+ "viewport"
+ ]
+ }
+ },
+ "configSettings": {
+ "output": [
+ "json"
+ ],
+ "maxWaitForFcp": 30000,
+ "maxWaitForLoad": 45000,
+ "pauseAfterFcpMs": 1000,
+ "pauseAfterLoadMs": 1000,
+ "networkQuietThresholdMs": 1000,
+ "cpuQuietThresholdMs": 1000,
+ "formFactor": "mobile",
+ "throttling": {
+ "rttMs": 150,
+ "throughputKbps": 1638.4,
+ "requestLatencyMs": 562.5,
+ "downloadThroughputKbps": 1474.5600000000002,
+ "uploadThroughputKbps": 675,
+ "cpuSlowdownMultiplier": 4
+ },
+ "throttlingMethod": "simulate",
+ "screenEmulation": {
+ "mobile": true,
+ "width": 412,
+ "height": 823,
+ "deviceScaleFactor": 1.75,
+ "disabled": false
+ },
+ "emulatedUserAgent": "Mozilla/5.0 (Linux; Android 11; moto g power (2022)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36",
+ "auditMode": false,
+ "gatherMode": false,
+ "clearStorageTypes": [
+ "file_systems",
+ "shader_cache",
+ "service_workers",
+ "cache_storage"
+ ],
+ "disableStorageReset": false,
+ "debugNavigation": false,
+ "channel": "cli",
+ "usePassiveGathering": false,
+ "disableFullPageScreenshot": false,
+ "skipAboutBlank": false,
+ "blankPage": "about:blank",
+ "ignoreStatusCode": false,
+ "locale": "en-US",
+ "blockedUrlPatterns": null,
+ "additionalTraceCategories": null,
+ "extraHeaders": null,
+ "precomputedLanternData": null,
+ "onlyAudits": null,
+ "onlyCategories": [
+ "performance"
+ ],
+ "skipAudits": null
+ },
+ "categories": {
+ "performance": {
+ "title": "Performance",
+ "supportedModes": [
+ "navigation",
+ "timespan",
+ "snapshot"
+ ],
+ "auditRefs": [
+ {
+ "id": "first-contentful-paint",
+ "weight": 10,
+ "group": "metrics",
+ "acronym": "FCP"
+ },
+ {
+ "id": "largest-contentful-paint",
+ "weight": 25,
+ "group": "metrics",
+ "acronym": "LCP"
+ },
+ {
+ "id": "total-blocking-time",
+ "weight": 30,
+ "group": "metrics",
+ "acronym": "TBT"
+ },
+ {
+ "id": "cumulative-layout-shift",
+ "weight": 25,
+ "group": "metrics",
+ "acronym": "CLS"
+ },
+ {
+ "id": "speed-index",
+ "weight": 10,
+ "group": "metrics",
+ "acronym": "SI"
+ },
+ {
+ "id": "cache-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "cls-culprits-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "document-latency-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "dom-size-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "duplicated-javascript-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "font-display-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "forced-reflow-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "image-delivery-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "inp-breakdown-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "lcp-breakdown-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "lcp-discovery-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "legacy-javascript-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "modern-http-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "network-dependency-tree-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "render-blocking-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "third-parties-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "viewport-insight",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "interactive",
+ "weight": 0,
+ "group": "hidden",
+ "acronym": "TTI"
+ },
+ {
+ "id": "max-potential-fid",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "first-meaningful-paint",
+ "weight": 0,
+ "acronym": "FMP",
+ "group": "hidden"
+ },
+ {
+ "id": "render-blocking-resources",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "uses-responsive-images",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "offscreen-images",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "unminified-css",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "unminified-javascript",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "unused-css-rules",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "unused-javascript",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "uses-optimized-images",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "modern-image-formats",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "uses-text-compression",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "uses-rel-preconnect",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "server-response-time",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "redirects",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "uses-http2",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "efficient-animated-content",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "duplicated-javascript",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "legacy-javascript",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "prioritize-lcp-image",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "total-byte-weight",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "uses-long-cache-ttl",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "dom-size",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "critical-request-chains",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "user-timings",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "bootup-time",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "mainthread-work-breakdown",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "font-display",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "third-party-summary",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "third-party-facades",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "largest-contentful-paint-element",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "lcp-lazy-loaded",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "layout-shifts",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "uses-passive-event-listeners",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "no-document-write",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "long-tasks",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "non-composited-animations",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "unsized-images",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "viewport",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "bf-cache",
+ "weight": 0,
+ "group": "diagnostics"
+ },
+ {
+ "id": "network-requests",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "network-rtt",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "network-server-latency",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "main-thread-tasks",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "diagnostics",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "metrics",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "screenshot-thumbnails",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "final-screenshot",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "script-treemap-data",
+ "weight": 0,
+ "group": "hidden"
+ },
+ {
+ "id": "resource-summary",
+ "weight": 0,
+ "group": "hidden"
+ }
+ ],
+ "id": "performance",
+ "score": 0.41
+ }
+ },
+ "categoryGroups": {
+ "metrics": {
+ "title": "Metrics"
+ },
+ "insights": {
+ "title": "Insights",
+ "description": "These insights are also available in the Chrome DevTools Performance Panel - [record a trace](https://developer.chrome.com/docs/devtools/performance/reference) to view more detailed information."
+ },
+ "diagnostics": {
+ "title": "Diagnostics",
+ "description": "More information about the performance of your application. These numbers don't [directly affect](https://developer.chrome.com/docs/lighthouse/performance/performance-scoring/) the Performance score."
+ },
+ "a11y-best-practices": {
+ "title": "Best practices",
+ "description": "These items highlight common accessibility best practices."
+ },
+ "a11y-color-contrast": {
+ "title": "Contrast",
+ "description": "These are opportunities to improve the legibility of your content."
+ },
+ "a11y-names-labels": {
+ "title": "Names and labels",
+ "description": "These are opportunities to improve the semantics of the controls in your application. This may enhance the experience for users of assistive technology, like a screen reader."
+ },
+ "a11y-navigation": {
+ "title": "Navigation",
+ "description": "These are opportunities to improve keyboard navigation in your application."
+ },
+ "a11y-aria": {
+ "title": "ARIA",
+ "description": "These are opportunities to improve the usage of ARIA in your application which may enhance the experience for users of assistive technology, like a screen reader."
+ },
+ "a11y-language": {
+ "title": "Internationalization and localization",
+ "description": "These are opportunities to improve the interpretation of your content by users in different locales."
+ },
+ "a11y-audio-video": {
+ "title": "Audio and video",
+ "description": "These are opportunities to provide alternative content for audio and video. This may improve the experience for users with hearing or vision impairments."
+ },
+ "a11y-tables-lists": {
+ "title": "Tables and lists",
+ "description": "These are opportunities to improve the experience of reading tabular or list data using assistive technology, like a screen reader."
+ },
+ "seo-mobile": {
+ "title": "Mobile Friendly",
+ "description": "Make sure your pages are mobile friendly so users don’t have to pinch or zoom in order to read the content pages. [Learn how to make pages mobile-friendly](https://developers.google.com/search/mobile-sites/)."
+ },
+ "seo-content": {
+ "title": "Content Best Practices",
+ "description": "Format your HTML in a way that enables crawlers to better understand your app’s content."
+ },
+ "seo-crawl": {
+ "title": "Crawling and Indexing",
+ "description": "To appear in search results, crawlers need access to your app."
+ },
+ "best-practices-trust-safety": {
+ "title": "Trust and Safety"
+ },
+ "best-practices-ux": {
+ "title": "User Experience"
+ },
+ "best-practices-browser-compat": {
+ "title": "Browser Compatibility"
+ },
+ "best-practices-general": {
+ "title": "General"
+ },
+ "hidden": {
+ "title": ""
+ }
+ },
+ "stackPacks": [],
+ "entities": [
+ {
+ "name": "localhost",
+ "origins": [
+ "http://localhost:3000"
+ ],
+ "isFirstParty": true,
+ "isUnrecognized": true
+ },
+ {
+ "name": "valuefrontier.cn",
+ "origins": [
+ "https://app.valuefrontier.cn"
+ ],
+ "isUnrecognized": true
+ },
+ {
+ "name": "49.232.185.254",
+ "origins": [
+ "http://49.232.185.254:5001"
+ ],
+ "isUnrecognized": true
+ }
+ ],
+ "fullPageScreenshot": {
+ "screenshot": {
+ "data": "data:image/webp;base64,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",
+ "width": 412,
+ "height": 2124
+ },
+ "nodes": {
+ "page-0-DIV": {
+ "id": "",
+ "top": 65,
+ "bottom": 2189,
+ "left": 206,
+ "right": 412,
+ "width": 206,
+ "height": 2124
+ },
+ "page-1-DIV": {
+ "id": "dify-chatbot-bubble-button",
+ "top": 2052,
+ "bottom": 2108,
+ "left": 340,
+ "right": 396,
+ "width": 56,
+ "height": 56
+ },
+ "page-2-META": {
+ "id": "",
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ },
+ "page-3-BODY": {
+ "id": "",
+ "top": 0,
+ "bottom": 2348,
+ "left": 0,
+ "right": 412,
+ "width": 412,
+ "height": 2348
+ },
+ "page-4-H2": {
+ "id": "",
+ "top": 513,
+ "bottom": 633,
+ "left": 136,
+ "right": 219,
+ "width": 83,
+ "height": 120
+ },
+ "page-5-DIV": {
+ "id": "",
+ "top": 1384,
+ "bottom": 1534,
+ "left": 180,
+ "right": 330,
+ "width": 150,
+ "height": 150
+ },
+ "page-6-DIV": {
+ "id": "",
+ "top": 484,
+ "bottom": 684,
+ "left": 41,
+ "right": 241,
+ "width": 200,
+ "height": 200
+ },
+ "1-0-H2": {
+ "id": "",
+ "top": 513,
+ "bottom": 633,
+ "left": 136,
+ "right": 219,
+ "width": 83,
+ "height": 120
+ },
+ "1-1-BODY": {
+ "id": "",
+ "top": 0,
+ "bottom": 2348,
+ "left": 0,
+ "right": 412,
+ "width": 412,
+ "height": 2348
+ },
+ "1-2-IMG": {
+ "id": "",
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ },
+ "1-3-DIV": {
+ "id": "",
+ "top": 65,
+ "bottom": 2189,
+ "left": 206,
+ "right": 412,
+ "width": 206,
+ "height": 2124
+ },
+ "1-4-LINK": {
+ "id": "",
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ },
+ "1-5-LINK": {
+ "id": "",
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ },
+ "1-6-LINK": {
+ "id": "",
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ },
+ "1-7-LINK": {
+ "id": "",
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ },
+ "1-8-META": {
+ "id": "",
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ },
+ "1-9-META": {
+ "id": "",
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ },
+ "1-10-META": {
+ "id": "",
+ "top": 0,
+ "bottom": 0,
+ "left": 0,
+ "right": 0,
+ "width": 0,
+ "height": 0
+ }
+ }
+ },
+ "timing": {
+ "entries": [
+ {
+ "startTime": 3477.91,
+ "name": "lh:config",
+ "duration": 1214.37,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 3480.47,
+ "name": "lh:config:resolveArtifactsToDefns",
+ "duration": 247.9,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 4692.44,
+ "name": "lh:runner:gather",
+ "duration": 48779.73,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 4894.92,
+ "name": "lh:driver:connect",
+ "duration": 6.16,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 4901.35,
+ "name": "lh:driver:navigate",
+ "duration": 105.14,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 5006.82,
+ "name": "lh:gather:getBenchmarkIndex",
+ "duration": 1022.98,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 6030.02,
+ "name": "lh:gather:getVersion",
+ "duration": 0.99,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 6031.1,
+ "name": "lh:gather:getDevicePixelRatio",
+ "duration": 0.83,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 6032.72,
+ "name": "lh:prepare:navigationMode",
+ "duration": 148.21,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 6062.17,
+ "name": "lh:storage:clearDataForOrigin",
+ "duration": 60.78,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 6123.11,
+ "name": "lh:storage:clearBrowserCaches",
+ "duration": 52.85,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 6178.88,
+ "name": "lh:gather:prepareThrottlingAndNetwork",
+ "duration": 2.02,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 6315.28,
+ "name": "lh:driver:navigate",
+ "duration": 16364.07,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45197.16,
+ "name": "lh:computed:NetworkRecords",
+ "duration": 3.52,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45201.27,
+ "name": "lh:gather:getArtifact:DevtoolsLog",
+ "duration": 0.04,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45201.33,
+ "name": "lh:gather:getArtifact:Trace",
+ "duration": 0.02,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45201.36,
+ "name": "lh:gather:getArtifact:ConsoleMessages",
+ "duration": 0.02,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45201.4,
+ "name": "lh:gather:getArtifact:CSSUsage",
+ "duration": 68.65,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45270.08,
+ "name": "lh:gather:getArtifact:DOMStats",
+ "duration": 15.06,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45285.17,
+ "name": "lh:gather:getArtifact:ImageElements",
+ "duration": 67.34,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45352.54,
+ "name": "lh:gather:getArtifact:JsUsage",
+ "duration": 0.22,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45352.88,
+ "name": "lh:gather:getArtifact:LinkElements",
+ "duration": 4.51,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45356.97,
+ "name": "lh:computed:MainResource",
+ "duration": 0.27,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45357.42,
+ "name": "lh:gather:getArtifact:MetaElements",
+ "duration": 3.63,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45361.1,
+ "name": "lh:gather:getArtifact:NetworkUserAgent",
+ "duration": 0.13,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45361.25,
+ "name": "lh:gather:getArtifact:OptimizedImages",
+ "duration": 90.74,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45452.03,
+ "name": "lh:gather:getArtifact:ResponseCompression",
+ "duration": 4.69,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45456.75,
+ "name": "lh:gather:getArtifact:Scripts",
+ "duration": 0.12,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45456.91,
+ "name": "lh:gather:getArtifact:SourceMaps",
+ "duration": 0.06,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45456.99,
+ "name": "lh:gather:getArtifact:Stacks",
+ "duration": 16.79,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45457.07,
+ "name": "lh:gather:collectStacks",
+ "duration": 16.67,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45473.79,
+ "name": "lh:gather:getArtifact:Stylesheets",
+ "duration": 92.93,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45566.77,
+ "name": "lh:gather:getArtifact:TraceElements",
+ "duration": 6068.6,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45567.01,
+ "name": "lh:computed:TraceEngineResult",
+ "duration": 5997.49,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 45567.13,
+ "name": "lh:computed:ProcessedTrace",
+ "duration": 611.23,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 46222.06,
+ "name": "lh:computed:TraceEngineResult:total",
+ "duration": 5331.7,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 46222.09,
+ "name": "lh:computed:TraceEngineResult:parse",
+ "duration": 5103.48,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 46224.11,
+ "name": "lh:computed:TraceEngineResult:parse:handleEvent",
+ "duration": 3332.67,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 49556.81,
+ "name": "lh:computed:TraceEngineResult:parse:Meta:finalize",
+ "duration": 0.32,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 49557.16,
+ "name": "lh:computed:TraceEngineResult:parse:AnimationFrames:finalize",
+ "duration": 1.22,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 49558.41,
+ "name": "lh:computed:TraceEngineResult:parse:Animations:finalize",
+ "duration": 3.95,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 49562.39,
+ "name": "lh:computed:TraceEngineResult:parse:Samples:finalize",
+ "duration": 1.23,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 49563.65,
+ "name": "lh:computed:TraceEngineResult:parse:AuctionWorklets:finalize",
+ "duration": 1.25,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 49564.92,
+ "name": "lh:computed:TraceEngineResult:parse:NetworkRequests:finalize",
+ "duration": 13.02,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 49577.98,
+ "name": "lh:computed:TraceEngineResult:parse:Renderer:finalize",
+ "duration": 1114.74,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50692.76,
+ "name": "lh:computed:TraceEngineResult:parse:Flows:finalize",
+ "duration": 83.8,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50776.6,
+ "name": "lh:computed:TraceEngineResult:parse:AsyncJSCalls:finalize",
+ "duration": 55.62,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50832.26,
+ "name": "lh:computed:TraceEngineResult:parse:DOMStats:finalize",
+ "duration": 1.39,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50833.69,
+ "name": "lh:computed:TraceEngineResult:parse:UserTimings:finalize",
+ "duration": 1.51,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50835.24,
+ "name": "lh:computed:TraceEngineResult:parse:ExtensionTraceData:finalize",
+ "duration": 1.98,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50837.27,
+ "name": "lh:computed:TraceEngineResult:parse:LayerTree:finalize",
+ "duration": 3.5,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50840.81,
+ "name": "lh:computed:TraceEngineResult:parse:Frames:finalize",
+ "duration": 116.12,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50956.97,
+ "name": "lh:computed:TraceEngineResult:parse:GPU:finalize",
+ "duration": 1.45,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50958.47,
+ "name": "lh:computed:TraceEngineResult:parse:ImagePainting:finalize",
+ "duration": 1.43,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50959.93,
+ "name": "lh:computed:TraceEngineResult:parse:Initiators:finalize",
+ "duration": 2.61,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50962.58,
+ "name": "lh:computed:TraceEngineResult:parse:Invalidations:finalize",
+ "duration": 1.35,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50963.97,
+ "name": "lh:computed:TraceEngineResult:parse:PageLoadMetrics:finalize",
+ "duration": 2.61,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50966.61,
+ "name": "lh:computed:TraceEngineResult:parse:LargestImagePaint:finalize",
+ "duration": 1.48,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50968.11,
+ "name": "lh:computed:TraceEngineResult:parse:LargestTextPaint:finalize",
+ "duration": 1.23,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50969.36,
+ "name": "lh:computed:TraceEngineResult:parse:Screenshots:finalize",
+ "duration": 7.71,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50977.11,
+ "name": "lh:computed:TraceEngineResult:parse:LayoutShifts:finalize",
+ "duration": 1.92,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50979.05,
+ "name": "lh:computed:TraceEngineResult:parse:Memory:finalize",
+ "duration": 1.26,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50980.33,
+ "name": "lh:computed:TraceEngineResult:parse:PageFrames:finalize",
+ "duration": 1.31,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50981.68,
+ "name": "lh:computed:TraceEngineResult:parse:Scripts:finalize",
+ "duration": 2.34,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50984.05,
+ "name": "lh:computed:TraceEngineResult:parse:SelectorStats:finalize",
+ "duration": 1.27,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50985.34,
+ "name": "lh:computed:TraceEngineResult:parse:UserInteractions:finalize",
+ "duration": 1.93,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50987.32,
+ "name": "lh:computed:TraceEngineResult:parse:Workers:finalize",
+ "duration": 1.33,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50988.69,
+ "name": "lh:computed:TraceEngineResult:parse:Warnings:finalize",
+ "duration": 1.64,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 50990.42,
+ "name": "lh:computed:TraceEngineResult:parse:clone",
+ "duration": 335.1,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51325.58,
+ "name": "lh:computed:TraceEngineResult:insights",
+ "duration": 228.17,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51326.06,
+ "name": "lh:computed:TraceEngineResult:insights:CLSCulprits",
+ "duration": 0.8,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51326.89,
+ "name": "lh:computed:TraceEngineResult:insights:Cache",
+ "duration": 0.32,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51327.22,
+ "name": "lh:computed:TraceEngineResult:insights:DOMSize",
+ "duration": 0.57,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51327.81,
+ "name": "lh:computed:TraceEngineResult:insights:DocumentLatency",
+ "duration": 0.24,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51328.07,
+ "name": "lh:computed:TraceEngineResult:insights:DuplicatedJavaScript",
+ "duration": 2.1,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51330.19,
+ "name": "lh:computed:TraceEngineResult:insights:FontDisplay",
+ "duration": 0.21,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51330.43,
+ "name": "lh:computed:TraceEngineResult:insights:ForcedReflow",
+ "duration": 0.3,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51330.74,
+ "name": "lh:computed:TraceEngineResult:insights:INPBreakdown",
+ "duration": 0.14,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51330.9,
+ "name": "lh:computed:TraceEngineResult:insights:ImageDelivery",
+ "duration": 0.41,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51331.33,
+ "name": "lh:computed:TraceEngineResult:insights:LCPBreakdown",
+ "duration": 0.21,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51331.56,
+ "name": "lh:computed:TraceEngineResult:insights:LCPDiscovery",
+ "duration": 0.21,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51331.79,
+ "name": "lh:computed:TraceEngineResult:insights:LegacyJavaScript",
+ "duration": 0.4,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51332.2,
+ "name": "lh:computed:TraceEngineResult:insights:ModernHTTP",
+ "duration": 0.35,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51332.58,
+ "name": "lh:computed:TraceEngineResult:insights:NetworkDependencyTree",
+ "duration": 0.16,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51332.76,
+ "name": "lh:computed:TraceEngineResult:insights:RenderBlocking",
+ "duration": 0.2,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51332.97,
+ "name": "lh:computed:TraceEngineResult:insights:SlowCSSSelector",
+ "duration": 0.26,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51333.25,
+ "name": "lh:computed:TraceEngineResult:insights:ThirdParties",
+ "duration": 3.07,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51336.35,
+ "name": "lh:computed:TraceEngineResult:insights:Viewport",
+ "duration": 0.27,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51336.92,
+ "name": "lh:computed:TraceEngineResult:insights:createLanternContext",
+ "duration": 191.31,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51528.29,
+ "name": "lh:computed:TraceEngineResult:insights:CLSCulprits",
+ "duration": 0.62,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51528.93,
+ "name": "lh:computed:TraceEngineResult:insights:Cache",
+ "duration": 2.12,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51531.07,
+ "name": "lh:computed:TraceEngineResult:insights:DOMSize",
+ "duration": 0.25,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51531.34,
+ "name": "lh:computed:TraceEngineResult:insights:DocumentLatency",
+ "duration": 0.35,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51531.7,
+ "name": "lh:computed:TraceEngineResult:insights:DuplicatedJavaScript",
+ "duration": 0.21,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51531.93,
+ "name": "lh:computed:TraceEngineResult:insights:FontDisplay",
+ "duration": 0.03,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51531.97,
+ "name": "lh:computed:TraceEngineResult:insights:ForcedReflow",
+ "duration": 0.02,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51532,
+ "name": "lh:computed:TraceEngineResult:insights:INPBreakdown",
+ "duration": 0.02,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51532.02,
+ "name": "lh:computed:TraceEngineResult:insights:ImageDelivery",
+ "duration": 1.09,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51533.13,
+ "name": "lh:computed:TraceEngineResult:insights:LCPBreakdown",
+ "duration": 0.29,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51533.43,
+ "name": "lh:computed:TraceEngineResult:insights:LCPDiscovery",
+ "duration": 0.06,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51533.5,
+ "name": "lh:computed:TraceEngineResult:insights:LegacyJavaScript",
+ "duration": 0.1,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51533.61,
+ "name": "lh:computed:TraceEngineResult:insights:ModernHTTP",
+ "duration": 1.89,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51535.52,
+ "name": "lh:computed:TraceEngineResult:insights:NetworkDependencyTree",
+ "duration": 1.79,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51537.32,
+ "name": "lh:computed:TraceEngineResult:insights:RenderBlocking",
+ "duration": 0.29,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51537.63,
+ "name": "lh:computed:TraceEngineResult:insights:SlowCSSSelector",
+ "duration": 0.03,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51537.67,
+ "name": "lh:computed:TraceEngineResult:insights:ThirdParties",
+ "duration": 14.75,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51552.45,
+ "name": "lh:computed:TraceEngineResult:insights:Viewport",
+ "duration": 0.17,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51570.04,
+ "name": "lh:computed:ProcessedNavigation",
+ "duration": 18.08,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51588.27,
+ "name": "lh:computed:CumulativeLayoutShift",
+ "duration": 28.11,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51617.77,
+ "name": "lh:computed:Responsiveness",
+ "duration": 0.27,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51635.4,
+ "name": "lh:gather:getArtifact:ViewportDimensions",
+ "duration": 1.48,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 51636.9,
+ "name": "lh:gather:getArtifact:FullPageScreenshot",
+ "duration": 1183.21,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 52820.17,
+ "name": "lh:gather:getArtifact:BFCacheFailures",
+ "duration": 624.44,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53472.67,
+ "name": "lh:runner:audit",
+ "duration": 3238.12,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53472.82,
+ "name": "lh:runner:auditing",
+ "duration": 3237.56,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53475.83,
+ "name": "lh:audit:viewport",
+ "duration": 3.81,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53476.61,
+ "name": "lh:computed:ViewportMeta",
+ "duration": 0.7,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53480.2,
+ "name": "lh:audit:first-contentful-paint",
+ "duration": 20.02,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53480.88,
+ "name": "lh:computed:FirstContentfulPaint",
+ "duration": 15.66,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53481.21,
+ "name": "lh:computed:LanternFirstContentfulPaint",
+ "duration": 15.32,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53481.37,
+ "name": "lh:computed:PageDependencyGraph",
+ "duration": 12.28,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53493.7,
+ "name": "lh:computed:LoadSimulator",
+ "duration": 1.1,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53493.79,
+ "name": "lh:computed:NetworkAnalysis",
+ "duration": 0.94,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53500.82,
+ "name": "lh:audit:largest-contentful-paint",
+ "duration": 4.75,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53501.35,
+ "name": "lh:computed:LargestContentfulPaint",
+ "duration": 2.88,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53501.43,
+ "name": "lh:computed:LanternLargestContentfulPaint",
+ "duration": 2.78,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53506.06,
+ "name": "lh:audit:first-meaningful-paint",
+ "duration": 1.51,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53507.97,
+ "name": "lh:audit:speed-index",
+ "duration": 481.28,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53508.42,
+ "name": "lh:computed:SpeedIndex",
+ "duration": 479.55,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53508.5,
+ "name": "lh:computed:LanternSpeedIndex",
+ "duration": 479.44,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53508.55,
+ "name": "lh:computed:Speedline",
+ "duration": 461.45,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53989.3,
+ "name": "lh:audit:screenshot-thumbnails",
+ "duration": 0.64,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53989.97,
+ "name": "lh:audit:final-screenshot",
+ "duration": 29.2,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 53990.07,
+ "name": "lh:computed:Screenshots",
+ "duration": 29.02,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54019.65,
+ "name": "lh:audit:total-blocking-time",
+ "duration": 20.71,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54020.15,
+ "name": "lh:computed:TotalBlockingTime",
+ "duration": 19.04,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54020.25,
+ "name": "lh:computed:LanternTotalBlockingTime",
+ "duration": 18.92,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54020.35,
+ "name": "lh:computed:LanternInteractive",
+ "duration": 10.49,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54040.73,
+ "name": "lh:audit:max-potential-fid",
+ "duration": 11.43,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54041.19,
+ "name": "lh:computed:MaxPotentialFID",
+ "duration": 8.88,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54041.27,
+ "name": "lh:computed:LanternMaxPotentialFID",
+ "duration": 8.78,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54052.49,
+ "name": "lh:audit:cumulative-layout-shift",
+ "duration": 2.47,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54055.41,
+ "name": "lh:audit:server-response-time",
+ "duration": 2.34,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54058.12,
+ "name": "lh:audit:interactive",
+ "duration": 1.61,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54058.6,
+ "name": "lh:computed:Interactive",
+ "duration": 0.1,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54060.05,
+ "name": "lh:audit:user-timings",
+ "duration": 6.33,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54060.44,
+ "name": "lh:computed:UserTimings",
+ "duration": 4.87,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54066.68,
+ "name": "lh:audit:critical-request-chains",
+ "duration": 2.15,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54067.08,
+ "name": "lh:computed:CriticalRequestChains",
+ "duration": 0.7,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54069.1,
+ "name": "lh:audit:redirects",
+ "duration": 7.26,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54076.8,
+ "name": "lh:audit:mainthread-work-breakdown",
+ "duration": 33.6,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54077.54,
+ "name": "lh:computed:MainThreadTasks",
+ "duration": 29.65,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54110.76,
+ "name": "lh:audit:bootup-time",
+ "duration": 17.97,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54115.1,
+ "name": "lh:computed:TBTImpactTasks",
+ "duration": 10.93,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54129.01,
+ "name": "lh:audit:uses-rel-preconnect",
+ "duration": 6.88,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54136.25,
+ "name": "lh:audit:font-display",
+ "duration": 3.61,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54139.88,
+ "name": "lh:audit:diagnostics",
+ "duration": 1.24,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54141.15,
+ "name": "lh:audit:network-requests",
+ "duration": 4.28,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54141.35,
+ "name": "lh:computed:EntityClassification",
+ "duration": 3.26,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54145.76,
+ "name": "lh:audit:network-rtt",
+ "duration": 1.45,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54147.48,
+ "name": "lh:audit:network-server-latency",
+ "duration": 1.31,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54148.81,
+ "name": "lh:audit:main-thread-tasks",
+ "duration": 0.64,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54149.47,
+ "name": "lh:audit:metrics",
+ "duration": 29.18,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54149.64,
+ "name": "lh:computed:TimingSummary",
+ "duration": 28.8,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54149.97,
+ "name": "lh:computed:FirstContentfulPaintAllFrames",
+ "duration": 0.09,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54150.11,
+ "name": "lh:computed:LargestContentfulPaintAllFrames",
+ "duration": 0.08,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54150.27,
+ "name": "lh:computed:LCPBreakdown",
+ "duration": 27.54,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54150.37,
+ "name": "lh:computed:TimeToFirstByte",
+ "duration": 0.2,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54150.58,
+ "name": "lh:computed:LCPImageRecord",
+ "duration": 27.13,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54178.66,
+ "name": "lh:audit:resource-summary",
+ "duration": 1.76,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54178.83,
+ "name": "lh:computed:ResourceSummary",
+ "duration": 0.69,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54180.89,
+ "name": "lh:audit:third-party-summary",
+ "duration": 5.57,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54186.94,
+ "name": "lh:audit:third-party-facades",
+ "duration": 3.8,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54191.05,
+ "name": "lh:audit:largest-contentful-paint-element",
+ "duration": 1.95,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54193.37,
+ "name": "lh:audit:lcp-lazy-loaded",
+ "duration": 1.76,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54195.42,
+ "name": "lh:audit:layout-shifts",
+ "duration": 1.54,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54197.25,
+ "name": "lh:audit:long-tasks",
+ "duration": 11.49,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54209.26,
+ "name": "lh:audit:non-composited-animations",
+ "duration": 3.06,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54212.79,
+ "name": "lh:audit:unsized-images",
+ "duration": 2.08,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54215.19,
+ "name": "lh:audit:prioritize-lcp-image",
+ "duration": 5.43,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54220.65,
+ "name": "lh:audit:script-treemap-data",
+ "duration": 354.63,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54221.04,
+ "name": "lh:computed:JSBundles",
+ "duration": 0.1,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54221.16,
+ "name": "lh:computed:ModuleDuplication",
+ "duration": 0.23,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54221.43,
+ "name": "lh:computed:UnusedJavascriptSummary",
+ "duration": 0.34,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54221.88,
+ "name": "lh:computed:UnusedJavascriptSummary",
+ "duration": 352.95,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54575.02,
+ "name": "lh:computed:UnusedJavascriptSummary",
+ "duration": 0.16,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54575.77,
+ "name": "lh:audit:uses-long-cache-ttl",
+ "duration": 3.64,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54579.95,
+ "name": "lh:audit:total-byte-weight",
+ "duration": 2.7,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54583.01,
+ "name": "lh:audit:offscreen-images",
+ "duration": 4.7,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54588.08,
+ "name": "lh:audit:render-blocking-resources",
+ "duration": 34.15,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54589.16,
+ "name": "lh:computed:UnusedCSS",
+ "duration": 31.3,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54620.76,
+ "name": "lh:computed:NavigationInsights",
+ "duration": 0.21,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54621.04,
+ "name": "lh:computed:FirstContentfulPaint",
+ "duration": 0.09,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54622.58,
+ "name": "lh:audit:unminified-css",
+ "duration": 64.18,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 54687.1,
+ "name": "lh:audit:unminified-javascript",
+ "duration": 642.84,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55330.17,
+ "name": "lh:audit:unused-css-rules",
+ "duration": 1.97,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55332.35,
+ "name": "lh:audit:unused-javascript",
+ "duration": 3.22,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55335.79,
+ "name": "lh:audit:modern-image-formats",
+ "duration": 2.47,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55338.48,
+ "name": "lh:audit:uses-optimized-images",
+ "duration": 2.01,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55340.7,
+ "name": "lh:audit:uses-text-compression",
+ "duration": 1.83,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55342.74,
+ "name": "lh:audit:uses-responsive-images",
+ "duration": 2.51,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55343.07,
+ "name": "lh:computed:ImageRecords",
+ "duration": 0.3,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55345.48,
+ "name": "lh:audit:efficient-animated-content",
+ "duration": 2.24,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55347.94,
+ "name": "lh:audit:duplicated-javascript",
+ "duration": 2.27,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 55350.5,
+ "name": "lh:audit:legacy-javascript",
+ "duration": 1317.97,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56668.75,
+ "name": "lh:audit:dom-size",
+ "duration": 2.18,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56672.22,
+ "name": "lh:audit:no-document-write",
+ "duration": 1.42,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56673.87,
+ "name": "lh:audit:uses-http2",
+ "duration": 3.25,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56677.47,
+ "name": "lh:audit:uses-passive-event-listeners",
+ "duration": 1.22,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56679.01,
+ "name": "lh:audit:bf-cache",
+ "duration": 1.5,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56680.82,
+ "name": "lh:audit:cache-insight",
+ "duration": 1.91,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56683.04,
+ "name": "lh:audit:cls-culprits-insight",
+ "duration": 1.27,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56684.62,
+ "name": "lh:audit:document-latency-insight",
+ "duration": 1.08,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56686.02,
+ "name": "lh:audit:dom-size-insight",
+ "duration": 1.47,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56687.78,
+ "name": "lh:audit:duplicated-javascript-insight",
+ "duration": 1.18,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56689.29,
+ "name": "lh:audit:font-display-insight",
+ "duration": 1.21,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56690.82,
+ "name": "lh:audit:forced-reflow-insight",
+ "duration": 1.4,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56692.53,
+ "name": "lh:audit:image-delivery-insight",
+ "duration": 1.72,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56694.55,
+ "name": "lh:audit:inp-breakdown-insight",
+ "duration": 1.31,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56696.17,
+ "name": "lh:audit:lcp-breakdown-insight",
+ "duration": 1.53,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56698.06,
+ "name": "lh:audit:lcp-discovery-insight",
+ "duration": 1.19,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56699.96,
+ "name": "lh:audit:legacy-javascript-insight",
+ "duration": 1.48,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56701.82,
+ "name": "lh:audit:modern-http-insight",
+ "duration": 1.42,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56703.6,
+ "name": "lh:audit:network-dependency-tree-insight",
+ "duration": 2.06,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56705.98,
+ "name": "lh:audit:render-blocking-insight",
+ "duration": 1.3,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56707.66,
+ "name": "lh:audit:third-parties-insight",
+ "duration": 1.36,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56709.31,
+ "name": "lh:audit:viewport-insight",
+ "duration": 1.05,
+ "entryType": "measure"
+ },
+ {
+ "startTime": 56710.39,
+ "name": "lh:runner:generate",
+ "duration": 0.39,
+ "entryType": "measure"
+ }
+ ],
+ "total": 52017.850000000006
+ },
+ "i18n": {
+ "rendererFormattedStrings": {
+ "calculatorLink": "See calculator.",
+ "collapseView": "Collapse view",
+ "crcInitialNavigation": "Initial Navigation",
+ "crcLongestDurationLabel": "Maximum critical path latency:",
+ "dropdownCopyJSON": "Copy JSON",
+ "dropdownDarkTheme": "Toggle Dark Theme",
+ "dropdownPrintExpanded": "Print Expanded",
+ "dropdownPrintSummary": "Print Summary",
+ "dropdownSaveGist": "Save as Gist",
+ "dropdownSaveHTML": "Save as HTML",
+ "dropdownSaveJSON": "Save as JSON",
+ "dropdownViewUnthrottledTrace": "View Unthrottled Trace",
+ "dropdownViewer": "Open in Viewer",
+ "errorLabel": "Error!",
+ "errorMissingAuditInfo": "Report error: no audit information",
+ "expandView": "Expand view",
+ "firstPartyChipLabel": "1st party",
+ "footerIssue": "File an issue",
+ "goBackToAudits": "Go back to audits",
+ "hide": "Hide",
+ "insightsNotice": "Later this year, insights will replace performance audits. [Learn more and provide feedback here](https://github.com/GoogleChrome/lighthouse/discussions/16462).",
+ "labDataTitle": "Lab Data",
+ "lsPerformanceCategoryDescription": "[Lighthouse](https://developers.google.com/web/tools/lighthouse/) analysis of the current page on an emulated mobile network. Values are estimated and may vary.",
+ "manualAuditsGroupTitle": "Additional items to manually check",
+ "notApplicableAuditsGroupTitle": "Not applicable",
+ "openInANewTabTooltip": "Open in a new tab",
+ "opportunityResourceColumnLabel": "Opportunity",
+ "opportunitySavingsColumnLabel": "Estimated Savings",
+ "passedAuditsGroupTitle": "Passed audits",
+ "runtimeAnalysisWindow": "Initial page load",
+ "runtimeAnalysisWindowSnapshot": "Point-in-time snapshot",
+ "runtimeAnalysisWindowTimespan": "User interactions timespan",
+ "runtimeCustom": "Custom throttling",
+ "runtimeDesktopEmulation": "Emulated Desktop",
+ "runtimeMobileEmulation": "Emulated Moto G Power",
+ "runtimeNoEmulation": "No emulation",
+ "runtimeSettingsAxeVersion": "Axe version",
+ "runtimeSettingsBenchmark": "Unthrottled CPU/Memory Power",
+ "runtimeSettingsCPUThrottling": "CPU throttling",
+ "runtimeSettingsDevice": "Device",
+ "runtimeSettingsNetworkThrottling": "Network throttling",
+ "runtimeSettingsScreenEmulation": "Screen emulation",
+ "runtimeSettingsUANetwork": "User agent (network)",
+ "runtimeSingleLoad": "Single page session",
+ "runtimeSingleLoadTooltip": "This data is taken from a single page session, as opposed to field data summarizing many sessions.",
+ "runtimeSlow4g": "Slow 4G throttling",
+ "runtimeUnknown": "Unknown",
+ "show": "Show",
+ "showRelevantAudits": "Show audits relevant to:",
+ "snippetCollapseButtonLabel": "Collapse snippet",
+ "snippetExpandButtonLabel": "Expand snippet",
+ "thirdPartyResourcesLabel": "Show 3rd-party resources",
+ "throttlingProvided": "Provided by environment",
+ "toplevelWarningsMessage": "There were issues affecting this run of Lighthouse:",
+ "tryInsights": "Try insights",
+ "unattributable": "Unattributable",
+ "varianceDisclaimer": "Values are estimated and may vary. The [performance score is calculated](https://developer.chrome.com/docs/lighthouse/performance/performance-scoring/) directly from these metrics.",
+ "viewTraceLabel": "View Trace",
+ "viewTreemapLabel": "View Treemap",
+ "warningAuditsGroupTitle": "Passed audits but with warnings",
+ "warningHeader": "Warnings: "
+ },
+ "icuMessagePaths": {
+ "core/audits/viewport.js | title": [
+ "audits.viewport.title"
+ ],
+ "core/audits/viewport.js | description": [
+ "audits.viewport.description"
+ ],
+ "core/lib/i18n/i18n.js | firstContentfulPaintMetric": [
+ "audits[first-contentful-paint].title"
+ ],
+ "core/audits/metrics/first-contentful-paint.js | description": [
+ "audits[first-contentful-paint].description"
+ ],
+ "core/lib/i18n/i18n.js | seconds": [
+ {
+ "values": {
+ "timeInMs": 650.34495
+ },
+ "path": "audits[first-contentful-paint].displayValue"
+ },
+ {
+ "values": {
+ "timeInMs": 28455.6899
+ },
+ "path": "audits[largest-contentful-paint].displayValue"
+ },
+ {
+ "values": {
+ "timeInMs": 5404.548441431197
+ },
+ "path": "audits[speed-index].displayValue"
+ },
+ {
+ "values": {
+ "timeInMs": 51540.68990000001
+ },
+ "path": "audits.interactive.displayValue"
+ },
+ {
+ "values": {
+ "timeInMs": 9049.531999999708
+ },
+ "path": "audits[mainthread-work-breakdown].displayValue"
+ },
+ {
+ "values": {
+ "timeInMs": 7880.652000000009
+ },
+ "path": "audits[bootup-time].displayValue"
+ }
+ ],
+ "core/lib/i18n/i18n.js | largestContentfulPaintMetric": [
+ "audits[largest-contentful-paint].title"
+ ],
+ "core/audits/metrics/largest-contentful-paint.js | description": [
+ "audits[largest-contentful-paint].description"
+ ],
+ "core/lib/i18n/i18n.js | firstMeaningfulPaintMetric": [
+ "audits[first-meaningful-paint].title"
+ ],
+ "core/audits/metrics/first-meaningful-paint.js | description": [
+ "audits[first-meaningful-paint].description"
+ ],
+ "core/lib/i18n/i18n.js | speedIndexMetric": [
+ "audits[speed-index].title"
+ ],
+ "core/audits/metrics/speed-index.js | description": [
+ "audits[speed-index].description"
+ ],
+ "core/lib/i18n/i18n.js | totalBlockingTimeMetric": [
+ "audits[total-blocking-time].title"
+ ],
+ "core/audits/metrics/total-blocking-time.js | description": [
+ "audits[total-blocking-time].description"
+ ],
+ "core/lib/i18n/i18n.js | ms": [
+ {
+ "values": {
+ "timeInMs": 6581.000000000004
+ },
+ "path": "audits[total-blocking-time].displayValue"
+ },
+ {
+ "values": {
+ "timeInMs": 7338
+ },
+ "path": "audits[max-potential-fid].displayValue"
+ },
+ {
+ "values": {
+ "timeInMs": 19.20536999999998
+ },
+ "path": "audits[network-rtt].displayValue"
+ },
+ {
+ "values": {
+ "timeInMs": 671.76363
+ },
+ "path": "audits[network-server-latency].displayValue"
+ },
+ {
+ "values": {
+ "timeInMs": 28455.6899
+ },
+ "path": "audits[largest-contentful-paint-element].displayValue"
+ }
+ ],
+ "core/lib/i18n/i18n.js | maxPotentialFIDMetric": [
+ "audits[max-potential-fid].title"
+ ],
+ "core/audits/metrics/max-potential-fid.js | description": [
+ "audits[max-potential-fid].description"
+ ],
+ "core/lib/i18n/i18n.js | cumulativeLayoutShiftMetric": [
+ "audits[cumulative-layout-shift].title"
+ ],
+ "core/audits/metrics/cumulative-layout-shift.js | description": [
+ "audits[cumulative-layout-shift].description"
+ ],
+ "core/audits/server-response-time.js | title": [
+ "audits[server-response-time].title"
+ ],
+ "core/audits/server-response-time.js | description": [
+ "audits[server-response-time].description"
+ ],
+ "core/audits/server-response-time.js | displayValue": [
+ {
+ "values": {
+ "timeInMs": 17.037000000000003
+ },
+ "path": "audits[server-response-time].displayValue"
+ }
+ ],
+ "core/lib/i18n/i18n.js | columnURL": [
+ "audits[server-response-time].details.headings[0].label",
+ "audits[bootup-time].details.headings[0].label",
+ "audits[uses-rel-preconnect].details.headings[0].label",
+ "audits[font-display].details.headings[0].label",
+ "audits[network-rtt].details.headings[0].label",
+ "audits[network-server-latency].details.headings[0].label",
+ "audits[long-tasks].details.headings[0].label",
+ "audits[unsized-images].details.headings[1].label",
+ "audits[uses-long-cache-ttl].details.headings[0].label",
+ "audits[total-byte-weight].details.headings[0].label",
+ "audits[unminified-css].details.headings[0].label",
+ "audits[unused-css-rules].details.headings[0].label",
+ "audits[unused-javascript].details.headings[0].label",
+ "audits[modern-image-formats].details.headings[1].label",
+ "audits[legacy-javascript].details.headings[0].label",
+ "audits[uses-http2].details.headings[0].label",
+ "audits[font-display-insight].details.headings[0].label",
+ "audits[image-delivery-insight].details.headings[0].label",
+ "audits[legacy-javascript-insight].details.headings[0].label",
+ "audits[modern-http-insight].details.headings[0].label",
+ "audits[render-blocking-insight].details.headings[0].label"
+ ],
+ "core/lib/i18n/i18n.js | columnTimeSpent": [
+ "audits[server-response-time].details.headings[1].label",
+ "audits[mainthread-work-breakdown].details.headings[1].label",
+ "audits[network-rtt].details.headings[1].label",
+ "audits[network-server-latency].details.headings[1].label"
+ ],
+ "core/lib/i18n/i18n.js | interactiveMetric": [
+ "audits.interactive.title"
+ ],
+ "core/audits/metrics/interactive.js | description": [
+ "audits.interactive.description"
+ ],
+ "core/audits/user-timings.js | title": [
+ "audits[user-timings].title"
+ ],
+ "core/audits/user-timings.js | description": [
+ "audits[user-timings].description"
+ ],
+ "core/lib/i18n/i18n.js | columnName": [
+ "audits[user-timings].details.headings[0].label",
+ "audits[non-composited-animations].details.headings[1].label"
+ ],
+ "core/audits/user-timings.js | columnType": [
+ "audits[user-timings].details.headings[1].label"
+ ],
+ "core/lib/i18n/i18n.js | columnStartTime": [
+ "audits[user-timings].details.headings[2].label",
+ "audits[long-tasks].details.headings[1].label"
+ ],
+ "core/lib/i18n/i18n.js | columnDuration": [
+ "audits[user-timings].details.headings[3].label",
+ "audits[long-tasks].details.headings[2].label",
+ "audits[lcp-breakdown-insight].details.items[0].headings[1].label",
+ "audits[render-blocking-insight].details.headings[2].label"
+ ],
+ "core/audits/critical-request-chains.js | title": [
+ "audits[critical-request-chains].title"
+ ],
+ "core/audits/critical-request-chains.js | description": [
+ "audits[critical-request-chains].description"
+ ],
+ "core/audits/redirects.js | title": [
+ "audits.redirects.title"
+ ],
+ "core/audits/redirects.js | description": [
+ "audits.redirects.description"
+ ],
+ "core/audits/mainthread-work-breakdown.js | failureTitle": [
+ "audits[mainthread-work-breakdown].title"
+ ],
+ "core/audits/mainthread-work-breakdown.js | description": [
+ "audits[mainthread-work-breakdown].description"
+ ],
+ "core/audits/mainthread-work-breakdown.js | columnCategory": [
+ "audits[mainthread-work-breakdown].details.headings[0].label"
+ ],
+ "core/audits/bootup-time.js | failureTitle": [
+ "audits[bootup-time].title"
+ ],
+ "core/audits/bootup-time.js | description": [
+ "audits[bootup-time].description"
+ ],
+ "core/audits/bootup-time.js | columnTotal": [
+ "audits[bootup-time].details.headings[1].label"
+ ],
+ "core/audits/bootup-time.js | columnScriptEval": [
+ "audits[bootup-time].details.headings[2].label"
+ ],
+ "core/audits/bootup-time.js | columnScriptParse": [
+ "audits[bootup-time].details.headings[3].label"
+ ],
+ "core/audits/uses-rel-preconnect.js | title": [
+ "audits[uses-rel-preconnect].title"
+ ],
+ "core/audits/uses-rel-preconnect.js | description": [
+ "audits[uses-rel-preconnect].description"
+ ],
+ "core/lib/i18n/i18n.js | displayValueMsSavings": [
+ {
+ "values": {
+ "wastedMs": 169.14731999999998
+ },
+ "path": "audits[uses-rel-preconnect].displayValue"
+ }
+ ],
+ "core/lib/i18n/i18n.js | columnWastedBytes": [
+ "audits[uses-rel-preconnect].details.headings[1].label",
+ "audits[font-display].details.headings[1].label",
+ "audits[unminified-css].details.headings[2].label",
+ "audits[unused-css-rules].details.headings[2].label",
+ "audits[unused-javascript].details.headings[2].label",
+ "audits[modern-image-formats].details.headings[3].label",
+ "audits[legacy-javascript].details.headings[2].label",
+ "audits[font-display-insight].details.headings[1].label",
+ "audits[image-delivery-insight].details.headings[2].label"
+ ],
+ "core/audits/font-display.js | title": [
+ "audits[font-display].title"
+ ],
+ "core/audits/font-display.js | description": [
+ "audits[font-display].description"
+ ],
+ "core/audits/network-rtt.js | title": [
+ "audits[network-rtt].title"
+ ],
+ "core/audits/network-rtt.js | description": [
+ "audits[network-rtt].description"
+ ],
+ "core/audits/network-server-latency.js | title": [
+ "audits[network-server-latency].title"
+ ],
+ "core/audits/network-server-latency.js | description": [
+ "audits[network-server-latency].description"
+ ],
+ "core/lib/i18n/i18n.js | columnResourceType": [
+ "audits[resource-summary].details.headings[0].label"
+ ],
+ "core/lib/i18n/i18n.js | columnRequests": [
+ "audits[resource-summary].details.headings[1].label"
+ ],
+ "core/lib/i18n/i18n.js | columnTransferSize": [
+ "audits[resource-summary].details.headings[2].label",
+ "audits[third-party-summary].details.headings[1].label",
+ "audits[uses-long-cache-ttl].details.headings[2].label",
+ "audits[total-byte-weight].details.headings[1].label",
+ "audits[unminified-css].details.headings[1].label",
+ "audits[unused-css-rules].details.headings[1].label",
+ "audits[unused-javascript].details.headings[1].label",
+ "audits[cache-insight].details.headings[2].label",
+ "audits[render-blocking-insight].details.headings[1].label"
+ ],
+ "core/lib/i18n/i18n.js | total": [
+ "audits[resource-summary].details.items[0].label"
+ ],
+ "core/lib/i18n/i18n.js | scriptResourceType": [
+ "audits[resource-summary].details.items[1].label"
+ ],
+ "core/lib/i18n/i18n.js | imageResourceType": [
+ "audits[resource-summary].details.items[2].label"
+ ],
+ "core/lib/i18n/i18n.js | stylesheetResourceType": [
+ "audits[resource-summary].details.items[3].label"
+ ],
+ "core/lib/i18n/i18n.js | documentResourceType": [
+ "audits[resource-summary].details.items[4].label"
+ ],
+ "core/lib/i18n/i18n.js | otherResourceType": [
+ "audits[resource-summary].details.items[5].label"
+ ],
+ "core/lib/i18n/i18n.js | mediaResourceType": [
+ "audits[resource-summary].details.items[6].label"
+ ],
+ "core/lib/i18n/i18n.js | fontResourceType": [
+ "audits[resource-summary].details.items[7].label"
+ ],
+ "core/lib/i18n/i18n.js | thirdPartyResourceType": [
+ "audits[resource-summary].details.items[8].label"
+ ],
+ "core/audits/third-party-summary.js | title": [
+ "audits[third-party-summary].title"
+ ],
+ "core/audits/third-party-summary.js | description": [
+ "audits[third-party-summary].description"
+ ],
+ "core/audits/third-party-summary.js | displayValue": [
+ {
+ "values": {
+ "timeInMs": 0.19488088687721156
+ },
+ "path": "audits[third-party-summary].displayValue"
+ }
+ ],
+ "core/audits/third-party-summary.js | columnThirdParty": [
+ "audits[third-party-summary].details.headings[0].label"
+ ],
+ "core/lib/i18n/i18n.js | columnBlockingTime": [
+ "audits[third-party-summary].details.headings[2].label"
+ ],
+ "core/audits/third-party-facades.js | title": [
+ "audits[third-party-facades].title"
+ ],
+ "core/audits/third-party-facades.js | description": [
+ "audits[third-party-facades].description"
+ ],
+ "core/audits/largest-contentful-paint-element.js | title": [
+ "audits[largest-contentful-paint-element].title"
+ ],
+ "core/audits/largest-contentful-paint-element.js | description": [
+ "audits[largest-contentful-paint-element].description"
+ ],
+ "core/lib/i18n/i18n.js | columnElement": [
+ "audits[largest-contentful-paint-element].details.items[0].headings[0].label",
+ "audits[lcp-lazy-loaded].details.headings[0].label",
+ "audits[layout-shifts].details.headings[0].label",
+ "audits[non-composited-animations].details.headings[0].label",
+ "audits[dom-size].details.headings[1].label",
+ "audits[dom-size-insight].details.headings[1].label"
+ ],
+ "core/audits/largest-contentful-paint-element.js | columnPhase": [
+ "audits[largest-contentful-paint-element].details.items[1].headings[0].label"
+ ],
+ "core/audits/largest-contentful-paint-element.js | columnPercentOfLCP": [
+ "audits[largest-contentful-paint-element].details.items[1].headings[1].label"
+ ],
+ "core/audits/largest-contentful-paint-element.js | columnTiming": [
+ "audits[largest-contentful-paint-element].details.items[1].headings[2].label"
+ ],
+ "core/audits/largest-contentful-paint-element.js | itemTTFB": [
+ "audits[largest-contentful-paint-element].details.items[1].items[0].phase"
+ ],
+ "core/audits/largest-contentful-paint-element.js | itemLoadDelay": [
+ "audits[largest-contentful-paint-element].details.items[1].items[1].phase"
+ ],
+ "core/audits/largest-contentful-paint-element.js | itemLoadTime": [
+ "audits[largest-contentful-paint-element].details.items[1].items[2].phase"
+ ],
+ "core/audits/largest-contentful-paint-element.js | itemRenderDelay": [
+ "audits[largest-contentful-paint-element].details.items[1].items[3].phase"
+ ],
+ "core/audits/lcp-lazy-loaded.js | title": [
+ "audits[lcp-lazy-loaded].title"
+ ],
+ "core/audits/lcp-lazy-loaded.js | description": [
+ "audits[lcp-lazy-loaded].description"
+ ],
+ "core/audits/layout-shifts.js | title": [
+ "audits[layout-shifts].title"
+ ],
+ "core/audits/layout-shifts.js | description": [
+ "audits[layout-shifts].description"
+ ],
+ "core/audits/layout-shifts.js | columnScore": [
+ "audits[layout-shifts].details.headings[1].label"
+ ],
+ "core/audits/long-tasks.js | title": [
+ "audits[long-tasks].title"
+ ],
+ "core/audits/long-tasks.js | description": [
+ "audits[long-tasks].description"
+ ],
+ "core/audits/long-tasks.js | displayValue": [
+ {
+ "values": {
+ "itemCount": 6
+ },
+ "path": "audits[long-tasks].displayValue"
+ }
+ ],
+ "core/audits/non-composited-animations.js | title": [
+ "audits[non-composited-animations].title"
+ ],
+ "core/audits/non-composited-animations.js | description": [
+ "audits[non-composited-animations].description"
+ ],
+ "core/audits/non-composited-animations.js | displayValue": [
+ {
+ "values": {
+ "itemCount": 1
+ },
+ "path": "audits[non-composited-animations].displayValue"
+ }
+ ],
+ "core/audits/non-composited-animations.js | unsupportedCSSProperty": [
+ {
+ "values": {
+ "propertyCount": 1,
+ "properties": "border-left-color"
+ },
+ "path": "audits[non-composited-animations].details.items[0].subItems.items[0].failureReason"
+ },
+ {
+ "values": {
+ "propertyCount": 1,
+ "properties": "border-right-color"
+ },
+ "path": "audits[non-composited-animations].details.items[0].subItems.items[1].failureReason"
+ },
+ {
+ "values": {
+ "propertyCount": 1,
+ "properties": "color"
+ },
+ "path": "audits[non-composited-animations].details.items[0].subItems.items[2].failureReason"
+ },
+ {
+ "values": {
+ "propertyCount": 1,
+ "properties": "border-top-color"
+ },
+ "path": "audits[non-composited-animations].details.items[0].subItems.items[3].failureReason"
+ },
+ {
+ "values": {
+ "propertyCount": 1,
+ "properties": "border-bottom-color"
+ },
+ "path": "audits[non-composited-animations].details.items[0].subItems.items[4].failureReason"
+ }
+ ],
+ "core/audits/unsized-images.js | title": [
+ "audits[unsized-images].title"
+ ],
+ "core/audits/unsized-images.js | description": [
+ "audits[unsized-images].description"
+ ],
+ "core/audits/prioritize-lcp-image.js | title": [
+ "audits[prioritize-lcp-image].title"
+ ],
+ "core/audits/prioritize-lcp-image.js | description": [
+ "audits[prioritize-lcp-image].description"
+ ],
+ "core/audits/byte-efficiency/uses-long-cache-ttl.js | failureTitle": [
+ "audits[uses-long-cache-ttl].title"
+ ],
+ "core/audits/byte-efficiency/uses-long-cache-ttl.js | description": [
+ "audits[uses-long-cache-ttl].description"
+ ],
+ "core/audits/byte-efficiency/uses-long-cache-ttl.js | displayValue": [
+ {
+ "values": {
+ "itemCount": 2
+ },
+ "path": "audits[uses-long-cache-ttl].displayValue"
+ }
+ ],
+ "core/lib/i18n/i18n.js | columnCacheTTL": [
+ "audits[uses-long-cache-ttl].details.headings[1].label",
+ "audits[cache-insight].details.headings[1].label"
+ ],
+ "core/audits/byte-efficiency/total-byte-weight.js | failureTitle": [
+ "audits[total-byte-weight].title"
+ ],
+ "core/audits/byte-efficiency/total-byte-weight.js | description": [
+ "audits[total-byte-weight].description"
+ ],
+ "core/audits/byte-efficiency/total-byte-weight.js | displayValue": [
+ {
+ "values": {
+ "totalBytes": 7431629
+ },
+ "path": "audits[total-byte-weight].displayValue"
+ }
+ ],
+ "core/audits/byte-efficiency/offscreen-images.js | title": [
+ "audits[offscreen-images].title"
+ ],
+ "core/audits/byte-efficiency/offscreen-images.js | description": [
+ "audits[offscreen-images].description"
+ ],
+ "core/audits/byte-efficiency/render-blocking-resources.js | title": [
+ "audits[render-blocking-resources].title"
+ ],
+ "core/audits/byte-efficiency/render-blocking-resources.js | description": [
+ "audits[render-blocking-resources].description"
+ ],
+ "core/audits/byte-efficiency/unminified-css.js | title": [
+ "audits[unminified-css].title"
+ ],
+ "core/audits/byte-efficiency/unminified-css.js | description": [
+ "audits[unminified-css].description"
+ ],
+ "core/lib/i18n/i18n.js | displayValueByteSavings": [
+ {
+ "values": {
+ "wastedBytes": 37166
+ },
+ "path": "audits[unminified-css].displayValue"
+ },
+ {
+ "values": {
+ "wastedBytes": 45936
+ },
+ "path": "audits[unused-css-rules].displayValue"
+ },
+ {
+ "values": {
+ "wastedBytes": 21175
+ },
+ "path": "audits[unused-javascript].displayValue"
+ },
+ {
+ "values": {
+ "wastedBytes": 243692.5
+ },
+ "path": "audits[modern-image-formats].displayValue"
+ },
+ {
+ "values": {
+ "wastedBytes": 446
+ },
+ "path": "audits[legacy-javascript].displayValue"
+ },
+ {
+ "values": {
+ "wastedBytes": 4113021
+ },
+ "path": "audits[cache-insight].displayValue"
+ },
+ {
+ "values": {
+ "wastedBytes": 191341
+ },
+ "path": "audits[image-delivery-insight].displayValue"
+ }
+ ],
+ "core/audits/byte-efficiency/unminified-javascript.js | title": [
+ "audits[unminified-javascript].title"
+ ],
+ "core/audits/byte-efficiency/unminified-javascript.js | description": [
+ "audits[unminified-javascript].description"
+ ],
+ "core/audits/byte-efficiency/unused-css-rules.js | title": [
+ "audits[unused-css-rules].title"
+ ],
+ "core/audits/byte-efficiency/unused-css-rules.js | description": [
+ "audits[unused-css-rules].description"
+ ],
+ "core/audits/byte-efficiency/unused-javascript.js | title": [
+ "audits[unused-javascript].title"
+ ],
+ "core/audits/byte-efficiency/unused-javascript.js | description": [
+ "audits[unused-javascript].description"
+ ],
+ "core/audits/byte-efficiency/modern-image-formats.js | title": [
+ "audits[modern-image-formats].title"
+ ],
+ "core/audits/byte-efficiency/modern-image-formats.js | description": [
+ "audits[modern-image-formats].description"
+ ],
+ "core/lib/i18n/i18n.js | columnResourceSize": [
+ "audits[modern-image-formats].details.headings[2].label",
+ "audits[image-delivery-insight].details.headings[1].label"
+ ],
+ "core/audits/byte-efficiency/uses-optimized-images.js | title": [
+ "audits[uses-optimized-images].title"
+ ],
+ "core/audits/byte-efficiency/uses-optimized-images.js | description": [
+ "audits[uses-optimized-images].description"
+ ],
+ "core/audits/byte-efficiency/uses-text-compression.js | title": [
+ "audits[uses-text-compression].title"
+ ],
+ "core/audits/byte-efficiency/uses-text-compression.js | description": [
+ "audits[uses-text-compression].description"
+ ],
+ "core/audits/byte-efficiency/uses-responsive-images.js | title": [
+ "audits[uses-responsive-images].title"
+ ],
+ "core/audits/byte-efficiency/uses-responsive-images.js | description": [
+ "audits[uses-responsive-images].description"
+ ],
+ "core/audits/byte-efficiency/efficient-animated-content.js | title": [
+ "audits[efficient-animated-content].title"
+ ],
+ "core/audits/byte-efficiency/efficient-animated-content.js | description": [
+ "audits[efficient-animated-content].description"
+ ],
+ "core/audits/byte-efficiency/duplicated-javascript.js | title": [
+ "audits[duplicated-javascript].title"
+ ],
+ "core/audits/byte-efficiency/duplicated-javascript.js | description": [
+ "audits[duplicated-javascript].description"
+ ],
+ "core/audits/byte-efficiency/legacy-javascript.js | title": [
+ "audits[legacy-javascript].title"
+ ],
+ "core/audits/byte-efficiency/legacy-javascript.js | description": [
+ "audits[legacy-javascript].description"
+ ],
+ "core/audits/dobetterweb/dom-size.js | title": [
+ "audits[dom-size].title"
+ ],
+ "core/audits/dobetterweb/dom-size.js | description": [
+ "audits[dom-size].description"
+ ],
+ "core/audits/dobetterweb/dom-size.js | displayValue": [
+ {
+ "values": {
+ "itemCount": 125
+ },
+ "path": "audits[dom-size].displayValue"
+ }
+ ],
+ "core/audits/dobetterweb/dom-size.js | columnStatistic": [
+ "audits[dom-size].details.headings[0].label"
+ ],
+ "core/audits/dobetterweb/dom-size.js | columnValue": [
+ "audits[dom-size].details.headings[2].label"
+ ],
+ "core/audits/dobetterweb/dom-size.js | statisticDOMElements": [
+ "audits[dom-size].details.items[0].statistic"
+ ],
+ "core/audits/dobetterweb/dom-size.js | statisticDOMDepth": [
+ "audits[dom-size].details.items[1].statistic"
+ ],
+ "core/audits/dobetterweb/dom-size.js | statisticDOMWidth": [
+ "audits[dom-size].details.items[2].statistic"
+ ],
+ "core/audits/dobetterweb/no-document-write.js | title": [
+ "audits[no-document-write].title"
+ ],
+ "core/audits/dobetterweb/no-document-write.js | description": [
+ "audits[no-document-write].description"
+ ],
+ "core/lib/i18n/i18n.js | columnSource": [
+ "audits[no-document-write].details.headings[0].label",
+ "audits[uses-passive-event-listeners].details.headings[0].label",
+ "audits[forced-reflow-insight].details.items[0].headings[0].label"
+ ],
+ "core/audits/dobetterweb/uses-http2.js | title": [
+ "audits[uses-http2].title"
+ ],
+ "core/audits/dobetterweb/uses-http2.js | description": [
+ "audits[uses-http2].description"
+ ],
+ "core/audits/dobetterweb/uses-http2.js | displayValue": [
+ {
+ "values": {
+ "itemCount": 83
+ },
+ "path": "audits[uses-http2].displayValue"
+ }
+ ],
+ "core/audits/dobetterweb/uses-http2.js | columnProtocol": [
+ "audits[uses-http2].details.headings[1].label"
+ ],
+ "core/audits/dobetterweb/uses-passive-event-listeners.js | title": [
+ "audits[uses-passive-event-listeners].title"
+ ],
+ "core/audits/dobetterweb/uses-passive-event-listeners.js | description": [
+ "audits[uses-passive-event-listeners].description"
+ ],
+ "core/audits/bf-cache.js | failureTitle": [
+ "audits[bf-cache].title"
+ ],
+ "core/audits/bf-cache.js | description": [
+ "audits[bf-cache].description"
+ ],
+ "core/audits/bf-cache.js | displayValue": [
+ {
+ "values": {
+ "itemCount": 1
+ },
+ "path": "audits[bf-cache].displayValue"
+ }
+ ],
+ "core/audits/bf-cache.js | failureReasonColumn": [
+ "audits[bf-cache].details.headings[0].label"
+ ],
+ "core/audits/bf-cache.js | failureTypeColumn": [
+ "audits[bf-cache].details.headings[1].label"
+ ],
+ "node_modules/@paulirish/trace_engine/panels/application/components/BackForwardCacheStrings.js | webSocket": [
+ "audits[bf-cache].details.items[0].reason"
+ ],
+ "core/audits/bf-cache.js | supportPendingFailureType": [
+ "audits[bf-cache].details.items[0].failureType"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/Cache.js | title": [
+ "audits[cache-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/Cache.js | description": [
+ "audits[cache-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/Cache.js | requestColumn": [
+ "audits[cache-insight].details.headings[0].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/CLSCulprits.js | title": [
+ "audits[cls-culprits-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/CLSCulprits.js | description": [
+ "audits[cls-culprits-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DocumentLatency.js | title": [
+ "audits[document-latency-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DocumentLatency.js | description": [
+ "audits[document-latency-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DocumentLatency.js | passingRedirects": [
+ "audits[document-latency-insight].details.items.noRedirects.label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DocumentLatency.js | passingServerResponseTime": [
+ {
+ "values": {
+ "PH1": "17 ms"
+ },
+ "path": "audits[document-latency-insight].details.items.serverResponseIsFast.label"
+ }
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DocumentLatency.js | passingTextCompression": [
+ "audits[document-latency-insight].details.items.usesCompression.label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js | title": [
+ "audits[dom-size-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js | description": [
+ "audits[dom-size-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js | statistic": [
+ "audits[dom-size-insight].details.headings[0].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js | value": [
+ "audits[dom-size-insight].details.headings[2].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js | totalElements": [
+ "audits[dom-size-insight].details.items[0].statistic"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js | maxChildren": [
+ "audits[dom-size-insight].details.items[1].statistic"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js | maxDOMDepth": [
+ "audits[dom-size-insight].details.items[2].statistic"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DuplicatedJavaScript.js | title": [
+ "audits[duplicated-javascript-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DuplicatedJavaScript.js | description": [
+ "audits[duplicated-javascript-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DuplicatedJavaScript.js | columnSource": [
+ "audits[duplicated-javascript-insight].details.headings[0].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/DuplicatedJavaScript.js | columnDuplicatedBytes": [
+ "audits[duplicated-javascript-insight].details.headings[1].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/FontDisplay.js | title": [
+ "audits[font-display-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/FontDisplay.js | description": [
+ "audits[font-display-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ForcedReflow.js | title": [
+ "audits[forced-reflow-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ForcedReflow.js | description": [
+ "audits[forced-reflow-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ForcedReflow.js | totalReflowTime": [
+ "audits[forced-reflow-insight].details.items[0].headings[1].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ImageDelivery.js | title": [
+ "audits[image-delivery-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ImageDelivery.js | description": [
+ "audits[image-delivery-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ImageDelivery.js | useModernFormat": [
+ "audits[image-delivery-insight].details.items[0].subItems.items[0].reason"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/INPBreakdown.js | title": [
+ "audits[inp-breakdown-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/INPBreakdown.js | description": [
+ "audits[inp-breakdown-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js | title": [
+ "audits[lcp-breakdown-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js | description": [
+ "audits[lcp-breakdown-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js | subpart": [
+ "audits[lcp-breakdown-insight].details.items[0].headings[0].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js | timeToFirstByte": [
+ "audits[lcp-breakdown-insight].details.items[0].items[0].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js | resourceLoadDelay": [
+ "audits[lcp-breakdown-insight].details.items[0].items[1].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js | resourceLoadDuration": [
+ "audits[lcp-breakdown-insight].details.items[0].items[2].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js | elementRenderDelay": [
+ "audits[lcp-breakdown-insight].details.items[0].items[3].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js | title": [
+ "audits[lcp-discovery-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js | description": [
+ "audits[lcp-discovery-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js | fetchPriorityShouldBeApplied": [
+ "audits[lcp-discovery-insight].details.items[0].items.priorityHinted.label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js | requestDiscoverable": [
+ "audits[lcp-discovery-insight].details.items[0].items.requestDiscoverable.label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js | lazyLoadNotApplied": [
+ "audits[lcp-discovery-insight].details.items[0].items.eagerlyLoaded.label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LegacyJavaScript.js | title": [
+ "audits[legacy-javascript-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LegacyJavaScript.js | description": [
+ "audits[legacy-javascript-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/LegacyJavaScript.js | columnWastedBytes": [
+ "audits[legacy-javascript-insight].details.headings[2].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ModernHTTP.js | title": [
+ "audits[modern-http-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ModernHTTP.js | description": [
+ "audits[modern-http-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ModernHTTP.js | protocol": [
+ "audits[modern-http-insight].details.headings[1].label"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js | title": [
+ "audits[network-dependency-tree-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js | description": [
+ "audits[network-dependency-tree-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js | preconnectOriginsTableTitle": [
+ "audits[network-dependency-tree-insight].details.items[1].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js | preconnectOriginsTableDescription": [
+ "audits[network-dependency-tree-insight].details.items[1].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js | noPreconnectOrigins": [
+ "audits[network-dependency-tree-insight].details.items[1].value.value"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js | estSavingTableTitle": [
+ "audits[network-dependency-tree-insight].details.items[2].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js | estSavingTableDescription": [
+ "audits[network-dependency-tree-insight].details.items[2].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js | noPreconnectCandidates": [
+ "audits[network-dependency-tree-insight].details.items[2].value.value"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/RenderBlocking.js | title": [
+ "audits[render-blocking-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/RenderBlocking.js | description": [
+ "audits[render-blocking-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ThirdParties.js | title": [
+ "audits[third-parties-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/ThirdParties.js | description": [
+ "audits[third-parties-insight].description"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/Viewport.js | title": [
+ "audits[viewport-insight].title"
+ ],
+ "node_modules/@paulirish/trace_engine/models/trace/insights/Viewport.js | description": [
+ "audits[viewport-insight].description"
+ ],
+ "core/config/default-config.js | performanceCategoryTitle": [
+ "categories.performance.title"
+ ],
+ "core/config/default-config.js | metricGroupTitle": [
+ "categoryGroups.metrics.title"
+ ],
+ "core/config/default-config.js | insightsGroupTitle": [
+ "categoryGroups.insights.title"
+ ],
+ "core/config/default-config.js | insightsGroupDescription": [
+ "categoryGroups.insights.description"
+ ],
+ "core/config/default-config.js | diagnosticsGroupTitle": [
+ "categoryGroups.diagnostics.title"
+ ],
+ "core/config/default-config.js | diagnosticsGroupDescription": [
+ "categoryGroups.diagnostics.description"
+ ],
+ "core/config/default-config.js | a11yBestPracticesGroupTitle": [
+ "categoryGroups[a11y-best-practices].title"
+ ],
+ "core/config/default-config.js | a11yBestPracticesGroupDescription": [
+ "categoryGroups[a11y-best-practices].description"
+ ],
+ "core/config/default-config.js | a11yColorContrastGroupTitle": [
+ "categoryGroups[a11y-color-contrast].title"
+ ],
+ "core/config/default-config.js | a11yColorContrastGroupDescription": [
+ "categoryGroups[a11y-color-contrast].description"
+ ],
+ "core/config/default-config.js | a11yNamesLabelsGroupTitle": [
+ "categoryGroups[a11y-names-labels].title"
+ ],
+ "core/config/default-config.js | a11yNamesLabelsGroupDescription": [
+ "categoryGroups[a11y-names-labels].description"
+ ],
+ "core/config/default-config.js | a11yNavigationGroupTitle": [
+ "categoryGroups[a11y-navigation].title"
+ ],
+ "core/config/default-config.js | a11yNavigationGroupDescription": [
+ "categoryGroups[a11y-navigation].description"
+ ],
+ "core/config/default-config.js | a11yAriaGroupTitle": [
+ "categoryGroups[a11y-aria].title"
+ ],
+ "core/config/default-config.js | a11yAriaGroupDescription": [
+ "categoryGroups[a11y-aria].description"
+ ],
+ "core/config/default-config.js | a11yLanguageGroupTitle": [
+ "categoryGroups[a11y-language].title"
+ ],
+ "core/config/default-config.js | a11yLanguageGroupDescription": [
+ "categoryGroups[a11y-language].description"
+ ],
+ "core/config/default-config.js | a11yAudioVideoGroupTitle": [
+ "categoryGroups[a11y-audio-video].title"
+ ],
+ "core/config/default-config.js | a11yAudioVideoGroupDescription": [
+ "categoryGroups[a11y-audio-video].description"
+ ],
+ "core/config/default-config.js | a11yTablesListsVideoGroupTitle": [
+ "categoryGroups[a11y-tables-lists].title"
+ ],
+ "core/config/default-config.js | a11yTablesListsVideoGroupDescription": [
+ "categoryGroups[a11y-tables-lists].description"
+ ],
+ "core/config/default-config.js | seoMobileGroupTitle": [
+ "categoryGroups[seo-mobile].title"
+ ],
+ "core/config/default-config.js | seoMobileGroupDescription": [
+ "categoryGroups[seo-mobile].description"
+ ],
+ "core/config/default-config.js | seoContentGroupTitle": [
+ "categoryGroups[seo-content].title"
+ ],
+ "core/config/default-config.js | seoContentGroupDescription": [
+ "categoryGroups[seo-content].description"
+ ],
+ "core/config/default-config.js | seoCrawlingGroupTitle": [
+ "categoryGroups[seo-crawl].title"
+ ],
+ "core/config/default-config.js | seoCrawlingGroupDescription": [
+ "categoryGroups[seo-crawl].description"
+ ],
+ "core/config/default-config.js | bestPracticesTrustSafetyGroupTitle": [
+ "categoryGroups[best-practices-trust-safety].title"
+ ],
+ "core/config/default-config.js | bestPracticesUXGroupTitle": [
+ "categoryGroups[best-practices-ux].title"
+ ],
+ "core/config/default-config.js | bestPracticesBrowserCompatGroupTitle": [
+ "categoryGroups[best-practices-browser-compat].title"
+ ],
+ "core/config/default-config.js | bestPracticesGeneralGroupTitle": [
+ "categoryGroups[best-practices-general].title"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/optimize-images.js b/optimize-images.js
new file mode 100644
index 00000000..31dec1ab
--- /dev/null
+++ b/optimize-images.js
@@ -0,0 +1,129 @@
+// 图片优化脚本 - 使用sharp压缩PNG图片
+const sharp = require('sharp');
+const fs = require('fs');
+const path = require('path');
+
+// 需要优化的大图片列表 (> 500KB)
+const LARGE_IMAGES = [
+ 'CoverImage.png',
+ 'BasicImage.png',
+ 'teams-image.png',
+ 'hand-background.png',
+ 'basic-auth.png',
+ 'BgMusicCard.png',
+ 'Landing2.png',
+ 'Landing3.png',
+ 'Landing1.png',
+ 'smart-home.png',
+ 'automotive-background-card.png'
+];
+
+const IMG_DIR = path.join(__dirname, 'src/assets/img');
+const BACKUP_DIR = path.join(IMG_DIR, 'original-backup');
+
+// 确保备份目录存在
+if (!fs.existsSync(BACKUP_DIR)) {
+ fs.mkdirSync(BACKUP_DIR, { recursive: true });
+}
+
+console.log('🎨 开始优化图片...');
+console.log('================================\n');
+
+let totalBefore = 0;
+let totalAfter = 0;
+let optimizedCount = 0;
+
+async function optimizeImage(filename) {
+ const srcPath = path.join(IMG_DIR, filename);
+ const backupPath = path.join(BACKUP_DIR, filename);
+
+ if (!fs.existsSync(srcPath)) {
+ console.log(`⚠️ 跳过: ${filename} (文件不存在)`);
+ return;
+ }
+
+ try {
+ // 获取原始大小
+ const beforeStats = fs.statSync(srcPath);
+ const beforeSize = beforeStats.size;
+ totalBefore += beforeSize;
+
+ // 备份原始文件
+ if (!fs.existsSync(backupPath)) {
+ fs.copyFileSync(srcPath, backupPath);
+ }
+
+ // 读取图片元数据
+ const metadata = await sharp(srcPath).metadata();
+
+ // 优化策略:
+ // 1. 如果宽度 > 2000px,缩放到 2000px
+ // 2. 压缩质量到 85
+ // 3. 使用 pngquant 算法压缩
+ let pipeline = sharp(srcPath);
+
+ if (metadata.width > 2000) {
+ pipeline = pipeline.resize(2000, null, {
+ withoutEnlargement: true,
+ fit: 'inside'
+ });
+ }
+
+ // PNG优化
+ pipeline = pipeline.png({
+ quality: 85,
+ compressionLevel: 9,
+ adaptiveFiltering: true,
+ force: true
+ });
+
+ // 保存优化后的图片
+ await pipeline.toFile(srcPath + '.tmp');
+
+ // 替换原文件
+ fs.renameSync(srcPath + '.tmp', srcPath);
+
+ // 获取优化后的大小
+ const afterStats = fs.statSync(srcPath);
+ const afterSize = afterStats.size;
+ totalAfter += afterSize;
+
+ // 计算节省的大小
+ const saved = beforeSize - afterSize;
+ const percent = Math.round((saved / beforeSize) * 100);
+
+ if (saved > 0) {
+ optimizedCount++;
+ console.log(`✅ ${filename}`);
+ console.log(` ${Math.round(beforeSize/1024)} KB → ${Math.round(afterSize/1024)} KB`);
+ console.log(` 节省: ${Math.round(saved/1024)} KB (-${percent}%)\n`);
+ } else {
+ console.log(`ℹ️ ${filename} - 已经是最优化状态\n`);
+ }
+
+ } catch (error) {
+ console.error(`❌ ${filename} 优化失败:`, error.message);
+ }
+}
+
+async function main() {
+ // 依次优化每个图片
+ for (const img of LARGE_IMAGES) {
+ await optimizeImage(img);
+ }
+
+ console.log('================================');
+ console.log('📊 优化总结:\n');
+ console.log(` 优化前总大小: ${Math.round(totalBefore/1024/1024)} MB`);
+ console.log(` 优化后总大小: ${Math.round(totalAfter/1024/1024)} MB`);
+
+ const totalSaved = totalBefore - totalAfter;
+ const totalPercent = Math.round((totalSaved / totalBefore) * 100);
+
+ console.log(` 节省空间: ${Math.round(totalSaved/1024/1024)} MB (-${totalPercent}%)`);
+ console.log(` 成功优化: ${optimizedCount}/${LARGE_IMAGES.length} 个文件\n`);
+ console.log('✅ 图片优化完成!');
+ console.log(`📁 原始文件已备份到: ${BACKUP_DIR}\n`);
+}
+
+main().catch(console.error);
diff --git a/package.json b/package.json
index 6a85a5fc..d7633a9d 100755
--- a/package.json
+++ b/package.json
@@ -36,6 +36,7 @@
"framer-motion": "^4.1.17",
"fullcalendar": "^5.9.0",
"globalize": "^1.7.0",
+ "history": "^5.3.0",
"leaflet": "^1.9.4",
"lucide-react": "^0.540.0",
"match-sorter": "6.3.0",
@@ -60,7 +61,7 @@
"react-quill": "^2.0.0-beta.4",
"react-responsive": "^10.0.1",
"react-responsive-masonry": "^2.7.1",
- "react-router-dom": "^6.4.0",
+ "react-router-dom": "^6.30.1",
"react-scripts": "^5.0.1",
"react-scroll": "^1.8.4",
"react-scroll-into-view": "^2.1.3",
@@ -85,10 +86,14 @@
"@types/react": "18.2.0",
"@types/react-dom": "18.2.0"
},
+ "overrides": {
+ "uuid": "^9.0.1"
+ },
"scripts": {
- "start": "react-scripts --openssl-legacy-provider start",
- "build": "react-scripts build && gulp licenses",
- "test": "react-scripts test --env=jsdom",
+ "start": "NODE_OPTIONS='--openssl-legacy-provider --max_old_space_size=4096' craco start",
+ "build": "NODE_OPTIONS='--openssl-legacy-provider --max_old_space_size=4096' craco build && gulp licenses",
+ "build:analyze": "NODE_OPTIONS='--openssl-legacy-provider --max_old_space_size=4096' ANALYZE=true craco build",
+ "test": "craco test --env=jsdom",
"eject": "react-scripts eject",
"deploy": "npm run build",
"lint:check": "eslint . --ext=js,jsx; exit 0",
@@ -96,16 +101,24 @@
"install:clean": "rm -rf node_modules/ && rm -rf package-lock.json && npm install && npm start"
},
"devDependencies": {
+ "@craco/craco": "^7.1.0",
"ajv": "^8.17.1",
"autoprefixer": "^10.4.21",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-prettier": "3.4.0",
"gulp": "4.0.2",
"gulp-append-prepend": "1.0.9",
+ "imagemin": "^9.0.1",
+ "imagemin-mozjpeg": "^10.0.0",
+ "imagemin-pngquant": "^10.0.0",
"postcss": "^8.5.6",
"prettier": "2.2.1",
"react-error-overlay": "6.0.9",
- "tailwindcss": "^3.4.17"
+ "sharp": "^0.34.4",
+ "tailwindcss": "^3.4.17",
+ "ts-node": "^10.9.2",
+ "webpack-bundle-analyzer": "^4.10.2",
+ "yn": "^5.1.0"
},
"browserslist": {
"production": [
diff --git a/serve.log b/serve.log
new file mode 100644
index 00000000..012db7e5
--- /dev/null
+++ b/serve.log
@@ -0,0 +1,3 @@
+ INFO Accepting connections at http://localhost:58321
+
+ INFO Gracefully shutting down. Please wait...
diff --git a/src/App.js b/src/App.js
index d070db22..722443e7 100755
--- a/src/App.js
+++ b/src/App.js
@@ -9,7 +9,7 @@
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Visionware.
*/
-import React from "react";
+import React, { Suspense, useEffect } from "react";
import { ChakraProvider } from '@chakra-ui/react';
import { Routes, Route, Navigate } from "react-router-dom";
@@ -19,34 +19,44 @@ import { Box, useColorMode } from '@chakra-ui/react';
// Core Components
import theme from "theme/theme.js";
-// Layouts
+// Loading Component
+import PageLoader from "components/Loading/PageLoader";
+
+// Layouts - 保持同步导入(需要立即加载)
import Admin from "layouts/Admin";
import Auth from "layouts/Auth";
import HomeLayout from "layouts/Home";
-// Views
-import Community from "views/Community";
-import LimitAnalyse from "views/LimitAnalyse";
-import ForecastReport from "views/Company/ForecastReport";
-import ConceptCenter from "views/Concept";
-import FinancialPanorama from "views/Company/FinancialPanorama";
-import CompanyIndex from "views/Company";
-import MarketDataView from "views/Company/MarketDataView";
-import StockOverview from "views/StockOverview";
-import EventDetail from "views/EventDetail";
-import TradingSimulation from "views/TradingSimulation";
+// ⚡ 使用 React.lazy() 实现路由懒加载
+// 首屏不需要的组件按需加载,大幅减少初始 JS 包大小
+const Community = React.lazy(() => import("views/Community"));
+const LimitAnalyse = React.lazy(() => import("views/LimitAnalyse"));
+const ForecastReport = React.lazy(() => import("views/Company/ForecastReport"));
+const ConceptCenter = React.lazy(() => import("views/Concept"));
+const FinancialPanorama = React.lazy(() => import("views/Company/FinancialPanorama"));
+const CompanyIndex = React.lazy(() => import("views/Company"));
+const MarketDataView = React.lazy(() => import("views/Company/MarketDataView"));
+const StockOverview = React.lazy(() => import("views/StockOverview"));
+const EventDetail = React.lazy(() => import("views/EventDetail"));
+const TradingSimulation = React.lazy(() => import("views/TradingSimulation"));
+
// Contexts
import { AuthProvider } from "contexts/AuthContext";
+import { AuthModalProvider } from "contexts/AuthModalContext";
// Components
import ProtectedRoute from "components/ProtectedRoute";
+import ErrorBoundary from "components/ErrorBoundary";
+import AuthModalManager from "components/Auth/AuthModalManager";
function AppContent() {
const { colorMode } = useColorMode();
return (
-
+ {/* ⚡ Suspense 边界:懒加载组件加载时显示 Loading */}
+ }>
+
{/* 首页路由 */}
} />
@@ -110,14 +120,10 @@ function AppContent() {
{/* 事件详情独立页面路由(不经 Admin 布局) */}
} />
- {/* 模拟盘交易系统路由 - 需要登录 */}
-
-
-
- }
+ {/* 模拟盘交易系统路由 - 无需登录 */}
+ }
/>
{/* 管理后台路由 - 需要登录 */}
@@ -139,16 +145,45 @@ function AppContent() {
{/* 404 页面 */}
} />
+
);
}
export default function App() {
+ // 全局错误处理:捕获未处理的 Promise rejection
+ useEffect(() => {
+ const handleUnhandledRejection = (event) => {
+ console.error('未捕获的 Promise rejection:', event.reason);
+ // 阻止默认的错误处理(防止崩溃)
+ event.preventDefault();
+ };
+
+ const handleError = (event) => {
+ console.error('全局错误:', event.error);
+ // 阻止默认的错误处理(防止崩溃)
+ event.preventDefault();
+ };
+
+ window.addEventListener('unhandledrejection', handleUnhandledRejection);
+ window.addEventListener('error', handleError);
+
+ return () => {
+ window.removeEventListener('unhandledrejection', handleUnhandledRejection);
+ window.removeEventListener('error', handleError);
+ };
+ }, []);
+
return (
-
-
-
+
+
+
+
+
+
+
+
);
}
\ No newline at end of file
diff --git a/src/assets/img/BasicImage.png b/src/assets/img/BasicImage.png
old mode 100755
new mode 100644
index 7b82e11c..7226bff7
Binary files a/src/assets/img/BasicImage.png and b/src/assets/img/BasicImage.png differ
diff --git a/src/assets/img/BgMusicCard.png b/src/assets/img/BgMusicCard.png
old mode 100755
new mode 100644
index 6488b4e8..04ba9628
Binary files a/src/assets/img/BgMusicCard.png and b/src/assets/img/BgMusicCard.png differ
diff --git a/src/assets/img/CoverImage.png b/src/assets/img/CoverImage.png
old mode 100755
new mode 100644
index cbf02623..3937ce0f
Binary files a/src/assets/img/CoverImage.png and b/src/assets/img/CoverImage.png differ
diff --git a/src/assets/img/Landing1.png b/src/assets/img/Landing1.png
old mode 100755
new mode 100644
index 987c4cbc..9877e802
Binary files a/src/assets/img/Landing1.png and b/src/assets/img/Landing1.png differ
diff --git a/src/assets/img/Landing2.png b/src/assets/img/Landing2.png
old mode 100755
new mode 100644
index 8cd7caba..27bd2d9b
Binary files a/src/assets/img/Landing2.png and b/src/assets/img/Landing2.png differ
diff --git a/src/assets/img/Landing3.png b/src/assets/img/Landing3.png
old mode 100755
new mode 100644
index 72d5e527..705dff3c
Binary files a/src/assets/img/Landing3.png and b/src/assets/img/Landing3.png differ
diff --git a/src/assets/img/automotive-background-card.png b/src/assets/img/automotive-background-card.png
old mode 100755
new mode 100644
index 669b68b6..f4cb6c29
Binary files a/src/assets/img/automotive-background-card.png and b/src/assets/img/automotive-background-card.png differ
diff --git a/src/assets/img/basic-auth.png b/src/assets/img/basic-auth.png
old mode 100755
new mode 100644
index 3df52455..4332d738
Binary files a/src/assets/img/basic-auth.png and b/src/assets/img/basic-auth.png differ
diff --git a/src/assets/img/hand-background.png b/src/assets/img/hand-background.png
old mode 100755
new mode 100644
index 8e05de33..8028b6f4
Binary files a/src/assets/img/hand-background.png and b/src/assets/img/hand-background.png differ
diff --git a/src/assets/img/original-backup/BasicImage.png b/src/assets/img/original-backup/BasicImage.png
new file mode 100755
index 00000000..7b82e11c
Binary files /dev/null and b/src/assets/img/original-backup/BasicImage.png differ
diff --git a/src/assets/img/original-backup/BgMusicCard.png b/src/assets/img/original-backup/BgMusicCard.png
new file mode 100755
index 00000000..6488b4e8
Binary files /dev/null and b/src/assets/img/original-backup/BgMusicCard.png differ
diff --git a/src/assets/img/original-backup/CoverImage.png b/src/assets/img/original-backup/CoverImage.png
new file mode 100755
index 00000000..cbf02623
Binary files /dev/null and b/src/assets/img/original-backup/CoverImage.png differ
diff --git a/src/assets/img/original-backup/Landing1.png b/src/assets/img/original-backup/Landing1.png
new file mode 100755
index 00000000..987c4cbc
Binary files /dev/null and b/src/assets/img/original-backup/Landing1.png differ
diff --git a/src/assets/img/original-backup/Landing2.png b/src/assets/img/original-backup/Landing2.png
new file mode 100755
index 00000000..8cd7caba
Binary files /dev/null and b/src/assets/img/original-backup/Landing2.png differ
diff --git a/src/assets/img/original-backup/Landing3.png b/src/assets/img/original-backup/Landing3.png
new file mode 100755
index 00000000..72d5e527
Binary files /dev/null and b/src/assets/img/original-backup/Landing3.png differ
diff --git a/src/assets/img/original-backup/automotive-background-card.png b/src/assets/img/original-backup/automotive-background-card.png
new file mode 100755
index 00000000..669b68b6
Binary files /dev/null and b/src/assets/img/original-backup/automotive-background-card.png differ
diff --git a/src/assets/img/original-backup/basic-auth.png b/src/assets/img/original-backup/basic-auth.png
new file mode 100755
index 00000000..3df52455
Binary files /dev/null and b/src/assets/img/original-backup/basic-auth.png differ
diff --git a/src/assets/img/original-backup/hand-background.png b/src/assets/img/original-backup/hand-background.png
new file mode 100755
index 00000000..8e05de33
Binary files /dev/null and b/src/assets/img/original-backup/hand-background.png differ
diff --git a/src/assets/img/original-backup/smart-home.png b/src/assets/img/original-backup/smart-home.png
new file mode 100755
index 00000000..c11f53ea
Binary files /dev/null and b/src/assets/img/original-backup/smart-home.png differ
diff --git a/src/assets/img/original-backup/teams-image.png b/src/assets/img/original-backup/teams-image.png
new file mode 100755
index 00000000..9b5b3c21
Binary files /dev/null and b/src/assets/img/original-backup/teams-image.png differ
diff --git a/src/assets/img/smart-home.png b/src/assets/img/smart-home.png
old mode 100755
new mode 100644
index c11f53ea..769e30e9
Binary files a/src/assets/img/smart-home.png and b/src/assets/img/smart-home.png differ
diff --git a/src/assets/img/teams-image.png b/src/assets/img/teams-image.png
old mode 100755
new mode 100644
index 9b5b3c21..1a6695ad
Binary files a/src/assets/img/teams-image.png and b/src/assets/img/teams-image.png differ
diff --git a/src/components/Auth/AuthBackground.js b/src/components/Auth/AuthBackground.js
new file mode 100644
index 00000000..83533e21
--- /dev/null
+++ b/src/components/Auth/AuthBackground.js
@@ -0,0 +1,55 @@
+// src/components/Auth/AuthBackground.js
+import React from "react";
+import { Box } from "@chakra-ui/react";
+
+/**
+ * 认证页面通用背景组件
+ * 用于登录和注册页面的动态渐变背景
+ */
+export default function AuthBackground() {
+ return (
+
+ );
+}
diff --git a/src/components/Auth/AuthFooter.js b/src/components/Auth/AuthFooter.js
new file mode 100644
index 00000000..099267e7
--- /dev/null
+++ b/src/components/Auth/AuthFooter.js
@@ -0,0 +1,58 @@
+import React from "react";
+import { HStack, Text, Link as ChakraLink } from "@chakra-ui/react";
+import { Link } from "react-router-dom";
+
+/**
+ * 认证页面底部组件
+ * 包含页面切换链接和登录方式切换链接
+ *
+ * 支持两种模式:
+ * 1. 页面模式:使用 linkTo 进行路由跳转
+ * 2. 弹窗模式:使用 onClick 进行弹窗切换
+ */
+export default function AuthFooter({
+ // 左侧链接配置
+ linkText, // 提示文本,如 "还没有账号," 或 "已有账号?"
+ linkLabel, // 链接文本,如 "去注册" 或 "去登录"
+ linkTo, // 链接路径,如 "/auth/sign-up" 或 "/auth/sign-in"(页面模式)
+ onClick, // 点击回调函数(弹窗模式,优先级高于 linkTo)
+
+ // 右侧切换配置
+ useVerificationCode, // 当前是否使用验证码登录
+ onSwitchMethod // 切换登录方式的回调函数
+}) {
+ return (
+
+ {/* 左侧:页面切换链接(去注册/去登录) */}
+ {onClick ? (
+ // 弹窗模式:使用 onClick
+
+ {linkText}
+ {linkLabel}
+
+ ) : (
+ // 页面模式:使用 Link 组件跳转
+
+ {linkText}
+ {linkLabel}
+
+ )}
+
+ {/* 右侧:登录方式切换链接(仅在提供了切换方法时显示) */}
+ {onSwitchMethod && (
+ {
+ e.preventDefault();
+ onSwitchMethod();
+ }}
+ >
+ {useVerificationCode ? '密码登陆' : '验证码登陆'}
+
+ )}
+
+ );
+}
diff --git a/src/components/Auth/AuthFormContent.js b/src/components/Auth/AuthFormContent.js
new file mode 100644
index 00000000..38feb673
--- /dev/null
+++ b/src/components/Auth/AuthFormContent.js
@@ -0,0 +1,460 @@
+// src/components/Auth/AuthFormContent.js
+// 统一的认证表单组件
+import React, { useState, useEffect, useRef } from "react";
+import { useNavigate } from "react-router-dom";
+import {
+ Box,
+ Button,
+ FormControl,
+ Input,
+ Heading,
+ VStack,
+ HStack,
+ Stack,
+ useToast,
+ Icon,
+ FormErrorMessage,
+ Center,
+ AlertDialog,
+ AlertDialogBody,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogContent,
+ AlertDialogOverlay,
+ Text,
+ Link as ChakraLink,
+ useBreakpointValue,
+ Divider,
+ IconButton,
+} from "@chakra-ui/react";
+import { FaLock, FaWeixin } from "react-icons/fa";
+import { useAuth } from "../../contexts/AuthContext";
+import { useAuthModal } from "../../contexts/AuthModalContext";
+import { authService } from "../../services/authService";
+import AuthHeader from './AuthHeader';
+import VerificationCodeInput from './VerificationCodeInput';
+import WechatRegister from './WechatRegister';
+
+// 统一配置对象
+const AUTH_CONFIG = {
+ // UI文本
+ title: "价值前沿",
+ subtitle: "开启您的投资之旅",
+ formTitle: "登陆/注册",
+ buttonText: "登录/注册",
+ loadingText: "验证中...",
+ successTitle: "验证成功",
+ successDescription: "欢迎!",
+ errorTitle: "验证失败",
+
+ // API配置
+ api: {
+ endpoint: '/api/auth/register/phone',
+ purpose: 'login', // ⚡ 统一使用 'login' 模式
+ },
+
+ // 功能开关
+ features: {
+ successDelay: 1000, // 延迟1秒显示成功提示
+ }
+};
+
+export default function AuthFormContent() {
+ const toast = useToast();
+ const navigate = useNavigate();
+ const { checkSession } = useAuth();
+ const { handleLoginSuccess } = useAuthModal();
+
+ // 使用统一配置
+ const config = AUTH_CONFIG;
+
+ // 追踪组件挂载状态,防止内存泄漏
+ const isMountedRef = useRef(true);
+ const cancelRef = useRef(); // AlertDialog 需要的 ref
+
+ // 页面状态
+ const [isLoading, setIsLoading] = useState(false);
+ const [errors, setErrors] = useState({});
+
+ // 昵称设置引导对话框
+ const [showNicknamePrompt, setShowNicknamePrompt] = useState(false);
+ const [currentPhone, setCurrentPhone] = useState("");
+
+ // 响应式布局配置
+ const isMobile = useBreakpointValue({ base: true, md: false });
+ const stackDirection = useBreakpointValue({ base: "column", md: "row" });
+ const stackSpacing = useBreakpointValue({ base: 4, md: 8 });
+
+ // 表单数据
+ const [formData, setFormData] = useState({
+ phone: "",
+ verificationCode: "",
+ });
+
+ // 验证码状态
+ const [verificationCodeSent, setVerificationCodeSent] = useState(false);
+ const [sendingCode, setSendingCode] = useState(false);
+ const [countdown, setCountdown] = useState(0);
+
+ // 输入框变化处理
+ const handleInputChange = (e) => {
+ const { name, value } = e.target;
+ setFormData(prev => ({
+ ...prev,
+ [name]: value
+ }));
+ };
+
+ // 倒计时逻辑
+ useEffect(() => {
+ let timer;
+ let isMounted = true;
+
+ if (countdown > 0) {
+ timer = setInterval(() => {
+ if (isMounted) {
+ setCountdown(prev => prev - 1);
+ }
+ }, 1000);
+ } else if (countdown === 0 && isMounted) {
+ setVerificationCodeSent(false);
+ }
+
+ return () => {
+ isMounted = false;
+ if (timer) clearInterval(timer);
+ };
+ }, [countdown]);
+
+ // 发送验证码
+ const sendVerificationCode = async () => {
+ const credential = formData.phone;
+
+ if (!credential) {
+ toast({
+ title: "请先输入手机号",
+ status: "warning",
+ duration: 3000,
+ });
+ return;
+ }
+
+ if (!/^1[3-9]\d{9}$/.test(credential)) {
+ toast({
+ title: "请输入有效的手机号",
+ status: "warning",
+ duration: 3000,
+ });
+ return;
+ }
+
+ try {
+ setSendingCode(true);
+ const response = await fetch('/api/auth/send-verification-code', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ credentials: 'include', // 必须包含以支持跨域 session cookie
+ body: JSON.stringify({
+ credential,
+ type: 'phone',
+ purpose: config.api.purpose // 根据模式使用不同的purpose
+ }),
+ });
+
+ if (!response) {
+ throw new Error('网络请求失败,请检查网络连接');
+ }
+
+ const data = await response.json();
+
+ if (!isMountedRef.current) return;
+
+ if (!data) {
+ throw new Error('服务器响应为空');
+ }
+
+ if (response.ok && data.success) {
+ toast({
+ title: "验证码已发送",
+ description: "验证码已发送到您的手机号",
+ status: "success",
+ duration: 3000,
+ });
+ setVerificationCodeSent(true);
+ setCountdown(60);
+ } else {
+ throw new Error(data.error || '发送验证码失败');
+ }
+ } catch (error) {
+ if (isMountedRef.current) {
+ toast({
+ title: "发送验证码失败",
+ description: error.message || "请稍后重试",
+ status: "error",
+ duration: 3000,
+ });
+ }
+ } finally {
+ if (isMountedRef.current) {
+ setSendingCode(false);
+ }
+ }
+ };
+
+ // 提交处理(登录或注册)
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ setIsLoading(true);
+
+ try {
+ const { phone, verificationCode, nickname } = formData;
+
+ // 表单验证
+ if (!phone || !verificationCode) {
+ toast({
+ title: "请填写完整信息",
+ description: "手机号和验证码不能为空",
+ status: "warning",
+ duration: 3000,
+ });
+ return;
+ }
+
+ if (!/^1[3-9]\d{9}$/.test(phone)) {
+ toast({
+ title: "请输入有效的手机号",
+ status: "warning",
+ duration: 3000,
+ });
+ return;
+ }
+
+ // 构建请求体
+ const requestBody = {
+ credential: phone,
+ verification_code: verificationCode,
+ login_type: 'phone',
+ };
+
+ // 调用API(根据模式选择不同的endpoint
+ const response = await fetch('/api/auth/login-with-code', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ credentials: 'include', // 必须包含以支持跨域 session cookie
+ body: JSON.stringify(requestBody),
+ });
+
+ if (!response) {
+ throw new Error('网络请求失败,请检查网络连接');
+ }
+
+ const data = await response.json();
+
+ if (!isMountedRef.current) return;
+
+ if (!data) {
+ throw new Error('服务器响应为空');
+ }
+
+ if (response.ok && data.success) {
+ // 更新session
+ await checkSession();
+
+ toast({
+ title: config.successTitle,
+ description: config.successDescription,
+ status: "success",
+ duration: 2000,
+ });
+
+ // 检查是否为新注册用户
+ if (data.isNewUser) {
+ // 新注册用户,延迟后显示昵称设置引导
+ setTimeout(() => {
+ setCurrentPhone(phone);
+ setShowNicknamePrompt(true);
+ }, config.features.successDelay);
+ } else {
+ // 已有用户,直接登录成功
+ setTimeout(() => {
+ handleLoginSuccess({ phone });
+ }, config.features.successDelay);
+ }
+ } else {
+ throw new Error(data.error || `${config.errorTitle}`);
+ }
+ } catch (error) {
+ console.error('Auth error:', error);
+ if (isMountedRef.current) {
+ toast({
+ title: config.errorTitle,
+ description: error.message || "请稍后重试",
+ status: "error",
+ duration: 3000,
+ });
+ }
+ } finally {
+ if (isMountedRef.current) {
+ setIsLoading(false);
+ }
+ }
+ };
+
+ // 微信H5登录处理
+ const handleWechatH5Login = async () => {
+ try {
+ // 1. 构建回调URL
+ const redirectUrl = `${window.location.origin}/home/wechat-callback`;
+
+ // 2. 显示提示
+ toast({
+ title: "即将跳转",
+ description: "正在跳转到微信授权页面...",
+ status: "info",
+ duration: 2000,
+ isClosable: true,
+ });
+
+ // 3. 获取微信H5授权URL
+ const response = await authService.getWechatH5AuthUrl(redirectUrl);
+
+ if (!response || !response.auth_url) {
+ throw new Error('获取授权链接失败');
+ }
+
+ // 4. 延迟跳转,让用户看到提示
+ setTimeout(() => {
+ window.location.href = response.auth_url;
+ }, 500);
+ } catch (error) {
+ console.error('微信H5登录失败:', error);
+ toast({
+ title: "跳转失败",
+ description: error.message || "请稍后重试",
+ status: "error",
+ duration: 3000,
+ isClosable: true,
+ });
+ }
+ };
+
+ // 组件卸载时清理
+ useEffect(() => {
+ isMountedRef.current = true;
+
+ return () => {
+ isMountedRef.current = false;
+ };
+ }, []);
+
+ return (
+ <>
+
+
+
+
+
+
+
+ {/* 桌面端:右侧二维码扫描 */}
+ {!isMobile && (
+
+
+
+
+
+ )}
+
+
+
+ {/* 只在需要时才渲染 AlertDialog,避免创建不必要的 Portal */}
+ {showNicknamePrompt && (
+
{ setShowNicknamePrompt(false); handleLoginSuccess({ phone: currentPhone }); }} isCentered closeOnEsc={true} closeOnOverlayClick={false}>
+
+
+ 完善个人信息
+ 您已成功注册!是否前往个人中心设置昵称和其他信息?
+
+
+
+
+
+
+
+ )}
+ >
+ );
+}
diff --git a/src/components/Auth/AuthHeader.js b/src/components/Auth/AuthHeader.js
new file mode 100644
index 00000000..ba256868
--- /dev/null
+++ b/src/components/Auth/AuthHeader.js
@@ -0,0 +1,23 @@
+// src/components/Auth/AuthHeader.js
+import React from "react";
+import { Heading, Text, VStack } from "@chakra-ui/react";
+
+/**
+ * 认证页面通用头部组件
+ * 用于显示页面标题和描述
+ *
+ * @param {string} title - 主标题文字
+ * @param {string} subtitle - 副标题文字
+ */
+export default function AuthHeader({ title, subtitle }) {
+ return (
+
+
+ {title}
+
+
+ {subtitle}
+
+
+ );
+}
diff --git a/src/components/Auth/AuthModalManager.js b/src/components/Auth/AuthModalManager.js
new file mode 100644
index 00000000..40e38cd6
--- /dev/null
+++ b/src/components/Auth/AuthModalManager.js
@@ -0,0 +1,105 @@
+// src/components/Auth/AuthModalManager.js
+import React from 'react';
+import {
+ Modal,
+ ModalOverlay,
+ ModalContent,
+ ModalBody,
+ ModalCloseButton,
+ useBreakpointValue
+} from '@chakra-ui/react';
+import { useAuthModal } from '../../contexts/AuthModalContext';
+import AuthFormContent from './AuthFormContent';
+
+/**
+ * 全局认证弹窗管理器
+ * 统一的登录/注册弹窗
+ */
+export default function AuthModalManager() {
+ const {
+ isAuthModalOpen,
+ closeModal
+ } = useAuthModal();
+
+ // 响应式尺寸配置
+ const modalSize = useBreakpointValue({
+ base: "md", // 移动端:md(不占满全屏)
+ sm: "md", // 小屏:md
+ md: "lg", // 中屏:lg
+ lg: "xl" // 大屏:xl(更紧凑)
+ });
+
+ // 响应式宽度配置
+ const modalMaxW = useBreakpointValue({
+ base: "90%", // 移动端:屏幕宽度的90%
+ sm: "90%", // 小屏:90%
+ md: "700px", // 中屏:固定700px
+ lg: "700px" // 大屏:固定700px
+ });
+
+ // 响应式水平边距
+ const modalMx = useBreakpointValue({
+ base: 4, // 移动端:左右各16px边距
+ md: "auto" // 桌面端:自动居中
+ });
+
+ // 响应式垂直边距
+ const modalMy = useBreakpointValue({
+ base: 8, // 移动端:上下各32px边距
+ md: 8 // 桌面端:上下各32px边距
+ });
+
+ // 条件渲染:只在打开时才渲染 Modal,避免创建不必要的 Portal
+ if (!isAuthModalOpen) {
+ return null;
+ }
+
+ return (
+
+ {/* 半透明背景 + 模糊效果 */}
+
+
+ {/* 弹窗内容容器 */}
+
+ {/* 关闭按钮 */}
+
+
+ {/* 弹窗主体内容 */}
+
+
+
+
+
+ );
+}
diff --git a/src/components/Auth/VerificationCodeInput.js b/src/components/Auth/VerificationCodeInput.js
new file mode 100644
index 00000000..bc251055
--- /dev/null
+++ b/src/components/Auth/VerificationCodeInput.js
@@ -0,0 +1,56 @@
+import React from "react";
+import { FormControl, FormErrorMessage, HStack, Input, Button } from "@chakra-ui/react";
+
+/**
+ * 通用验证码输入组件
+ */
+export default function VerificationCodeInput({
+ value,
+ onChange,
+ onSendCode,
+ countdown,
+ isLoading,
+ isSending,
+ error,
+ placeholder = "请输入6位验证码",
+ buttonText = "获取验证码",
+ countdownText = (count) => `${count}s`,
+ colorScheme = "green",
+ isRequired = true
+}) {
+ // 包装 onSendCode,确保所有错误都被捕获,防止被 ErrorBoundary 捕获
+ const handleSendCode = async () => {
+ try {
+ if (onSendCode) {
+ await onSendCode();
+ }
+ } catch (error) {
+ // 错误已经在父组件处理,这里只需要防止未捕获的 Promise rejection
+ console.error('Send code error (caught in VerificationCodeInput):', error);
+ }
+ };
+
+ return (
+
+
+
+
+
+ {error}
+
+ );
+}
diff --git a/src/components/Auth/WechatRegister.js b/src/components/Auth/WechatRegister.js
new file mode 100644
index 00000000..c55689b1
--- /dev/null
+++ b/src/components/Auth/WechatRegister.js
@@ -0,0 +1,463 @@
+import React, { useState, useEffect, useLayoutEffect, useRef, useCallback } from "react";
+import {
+ Box,
+ Button,
+ VStack,
+ Text,
+ Icon,
+ useToast,
+ Spinner
+} from "@chakra-ui/react";
+import { FaQrcode } from "react-icons/fa";
+import { useNavigate } from "react-router-dom";
+import { authService, WECHAT_STATUS, STATUS_MESSAGES } from "../../services/authService";
+
+// 配置常量
+const POLL_INTERVAL = 2000; // 轮询间隔:2秒
+const BACKUP_POLL_INTERVAL = 3000; // 备用轮询间隔:3秒
+const QR_CODE_TIMEOUT = 300000; // 二维码超时:5分钟
+
+export default function WechatRegister() {
+ // 状态管理
+ const [wechatAuthUrl, setWechatAuthUrl] = useState("");
+ const [wechatSessionId, setWechatSessionId] = useState("");
+ const [wechatStatus, setWechatStatus] = useState(WECHAT_STATUS.NONE);
+ const [isLoading, setIsLoading] = useState(false);
+ const [scale, setScale] = useState(1); // iframe 缩放比例
+
+ // 使用 useRef 管理定时器,避免闭包问题和内存泄漏
+ const pollIntervalRef = useRef(null);
+ const backupPollIntervalRef = useRef(null); // 备用轮询定时器
+ const timeoutRef = useRef(null);
+ const isMountedRef = useRef(true); // 追踪组件挂载状态
+ const containerRef = useRef(null); // 容器DOM引用
+
+ const navigate = useNavigate();
+ const toast = useToast();
+
+ /**
+ * 显示统一的错误提示
+ */
+ const showError = useCallback((title, description) => {
+ toast({
+ title,
+ description,
+ status: "error",
+ duration: 3000,
+ isClosable: true,
+ });
+ }, [toast]);
+
+ /**
+ * 显示成功提示
+ */
+ const showSuccess = useCallback((title, description) => {
+ toast({
+ title,
+ description,
+ status: "success",
+ duration: 2000,
+ isClosable: true,
+ });
+ }, [toast]);
+
+ /**
+ * 清理所有定时器
+ */
+ const clearTimers = useCallback(() => {
+ if (pollIntervalRef.current) {
+ clearInterval(pollIntervalRef.current);
+ pollIntervalRef.current = null;
+ }
+ if (backupPollIntervalRef.current) {
+ clearInterval(backupPollIntervalRef.current);
+ backupPollIntervalRef.current = null;
+ }
+ if (timeoutRef.current) {
+ clearTimeout(timeoutRef.current);
+ timeoutRef.current = null;
+ }
+ }, []);
+
+ /**
+ * 处理登录成功
+ */
+ const handleLoginSuccess = useCallback(async (sessionId, status) => {
+ try {
+ const response = await authService.loginWithWechat(sessionId);
+
+ if (response?.success) {
+ // Session cookie 会自动管理,不需要手动存储
+ // 如果后端返回了 token,可以选择性存储(兼容旧方式)
+ if (response.token) {
+ localStorage.setItem('token', response.token);
+ }
+ if (response.user) {
+ localStorage.setItem('user', JSON.stringify(response.user));
+ }
+
+ showSuccess(
+ status === WECHAT_STATUS.LOGIN_SUCCESS ? "登录成功" : "注册成功",
+ "正在跳转..."
+ );
+
+ // 延迟跳转,让用户看到成功提示
+ setTimeout(() => {
+ navigate("/home");
+ }, 1000);
+ } else {
+ throw new Error(response?.error || '登录失败');
+ }
+ } catch (error) {
+ console.error('登录失败:', error);
+ showError("登录失败", error.message || "请重试");
+ }
+ }, [navigate, showSuccess, showError]);
+
+ /**
+ * 检查微信扫码状态
+ */
+ const checkWechatStatus = useCallback(async () => {
+ // 检查组件是否已卸载
+ if (!isMountedRef.current || !wechatSessionId) return;
+
+ try {
+ const response = await authService.checkWechatStatus(wechatSessionId);
+
+ // 安全检查:确保 response 存在且包含 status
+ if (!response || typeof response.status === 'undefined') {
+ console.warn('微信状态检查返回无效数据:', response);
+ return;
+ }
+
+ const { status } = response;
+
+ // 组件卸载后不再更新状态
+ if (!isMountedRef.current) return;
+
+ setWechatStatus(status);
+
+ // 处理成功状态
+ if (status === WECHAT_STATUS.LOGIN_SUCCESS || status === WECHAT_STATUS.REGISTER_SUCCESS) {
+ clearTimers(); // 停止轮询
+ await handleLoginSuccess(wechatSessionId, status);
+ }
+ // 处理过期状态
+ else if (status === WECHAT_STATUS.EXPIRED) {
+ clearTimers();
+ if (isMountedRef.current) {
+ toast({
+ title: "授权已过期",
+ description: "请重新获取授权",
+ status: "warning",
+ duration: 3000,
+ isClosable: true,
+ });
+ }
+ }
+ } catch (error) {
+ console.error("检查微信状态失败:", error);
+ // 轮询过程中的错误不显示给用户,避免频繁提示
+ // 但如果错误持续发生,停止轮询避免无限重试
+ if (error.message.includes('网络连接失败')) {
+ clearTimers();
+ if (isMountedRef.current) {
+ toast({
+ title: "网络连接失败",
+ description: "请检查网络后重试",
+ status: "error",
+ duration: 3000,
+ isClosable: true,
+ });
+ }
+ }
+ }
+ }, [wechatSessionId, handleLoginSuccess, clearTimers, toast]);
+
+ /**
+ * 启动轮询
+ */
+ const startPolling = useCallback(() => {
+ // 清理旧的定时器
+ clearTimers();
+
+ // 启动轮询
+ pollIntervalRef.current = setInterval(() => {
+ checkWechatStatus();
+ }, POLL_INTERVAL);
+
+ // 设置超时
+ timeoutRef.current = setTimeout(() => {
+ clearTimers();
+ setWechatStatus(WECHAT_STATUS.EXPIRED);
+ }, QR_CODE_TIMEOUT);
+ }, [checkWechatStatus, clearTimers]);
+
+ /**
+ * 获取微信二维码
+ */
+ const getWechatQRCode = useCallback(async () => {
+ try {
+ setIsLoading(true);
+
+ // 生产环境:调用真实 API
+ const response = await authService.getWechatQRCode();
+
+ // 检查组件是否已卸载
+ if (!isMountedRef.current) return;
+
+ // 安全检查:确保响应包含必要字段
+ if (!response) {
+ throw new Error('服务器无响应');
+ }
+
+ if (response.code !== 0) {
+ throw new Error(response.message || '获取二维码失败');
+ }
+
+ setWechatAuthUrl(response.data.auth_url);
+ setWechatSessionId(response.data.session_id);
+ setWechatStatus(WECHAT_STATUS.WAITING);
+
+ // 启动轮询检查扫码状态
+ startPolling();
+ } catch (error) {
+ console.error('获取微信授权失败:', error);
+ if (isMountedRef.current) {
+ showError("获取微信授权失败", error.message || "请稍后重试");
+ }
+ } finally {
+ if (isMountedRef.current) {
+ setIsLoading(false);
+ }
+ }
+ }, [startPolling, showError]);
+
+ /**
+ * 安全的按钮点击处理,确保所有错误都被捕获,防止被 ErrorBoundary 捕获
+ */
+ const handleGetQRCodeClick = useCallback(async () => {
+ try {
+ await getWechatQRCode();
+ } catch (error) {
+ // 错误已经在 getWechatQRCode 中处理,这里只需要防止未捕获的 Promise rejection
+ console.error('QR code button click error (caught in handler):', error);
+ }
+ }, [getWechatQRCode]);
+
+ /**
+ * 组件卸载时清理定时器和标记组件状态
+ */
+ useEffect(() => {
+ isMountedRef.current = true;
+
+ return () => {
+ isMountedRef.current = false;
+ clearTimers();
+ };
+ }, [clearTimers]);
+
+ /**
+ * 备用轮询机制 - 防止丢失状态
+ * 每3秒检查一次,仅在获取到二维码URL且状态为waiting时执行
+ */
+ useEffect(() => {
+ // 只在有auth_url、session_id且状态为waiting时启动备用轮询
+ if (wechatAuthUrl && wechatSessionId && wechatStatus === WECHAT_STATUS.WAITING) {
+ console.log('备用轮询:启动备用轮询机制');
+
+ backupPollIntervalRef.current = setInterval(() => {
+ try {
+ if (wechatStatus === WECHAT_STATUS.WAITING && isMountedRef.current) {
+ console.log('备用轮询:检查微信状态');
+ // 添加 .catch() 静默处理异步错误,防止被 ErrorBoundary 捕获
+ checkWechatStatus().catch(error => {
+ console.warn('备用轮询检查失败(静默处理):', error);
+ });
+ }
+ } catch (error) {
+ // 捕获所有同步错误,防止被 ErrorBoundary 捕获
+ console.warn('备用轮询执行出错(静默处理):', error);
+ }
+ }, BACKUP_POLL_INTERVAL);
+ }
+
+ // 清理备用轮询
+ return () => {
+ if (backupPollIntervalRef.current) {
+ clearInterval(backupPollIntervalRef.current);
+ backupPollIntervalRef.current = null;
+ }
+ };
+ }, [wechatAuthUrl, wechatSessionId, wechatStatus, checkWechatStatus]);
+
+ /**
+ * 测量容器尺寸并计算缩放比例
+ */
+ useLayoutEffect(() => {
+ // 微信授权页面的原始尺寸
+ const ORIGINAL_WIDTH = 600;
+ const ORIGINAL_HEIGHT = 800;
+
+ const calculateScale = () => {
+ if (containerRef.current) {
+ const { width, height } = containerRef.current.getBoundingClientRect();
+
+ // 计算宽高比例,取较小值确保完全适配
+ const scaleX = width / ORIGINAL_WIDTH;
+ const scaleY = height / ORIGINAL_HEIGHT;
+ const newScale = Math.min(scaleX, scaleY, 1.0); // 最大不超过1.0
+
+ // 设置最小缩放比例为0.3,避免过小
+ setScale(Math.max(newScale, 0.3));
+ }
+ };
+
+ // 初始计算
+ calculateScale();
+
+ // 使用 ResizeObserver 监听容器尺寸变化
+ const resizeObserver = new ResizeObserver(() => {
+ calculateScale();
+ });
+
+ if (containerRef.current) {
+ resizeObserver.observe(containerRef.current);
+ }
+
+ // 清理
+ return () => {
+ resizeObserver.disconnect();
+ };
+ }, [wechatStatus]); // 当状态变化时重新计算
+
+ /**
+ * 渲染状态提示文本
+ */
+ const renderStatusText = () => {
+ if (!wechatAuthUrl || wechatStatus === WECHAT_STATUS.NONE || wechatStatus === WECHAT_STATUS.EXPIRED) {
+ return null;
+ }
+
+ return (
+
+ {STATUS_MESSAGES[wechatStatus]}
+
+ );
+ };
+
+ return (
+
+ {wechatStatus === WECHAT_STATUS.WAITING ? (
+ <>
+
+ 微信扫码
+
+
+
+
+ {/* {renderStatusText()} */}
+ >
+ ) : (
+ <>
+
+ 微信扫码
+
+
+
+ {/* 灰色二维码底图 - 始终显示 */}
+
+
+ {/* 加载动画 */}
+ {isLoading && (
+
+
+
+ )}
+
+ {/* 显示获取/刷新二维码按钮 */}
+ {(wechatStatus === WECHAT_STATUS.NONE || wechatStatus === WECHAT_STATUS.EXPIRED) && (
+
+
+ }
+ _hover={{ bg: "green.50" }}
+ >
+ {wechatStatus === WECHAT_STATUS.EXPIRED ? "点击刷新" : "获取二维码"}
+
+ {wechatStatus === WECHAT_STATUS.EXPIRED && (
+
+ 二维码已过期
+
+ )}
+
+
+ )}
+
+
+ {/* 扫码状态提示 */}
+ {/* {renderStatusText()} */}
+ >
+ )}
+
+ );
+}
diff --git a/src/components/Citation/CitationMark.js b/src/components/Citation/CitationMark.js
new file mode 100644
index 00000000..aa15e0a4
--- /dev/null
+++ b/src/components/Citation/CitationMark.js
@@ -0,0 +1,140 @@
+// src/components/Citation/CitationMark.js
+import React, { useState } from 'react';
+import { Popover, Typography, Space, Divider } from 'antd';
+import { FileTextOutlined, UserOutlined, CalendarOutlined } from '@ant-design/icons';
+
+const { Text } = Typography;
+
+/**
+ * 引用标记组件 - 显示上标引用【1】【2】【3】
+ * 支持悬浮(桌面)和点击(移动)两种交互方式
+ *
+ * @param {Object} props
+ * @param {number} props.citationId - 引用 ID(1, 2, 3...)
+ * @param {Object} props.citation - 引用数据对象
+ * @param {string} props.citation.author - 作者
+ * @param {string} props.citation.report_title - 报告标题
+ * @param {string} props.citation.declare_date - 发布日期
+ * @param {string} props.citation.sentences - 摘要片段
+ */
+const CitationMark = ({ citationId, citation }) => {
+ const [popoverVisible, setPopoverVisible] = useState(false);
+
+ // 如果没有引用数据,不渲染
+ if (!citation) {
+ return null;
+ }
+
+ // 引用卡片内容
+ const citationContent = (
+
+ {/* 作者 */}
+
+
+
+ 作者
+
+ {citation.author}
+
+
+
+
+
+ {/* 报告标题 */}
+
+
+
+ 报告标题
+
+ {citation.report_title}
+
+
+
+
+
+ {/* 发布日期 */}
+
+
+
+ 发布日期
+
+ {citation.declare_date}
+
+
+
+
+
+ {/* 摘要片段 */}
+
+
+ 摘要片段
+
+
+ {citation.sentences}
+
+
+
+ );
+
+ // 检测是否为移动设备
+ const isMobile = () => {
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
+ navigator.userAgent
+ );
+ };
+
+ // 移动端:仅点击触发
+ // 桌面端:悬浮 + 点击都触发
+ const triggerType = isMobile() ? 'click' : ['hover', 'click'];
+
+ return (
+
+ {
+ if (!isMobile()) {
+ e.target.style.color = '#40a9ff';
+ e.target.style.textDecoration = 'underline';
+ }
+ }}
+ onMouseLeave={(e) => {
+ if (!isMobile()) {
+ e.target.style.color = '#1890ff';
+ e.target.style.textDecoration = 'none';
+ }
+ }}
+ onClick={() => {
+ setPopoverVisible(!popoverVisible);
+ }}
+ >
+ 【{citationId}】
+
+
+ );
+};
+
+export default CitationMark;
diff --git a/src/components/Citation/CitedContent.js b/src/components/Citation/CitedContent.js
new file mode 100644
index 00000000..1691e9f1
--- /dev/null
+++ b/src/components/Citation/CitedContent.js
@@ -0,0 +1,104 @@
+// src/components/Citation/CitedContent.js
+import React from 'react';
+import { Typography, Space, Tag } from 'antd';
+import { RobotOutlined, FileSearchOutlined } from '@ant-design/icons';
+import CitationMark from './CitationMark';
+import { processCitationData } from '../../utils/citationUtils';
+
+const { Text } = Typography;
+
+/**
+ * 带引用标注的内容组件
+ * 展示拼接的文本,每句话后显示上标引用【1】【2】【3】
+ * 支持鼠标悬浮和点击查看引用来源
+ *
+ * @param {Object} props
+ * @param {Object} props.data - API 返回的原始数据 { data: [...] }
+ * @param {string} props.title - 标题文本,默认 "AI 分析结果"
+ * @param {boolean} props.showAIBadge - 是否显示 AI 生成标识,默认 true
+ * @param {Object} props.containerStyle - 容器额外样式(可选)
+ *
+ * @example
+ *
+ */
+const CitedContent = ({
+ data,
+ title = 'AI 分析结果',
+ showAIBadge = true,
+ containerStyle = {}
+}) => {
+ // 处理数据
+ const processed = processCitationData(data);
+
+ // 如果数据无效,不渲染
+ if (!processed) {
+ console.warn('CitedContent: Invalid data, not rendering');
+ return null;
+ }
+
+ return (
+
+ {/* 标题栏 */}
+
+
+
+
+ {title}
+
+
+ {showAIBadge && (
+ }
+ color="purple"
+ style={{ margin: 0 }}
+ >
+ AI 生成
+
+ )}
+
+
+ {/* 带引用的文本内容 */}
+
+ {processed.segments.map((segment, index) => (
+
+ {/* 文本片段 */}
+
+ {segment.text}
+
+
+ {/* 引用标记 */}
+
+
+ {/* 在片段之间添加逗号分隔符(最后一个不加) */}
+ {index < processed.segments.length - 1 && (
+ ,
+ )}
+
+ ))}
+
+
+ );
+};
+
+export default CitedContent;
diff --git a/src/components/ErrorBoundary.js b/src/components/ErrorBoundary.js
index 0b69aef5..de2176b5 100755
--- a/src/components/ErrorBoundary.js
+++ b/src/components/ErrorBoundary.js
@@ -77,4 +77,4 @@ class ErrorBoundary extends React.Component {
}
}
-export
\ No newline at end of file
+export default ErrorBoundary;
\ No newline at end of file
diff --git a/src/components/Loading/PageLoader.js b/src/components/Loading/PageLoader.js
new file mode 100644
index 00000000..38fa4027
--- /dev/null
+++ b/src/components/Loading/PageLoader.js
@@ -0,0 +1,33 @@
+// src/components/Loading/PageLoader.js
+import React from 'react';
+import { Box, Spinner, Text, VStack } from '@chakra-ui/react';
+
+/**
+ * 页面加载组件 - 用于路由懒加载的 fallback
+ * 优雅的加载动画,提升用户体验
+ */
+export default function PageLoader({ message = '加载中...' }) {
+ return (
+
+
+
+
+ {message}
+
+
+
+ );
+}
diff --git a/src/components/Navbars/HomeNavbar.js b/src/components/Navbars/HomeNavbar.js
index 8cf5ec32..a106fb07 100644
--- a/src/components/Navbars/HomeNavbar.js
+++ b/src/components/Navbars/HomeNavbar.js
@@ -36,6 +36,7 @@ import { ChevronDownIcon, HamburgerIcon, SunIcon, MoonIcon } from '@chakra-ui/ic
import { FiStar, FiCalendar } from 'react-icons/fi';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../../contexts/AuthContext';
+import { useAuthModal } from '../../contexts/AuthModalContext';
/** 桌面端导航 - 完全按照原网站
* @TODO 添加逻辑 不展示导航case
@@ -45,7 +46,7 @@ import { useAuth } from '../../contexts/AuthContext';
const NavItems = ({ isAuthenticated, user }) => {
const navigate = useNavigate();
- if (!isAuthenticated && !user) {
+ if (isAuthenticated && user) {
return (
) : (
- // 未登录状态
+ // 未登录状态 - 单一按钮
{/* 关联描述 */}
- {stock?.relation_desc && (
+ {stock?.relation_desc?.data ? (
+ // 使用引用组件(带研报来源)
+
+ ) : stock?.relation_desc ? (
+ // 降级显示(无引用数据)
- )}
+ ) : null}
{/* 调试信息 */}
{process.env.NODE_ENV === 'development' && chartData && (
diff --git a/src/components/UserAgreementModal.js b/src/components/UserAgreementModal.js
index 98bbe7c0..34f72a25 100644
--- a/src/components/UserAgreementModal.js
+++ b/src/components/UserAgreementModal.js
@@ -18,6 +18,11 @@ const UserAgreementModal = ({ isOpen, onClose }) => {
const headingColor = useColorModeValue("gray.800", "white");
const textColor = useColorModeValue("gray.600", "gray.300");
+ // Conditional rendering: only render Modal when open
+ if (!isOpen) {
+ return null;
+ }
+
return (