From b6d0c2baf23f3fdc90b6f7628d569b69593c9201 Mon Sep 17 00:00:00 2001 From: Joker-john Date: Sat, 27 Jan 2024 18:08:32 +0800 Subject: [PATCH 1/3] chore: disable ci temporarily --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index af37933..a180e62 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,12 @@ name: CI on: - push: - branches: - - '**' - pull_request: - branches: - - main + # push: + # branches: + # - '**' + # pull_request: + # branches: + # - main # Declare default permissions as read only. permissions: read-all From 8708556aaa8650ddfa1e1981dd3d7783c44b350c Mon Sep 17 00:00:00 2001 From: Joker-john Date: Tue, 30 Jan 2024 21:05:27 +0800 Subject: [PATCH 2/3] feat: revise svelte project and add excel data integration --- index.js | 8 ++++-- package.json | 3 ++- projectList.json | 2 +- resultSort.js | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 resultSort.js diff --git a/index.js b/index.js index 3355207..ec39b3d 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,8 @@ import * as fs from 'node:fs'; import { execSync, exec } from 'node:child_process'; import * as chromeLauncher from "chrome-launcher"; -import * as path from "path"; import lighthouse from "lighthouse"; +import { sortResult } from './resultSort.js'; function install(project) { console.log('Installing: ', project.name); @@ -104,9 +104,12 @@ async function main() { // lighthouse benchmark if (args.length == 0 || args.includes("--bench")) { let port = 5000; - fs.mkdirSync('./results'); + if (!fs.existsSync('./results')) { + fs.mkdirSync('./results'); + } for (const project of projects) { if (project.name) { + console.log(`Start testing ${project.name}...`) let serve = preview(project, port); const result = await runLighthouse(`http://localhost:${port}/`); fs.writeFileSync(`./results/${project.name}.json`, JSON.stringify(result)); @@ -116,6 +119,7 @@ async function main() { port++; } } + sortResult('./results'); } // generate result diff --git a/package.json b/package.json index 2e3d046..167ffc7 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dependencies": { "chrome-launcher": "^1.1.0", "lighthouse": "^11.4.0", - "serve": "^14.2.1" + "serve": "^14.2.1", + "xlsx": "^0.18.5" } } \ No newline at end of file diff --git a/projectList.json b/projectList.json index b8cad00..40cb8d9 100644 --- a/projectList.json +++ b/projectList.json @@ -16,7 +16,7 @@ { "name":"svelte", "path":"app/realworld", - "preview":"\"node_modules/.bin/vite\" preview" + "preview":"set NODE_EXTRA_CA_CERTS=../../server/realword-express-sequelize/CA.crt && \"node_modules/.bin/vite\" preview" }, { "name":"solid", diff --git a/resultSort.js b/resultSort.js new file mode 100644 index 0000000..d4e91c7 --- /dev/null +++ b/resultSort.js @@ -0,0 +1,64 @@ +import * as xlsx from 'xlsx'; +import * as fs from 'fs'; +import * as path from 'path'; + +const FIELDS = ['Name', 'First Contentful Paint', 'Largest Contentful Paint', 'Total Blocking Time', 'Cumulative Layout Shift', 'Speed Index', 'Total Score']; + +function sortResult() { + let table = []; + table.push(FIELDS); + traverseFolder('./results', table); + + const workbook = xlsx.utils.book_new(); + const sheet = xlsx.utils.aoa_to_sheet(table); + xlsx.utils.book_append_sheet(workbook, sheet, 'Sheet1'); + + const filename = `results${getTime()}.xlsx`; + try { + xlsx.writeFile(workbook, filename); + console.log('Result output success!') + } catch(err) { + console.log('Result output fail! Error:', err); + } +} + +function getTime() { + const now = new Date(); + const dateStr = now.toLocaleString(); // 获取当前日期字符串,格式根据操作系统的区域设置而定 + const [year, month, daytime] = dateStr.split('/'); // 根据具体格式使用适当的分隔符拆分日期字符串 + const [day,time] = daytime.split(' '); + const [hour, min, sec] = time.split(':') + return `${year}-${month}-${day}-${hour}-${min}-${sec}`; +} + +// 遍历文件夹 +function traverseFolder(folderPath, table) { + const files = fs.readdirSync(folderPath); + files.forEach((file) => { + const filePath = path.join(folderPath, file); + const stats = fs.statSync(filePath); + if (stats.isDirectory()) { + traverseFolder(filePath, table); + } else { + if (file.includes(".json")) { + const jsonString = fs.readFileSync(filePath, 'utf-8'); + const jsonArray = JSON.parse(jsonString); + table.push(getFactors(jsonArray, file)); + } + } + }) +} + +function getFactors(json, file) { + return [ + file.substring(0, file.length - 5), + `${json.audits["first-contentful-paint"].displayValue}(${json.audits["first-contentful-paint"].score * 100})`, + `${json.audits["largest-contentful-paint"].displayValue}(${json.audits["largest-contentful-paint"].score * 100})`, + `${json.audits["total-blocking-time"].displayValue}(${json.audits["total-blocking-time"].score * 100})`, + `${json.audits["cumulative-layout-shift"].displayValue}(${json.audits["cumulative-layout-shift"].score * 100})`, + `${json.audits["speed-index"].displayValue}(${json.audits["speed-index"].score * 100})`, + `${json.categories.performance.score * 100}` + ] +} + +export {sortResult}; \ No newline at end of file From 06aca7705a738cbf260e9efc3dd185a2ff794040 Mon Sep 17 00:00:00 2001 From: Joker-john Date: Tue, 19 Mar 2024 14:38:41 +0800 Subject: [PATCH 3/3] feat: add data report for realworld benchmark --- index.js | 18 +++++--- package.json | 4 +- pnpm-lock.yaml | 111 +++++++++++++++++++++++++++++++++++++++++++++++ projectList.json | 9 +++- report.js | 54 +++++++++++++++++++++++ 5 files changed, 187 insertions(+), 9 deletions(-) create mode 100644 report.js diff --git a/index.js b/index.js index ec39b3d..ed6071a 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,7 @@ import * as fs from 'node:fs'; import { execSync, exec } from 'node:child_process'; import * as chromeLauncher from "chrome-launcher"; import lighthouse from "lighthouse"; -import { sortResult } from './resultSort.js'; +import { report } from './report.js'; function install(project) { console.log('Installing: ', project.name); @@ -86,7 +86,7 @@ async function main() { const args = process.argv.length <= 2 ? [] : process.argv.slice(2, process.argv.length); const projects = JSON.parse(fs.readFileSync("projectList.json")); // install - if (args.length == 0 || args.includes("--install")) { + if (args.length == 0 || args.includes("--all") || args.includes("--install")) { for (const project of projects) { if (project.name) { install(project); @@ -94,7 +94,7 @@ async function main() { } } // build - if (args.length == 0 || args.includes("--build")) { + if (args.length == 0 || args.includes("--all") || args.includes("--build")) { for (const project of projects) { if (project.name) { build(project); @@ -102,7 +102,7 @@ async function main() { } } // lighthouse benchmark - if (args.length == 0 || args.includes("--bench")) { + if (args.length == 0 || args.includes("--all") || args.includes("--bench")) { let port = 5000; if (!fs.existsSync('./results')) { fs.mkdirSync('./results'); @@ -112,14 +112,20 @@ async function main() { console.log(`Start testing ${project.name}...`) let serve = preview(project, port); const result = await runLighthouse(`http://localhost:${port}/`); - fs.writeFileSync(`./results/${project.name}.json`, JSON.stringify(result)); + if (args.includes("--upload")) { + report(project.name, result); + } else { + fs.writeFileSync(`./results/${project.name}.json`, JSON.stringify(result)); + } if (serve) { serve.kill('SIGINT'); } port++; } } - sortResult('./results'); + if (!args.includes("--upload")) { + sortResult('./results'); + } } // generate result diff --git a/package.json b/package.json index 167ffc7..9297a40 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,13 @@ "main": "index.js", "scripts": { "preinstall": "npx only-allow pnpm", - "bench": "node index.js" + "bench": "node index.js", + "report": "node index.js --upload" }, "author": "@originjs", "license": "MulanPSL-2.0", "dependencies": { + "axios": "^1.6.8", "chrome-launcher": "^1.1.0", "lighthouse": "^11.4.0", "serve": "^14.2.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4736091..5eb30c9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + axios: + specifier: ^1.6.8 + version: 1.6.8 chrome-launcher: specifier: ^1.1.0 version: 1.1.0 @@ -14,6 +17,9 @@ dependencies: serve: specifier: ^14.2.1 version: 14.2.1 + xlsx: + specifier: ^0.18.5 + version: 0.18.5 packages: @@ -155,6 +161,11 @@ packages: negotiator: 0.6.3 dev: false + /adler-32@1.3.1: + resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} + engines: {node: '>=0.8'} + dev: false + /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -230,11 +241,25 @@ packages: tslib: 2.6.2 dev: false + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + /axe-core@4.8.3: resolution: {integrity: sha512-d5ZQHPSPkF9Tw+yfyDcRoUOc4g/8UloJJe5J8m4L5+c7AtDdjDLRxew/knnI4CxvtdxEUVgWz4x3OIQUIFiMfw==} engines: {node: '>=4'} dev: false + /axios@1.6.8: + resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + /b4a@1.6.4: resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} dev: false @@ -294,6 +319,14 @@ packages: engines: {node: '>=14.16'} dev: false + /cfb@1.2.2: + resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} + engines: {node: '>=0.8'} + dependencies: + adler-32: 1.3.1 + crc-32: 1.2.2 + dev: false + /chalk-template@0.4.0: resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==} engines: {node: '>=12'} @@ -360,6 +393,11 @@ packages: wrap-ansi: 7.0.0 dev: false + /codepage@1.15.0: + resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} + engines: {node: '>=0.8'} + dev: false + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -371,6 +409,13 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: false + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + /compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} @@ -419,6 +464,12 @@ packages: engines: {node: '>= 0.6'} dev: false + /crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + dev: false + /cross-fetch@4.0.0: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} dependencies: @@ -492,6 +543,11 @@ packages: esprima: 4.0.1 dev: false + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + /devtools-protocol@0.0.1203626: resolution: {integrity: sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g==} dev: false @@ -620,6 +676,30 @@ packages: pend: 1.2.0 dev: false + /follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /frac@1.1.2: + resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} + engines: {node: '>=0.8'} + dev: false + /fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -1265,6 +1345,13 @@ packages: jpeg-js: 0.4.4 dev: false + /ssf@0.11.2: + resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==} + engines: {node: '>=0.8'} + dependencies: + frac: 1.1.2 + dev: false + /streamx@2.15.6: resolution: {integrity: sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==} dependencies: @@ -1449,6 +1536,16 @@ packages: string-width: 5.1.2 dev: false + /wmf@1.0.2: + resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==} + engines: {node: '>=0.8'} + dev: false + + /word@0.3.0: + resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==} + engines: {node: '>=0.8'} + dev: false + /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -1511,6 +1608,20 @@ packages: engines: {node: '>=8'} dev: false + /xlsx@0.18.5: + resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} + engines: {node: '>=0.8'} + hasBin: true + dependencies: + adler-32: 1.3.1 + cfb: 1.2.2 + codepage: 1.15.0 + crc-32: 1.2.2 + ssf: 0.11.2 + wmf: 1.0.2 + word: 0.3.0 + dev: false + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} diff --git a/projectList.json b/projectList.json index 40cb8d9..42a76ee 100644 --- a/projectList.json +++ b/projectList.json @@ -1,6 +1,6 @@ [ { - "name":"vue3", + "name":"vue", "path":"app/vue3-realworld-app" }, { @@ -34,7 +34,7 @@ "preview":"\"node_modules/.bin/vite\" preview" }, { - "name":"ember", + "name":"ember.js", "path":"app/ember-realworld", "build":"set NODE_OPTIONS=--openssl-legacy-provider && \"node_modules/.bin/ember\" build --environment=production" }, @@ -74,5 +74,10 @@ "install":"cargo install wasm-pack && cargo install --locked trunk", "build":"cd crates/conduit-wasm && trunk build", "dist":"crates/conduit-wasm/dist" + }, + { + "name":"million", + "path":"app/million-realworld-example-app", + "dist":"build" } ] \ No newline at end of file diff --git a/report.js b/report.js new file mode 100644 index 0000000..2056713 --- /dev/null +++ b/report.js @@ -0,0 +1,54 @@ +import { platform as _platform } from "os"; +import axios from "axios"; + +const techStack = "前端框架"; +const REPORT_URL='http://8.134.178.105:3000'; +const url = REPORT_URL; +const BOOST_PERFORMANCE = Object.freeze([ + 'first-contentful-paint', + 'largest-contentful-paint', + 'total-blocking-time', + 'cumulative-layout-shift', + 'speed-index']) + +export async function report(project, jsonData) { + const patchId = await getPatchId(); + const res = dealdata(project, jsonData, patchId.toString()); + await postData(res); +} + +async function getPatchId() { + const { data: patchId } = await axios.post( + `${url}/sync/benchmark/getPatchId`, + {}, + ); + console.log("patchId: ", patchId); + return patchId.toString(); +} + +function dealdata(projectName, jsonData, patchId) { + const res = []; + for (let bench of BOOST_PERFORMANCE) { + res.push({ + projectName, + benchmark: bench, + techStack, + rawValue: jsonData.audits[bench].numericValue, + patchId, + platform: _platform(), + }) + } + return res; +} + +async function postData(res) { + for (let data of res) { + try { + console.log(data); + const response = await axios.post(`${url}/sync/benchmark`, data); + console.log(response.data); + } catch (error) { + console.error(error); + } + } +} \ No newline at end of file