Skip to content

Performance

Audit performed without running npm run build (no production artifacts at audit time). Numbers below are projections.

Initial bundle (projected)

  • Nuxt 2 + Vue 2 core: ~80 KB gzipped
  • BootstrapVue 2: ~70 KB gzipped (large; whole-library import)
  • Bootstrap CSS: ~50 KB
  • BlueprintJS CSS (for Polotno consistency): ~30 KB
  • App code + 73 pages: ~150-200 KB combined (Nuxt splits per page, so initial = layout + visited page)
  • Filepond + plugins: ~30 KB
  • Polotno bundle (polotno-bundle.js): 50 KB

Projected initial load: ~250-300 KB gzipped (just app shell + landing page). Adding editor pages: + 50 KB Polotno bundle on demand.

For an internal staff tool: acceptable. Staff load the app once per day; FCP is not the user's pain point.

Code splitting

Nuxt 2 auto-splits per page. Default works fine.

Tree shaking

BootstrapVue 2 is not tree-shakeable in its default Nuxt module import (bootstrap-vue/nuxt) — the whole library ships. This adds ~70 KB you don't need if you only use a handful of <b-*> components. Fix: use BootstrapVue/nuxt with the explicit component import option, listing only the components actually used.

Polotno bundle

polotno-bundle.js is 50 KB at audit time. Compare to customer FE's 221 KB — the designer bundle is much leaner (intentional, fewer features).

Polotno itself spins up React + MobX-state-tree + the Polotno UI — heavy. Once loaded, the editor is responsive but cold-start is 2-3 seconds.

Image optimisation

Designer staff upload images via filepond. The editor uses Polotno's image-handling pipeline. No Nuxt-side image optimisation. Sharp / S3-side resizing happens server-side via designer-api.

Caching strategy

  • No service worker
  • Browser cache defaults (whatever nginx sets)
  • No Vuex action caching → every page-mount re-fetches data (vs someli-platform's 5-min TTL cache)

Core Web Vitals

Not measured. No RUM. For an internal tool used daily by ~10-50 staff, acceptable.

Network footprint

Each page mount triggers ~3-10 API calls to designer-api (typical for table-heavy pages with filter dropdowns). With no caching, common filters re-fetch on every page mount.

Adding the 5-min cache from someli-platform/store/api.js would cut typical session traffic by ~50-70%.

Render performance

  • Pages with large tables (e.g., master_library.vue, content_library.vue) likely render hundreds of rows. No virtualisation observed.
  • Polotno editor handles its own rendering performance internally (React + MobX).

For internal tool scale: acceptable. If a table ever exceeds 5000 rows, virtualisation (vue-virtual-scroller) becomes worth adding.

Recommendations

ID Recommendation Effort
P-1 Switch to per-component BootstrapVue import; cut ~50 KB Small
P-2 Port someli-platform/store/api.js cache pattern; cut session traffic ~50% Medium
P-3 Self-host the Bootstrap CDN script to remove an external round-trip Small
P-4 Add web-vitals reporting (5-line wire-up) Trivial
P-5 Virtualise tables that exceed 1000 rows Medium
P-6 Audit bundle size at next major release; flag growth Trivial