OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Significant Vue performance drop after moving to yarn workspace

  • Thread starter Thread starter Tyler Wanta
  • Start date Start date
T

Tyler Wanta

Guest
I made an electron app using vue and now wanted to also make a mobile version. To accomplish this, I planned on using workspaces to share the source code between the electron app and mobile app. Previously, my file structure looked like this:

Code:
electron/
   - package.json
   - src/
      - main/ 
      - preload/
      - renderer/
          - src/
              - main.ts
              - components/
              - helpers/
              - etc.

now it looks like this

Code:
common/
    - package.json
    - src/
      - main.ts
      - components/
      - helpers/ 
      - etc.
electron/
    - package.json
    - src/
         - main/
         - preload/
         - renderer/
              - src/
                   main.ts

This is all nice and dandy, but when re testing the app after getting everything re setup, I noticed a significant performance drop (loading indicator stopped working, popups took seconds longer to appear, the main app component itself took seconds longer to mount, etc). Curious, I used console.time() and console.timeLog() to try and narrow down the issue but it seems like all of my code runs exactly the same (I'm comparing against main where all the code is still under the electron directory). The only meaningful difference I could locate is when triggering a popup. I did something like this:

Code:
// someComponent.vue
<SomePopup v-if="showPopup" />

Code:
// someFile.ts
console.time();

// trigger the popup
showPopup.value = true;

Code:
// someComponent.vue
onMounted(() => 
{
    console.timeLog();
});

In the original setup, with everything under the electron app, it would only take ~11ms for the onMounted to be reached. After moving to the workspace, it takes ~950ms+. The only thing that was changed in the source code is that I am calling an exported function to mount the app component, like so:

Code:
// common/main.ts
// import the main app
import App from "./App"
export function setupApp()
{
    const app = createApp(App);
    app.mount("#app");
}

Code:
// electron/src/renderer/src/main.ts
import { setupApp } from "common"
setupApp();

I did some more testing and decided to instead export the main app component from common, and then create it and mount it within main.ts in the electron app like so:

Code:
// common/main.ts
import App from './App.vue'
export const mainApp = App;

Code:
// electron/src/renderer/src/main.ts
import { mainApp } from "common"

const app = createApp(mainApp);
app.mount("#app");

This seemed to fix the delay / performance issue earlier mentioned when mounting the initial app component, but all other components are still extremely slow.

I have ~100 components so I would very much like to share them across multiple projects. Does anybody know how to do this effectively / what is wrong?

Here are my package.json files in case those are useful:

Code:
// root
{
    "name": "root",
    "private": "true",
    "version": "1.0.0",
    "description": "",
    "license": "ISC",
    "dependencies": {
        "lerna": "^8.1.3"
    },
    "workspaces": {
        "packages": [
            "./common",
            "./desktop"
        ]
    }
}

Code:
common/package.json
 {
    "name": "common",
    "version": "1.0.0",
    "private": true,
    "type": "module",
    "main": "./src/main.ts",
    "scripts": {
        "dev": "vite",
        "build": "run-p type-check \"build-only {@}\" --",
        "preview": "vite preview",
        "build-only": "vite build",
        "type-check": "vue-tsc --build --force"
    },
    "dependencies": {
        "vue": "^3.4.29",
        "marked": "^13.0.0",
        "qrcode": "^1.5.3",
        "tippy.js": "^6.3.7",
        "vue-chartjs": "^5.2.0",
        "@melloware/coloris": "^0.24.0",
        "@popperjs/core": "^2.11.8",
        "@serenity-kit/opaque": "^0.8.4",
        "@tweenjs/tween.js": "^21.0.0",
        "axios": "^1.6.7",
        "chart.js": "^4.4.0",
        "chartjs-plugin-zoom": "^2.0.1",
        "clipboardy": "^4.0.0",
        "d3": "^7.8.5",
        "dompurify": "^3.1.5"
    },
    "devDependencies": {
        "@tsconfig/node20": "^20.1.4",
        "@types/jsdom": "^21.1.7",
        "@types/node": "^20.14.5",
        "@vitejs/plugin-vue": "^5.0.5",
        "@vue/test-utils": "^2.4.6",
        "@vue/tsconfig": "^0.5.1",
        "jsdom": "^24.1.0",
        "npm-run-all2": "^6.2.0",
        "typescript": "~5.4.0",
        "vite": "^5.3.1",
        "vue-tsc": "^2.0.21"
    },
    "workspaces": {
        "nohoist": [
            "**"
        ]
    }
}

Code:
// electron/package.json
{
    "name": "desktop",
    "private": "true",
    "version": "1.0.0",
    "main": "./out/main/index.js",
    "homepage": "https://www.electronjs.org",
    "scripts": {
        "format": "prettier --write .",
        "lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix",
        "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
        "typecheck:web": "vue-tsc --noEmit -p tsconfig.web.json --composite false",
        "typecheck": "npm run typecheck:node && npm run typecheck:web",
        "start": "electron-vite preview",
        "dev": "electron-vite dev",
        "build": "electron-vite build",
        "postinstall": "electron-builder install-app-deps",
        "build:win": "npm run build && electron-builder --win --config",
        "build:mac": "npm run build && electron-builder --mac --config",
        "build:linux": "npm run build && electron-builder --linux --config",
        "package": "electron-vite build --outDir=dist && electron-forge package",
        "make": "electron-vite build --outDir=dist && electron-forge make"
    },
    "dependencies": {
        "@electron-toolkit/preload": "^2.0.0",
        "@electron-toolkit/utils": "^2.0.0",
        "@electron/asar": "^3.2.8",
        "electron-updater": "^6.1.1",
        "common": "1.0.0",
        "getmac": "^6.6.0",
        "@melloware/coloris": "^0.24.0",
    },
    "devDependencies": {
        "@electron-forge/cli": "^6.2.1",
        "@electron-forge/maker-deb": "^6.2.1",
        "@electron-forge/maker-rpm": "^6.2.1",
        "@electron-forge/maker-squirrel": "^6.2.1",
        "@electron-forge/maker-zip": "^6.2.1",
        "@electron-toolkit/eslint-config": "^1.0.1",
        "@electron-toolkit/eslint-config-ts": "^1.0.0",
        "@electron-toolkit/tsconfig": "^1.0.1",
        "@rushstack/eslint-patch": "^1.3.3",
        "@types/node": "^18.17.5",
        "@vitejs/plugin-vue": "^4.3.1",
        "@vue/eslint-config-prettier": "^8.0.0",
        "@vue/eslint-config-typescript": "^11.0.3",
        "electron": "30.0.6",
        "electron-builder": "^24.6.3",
        "electron-vite": "^2.2.0",
        "eslint": "^8.47.0",
        "eslint-plugin-vue": "^9.17.0",
        "less": "^4.2.0",
        "prettier": "^3.0.2",
        "typescript": "^5.1.6",
        "vite": "^5.2.11",
        "vue": "^3.3.4"
    },
    "workspaces": {
        "nohoist": [
            "**"
        ]
    }
}

<p>I made an electron app using vue and now wanted to also make a mobile version. To accomplish this, I planned on using workspaces to share the source code between the electron app and mobile app. Previously, my file structure looked like this:</p>
<pre><code>electron/
- package.json
- src/
- main/
- preload/
- renderer/
- src/
- main.ts
- components/
- helpers/
- etc.
</code></pre>
<p>now it looks like this</p>
<pre><code>common/
- package.json
- src/
- main.ts
- components/
- helpers/
- etc.
electron/
- package.json
- src/
- main/
- preload/
- renderer/
- src/
main.ts
</code></pre>
<p>This is all nice and dandy, but when re testing the app after getting everything re setup, I noticed a significant performance drop (loading indicator stopped working, popups took seconds longer to appear, the main app component itself took seconds longer to mount, etc). Curious, I used <code>console.time()</code> and <code>console.timeLog()</code> to try and narrow down the issue but it seems like all of my code runs exactly the same (I'm comparing against main where all the code is still under the electron directory). The only meaningful difference I could locate is when triggering a popup. I did something like this:</p>
<pre><code>// someComponent.vue
<SomePopup v-if="showPopup" />
</code></pre>
<pre><code>// someFile.ts
console.time();

// trigger the popup
showPopup.value = true;
</code></pre>
<pre><code>// someComponent.vue
onMounted(() =>
{
console.timeLog();
});
</code></pre>
<p>In the original setup, with everything under the electron app, it would only take <code>~11ms</code> for the <code>onMounted</code> to be reached. After moving to the workspace, it takes <code>~950ms+</code>. The only thing that was changed in the source code is that I am calling an exported function to mount the app component, like so:</p>
<pre><code>// common/main.ts
// import the main app
import App from "./App"
export function setupApp()
{
const app = createApp(App);
app.mount("#app");
}
</code></pre>
<pre><code>// electron/src/renderer/src/main.ts
import { setupApp } from "common"
setupApp();
</code></pre>
<p>I did some more testing and decided to instead export the main app component from <code>common</code>, and then create it and mount it within <code>main.ts</code> in the electron app like so:</p>
<pre><code>// common/main.ts
import App from './App.vue'
export const mainApp = App;
</code></pre>
<pre><code>// electron/src/renderer/src/main.ts
import { mainApp } from "common"

const app = createApp(mainApp);
app.mount("#app");

</code></pre>
<p>This seemed to fix the delay / performance issue earlier mentioned when mounting the initial app component, but all other components are still extremely slow.</p>
<p>I have ~100 components so I would very much like to share them across multiple projects. Does anybody know how to do this effectively / what is wrong?</p>
<p>Here are my <code>package.json</code> files in case those are useful:</p>
<pre><code>// root
{
"name": "root",
"private": "true",
"version": "1.0.0",
"description": "",
"license": "ISC",
"dependencies": {
"lerna": "^8.1.3"
},
"workspaces": {
"packages": [
"./common",
"./desktop"
]
}
}
</code></pre>
<pre><code>common/package.json
{
"name": "common",
"version": "1.0.0",
"private": true,
"type": "module",
"main": "./src/main.ts",
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --build --force"
},
"dependencies": {
"vue": "^3.4.29",
"marked": "^13.0.0",
"qrcode": "^1.5.3",
"tippy.js": "^6.3.7",
"vue-chartjs": "^5.2.0",
"@melloware/coloris": "^0.24.0",
"@popperjs/core": "^2.11.8",
"@serenity-kit/opaque": "^0.8.4",
"@tweenjs/tween.js": "^21.0.0",
"axios": "^1.6.7",
"chart.js": "^4.4.0",
"chartjs-plugin-zoom": "^2.0.1",
"clipboardy": "^4.0.0",
"d3": "^7.8.5",
"dompurify": "^3.1.5"
},
"devDependencies": {
"@tsconfig/node20": "^20.1.4",
"@types/jsdom": "^21.1.7",
"@types/node": "^20.14.5",
"@vitejs/plugin-vue": "^5.0.5",
"@vue/test-utils": "^2.4.6",
"@vue/tsconfig": "^0.5.1",
"jsdom": "^24.1.0",
"npm-run-all2": "^6.2.0",
"typescript": "~5.4.0",
"vite": "^5.3.1",
"vue-tsc": "^2.0.21"
},
"workspaces": {
"nohoist": [
"**"
]
}
}
</code></pre>
<pre><code>// electron/package.json
{
"name": "desktop",
"private": "true",
"version": "1.0.0",
"main": "./out/main/index.js",
"homepage": "https://www.electronjs.org",
"scripts": {
"format": "prettier --write .",
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix",
"typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
"typecheck:web": "vue-tsc --noEmit -p tsconfig.web.json --composite false",
"typecheck": "npm run typecheck:node && npm run typecheck:web",
"start": "electron-vite preview",
"dev": "electron-vite dev",
"build": "electron-vite build",
"postinstall": "electron-builder install-app-deps",
"build:win": "npm run build && electron-builder --win --config",
"build:mac": "npm run build && electron-builder --mac --config",
"build:linux": "npm run build && electron-builder --linux --config",
"package": "electron-vite build --outDir=dist && electron-forge package",
"make": "electron-vite build --outDir=dist && electron-forge make"
},
"dependencies": {
"@electron-toolkit/preload": "^2.0.0",
"@electron-toolkit/utils": "^2.0.0",
"@electron/asar": "^3.2.8",
"electron-updater": "^6.1.1",
"common": "1.0.0",
"getmac": "^6.6.0",
"@melloware/coloris": "^0.24.0",
},
"devDependencies": {
"@electron-forge/cli": "^6.2.1",
"@electron-forge/maker-deb": "^6.2.1",
"@electron-forge/maker-rpm": "^6.2.1",
"@electron-forge/maker-squirrel": "^6.2.1",
"@electron-forge/maker-zip": "^6.2.1",
"@electron-toolkit/eslint-config": "^1.0.1",
"@electron-toolkit/eslint-config-ts": "^1.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
"@rushstack/eslint-patch": "^1.3.3",
"@types/node": "^18.17.5",
"@vitejs/plugin-vue": "^4.3.1",
"@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^11.0.3",
"electron": "30.0.6",
"electron-builder": "^24.6.3",
"electron-vite": "^2.2.0",
"eslint": "^8.47.0",
"eslint-plugin-vue": "^9.17.0",
"less": "^4.2.0",
"prettier": "^3.0.2",
"typescript": "^5.1.6",
"vite": "^5.2.11",
"vue": "^3.3.4"
},
"workspaces": {
"nohoist": [
"**"
]
}
}
</code></pre>
 

Latest posts

S
Replies
0
Views
1
Safwan Aipuram
S
Top