Skip to main content
RapidDev - Software Development Agency
weweb-tutorial

WeWeb Performance: Lighthouse Scores, Load Times, and Optimization

WeWeb generates Vue.js SPAs that typically score 20-50 on mobile Lighthouse. Improve scores by: using Conditional Rendering to reduce DOM size, lazy-loading collections instead of all-on-page-load, enabling DataGrid virtual scrolling for large datasets, converting images to WebP, implementing server-side pagination, and self-hosting on Cloudflare for edge CDN. WeWeb has no SSR support as of 2026 — prerendering via Prerender.io is required for SEO crawlers.

What you'll learn

  • Why WeWeb SPAs score 20-50 on mobile Lighthouse and which Core Web Vitals are hardest to optimize
  • How to reduce DOM size using Conditional Rendering and lazy collection fetching
  • How to implement server-side pagination and DataGrid virtual scrolling for large datasets
  • How to optimize images (WebP conversion, lazy loading) and reduce page weight
  • How self-hosting on Cloudflare improves global load times compared to WeWeb Cloud
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced13 min read60-90 minWeWeb Free plan and above; some optimizations require Essential+ for self-hostingMarch 2026RapidDev Engineering Team
TL;DR

WeWeb generates Vue.js SPAs that typically score 20-50 on mobile Lighthouse. Improve scores by: using Conditional Rendering to reduce DOM size, lazy-loading collections instead of all-on-page-load, enabling DataGrid virtual scrolling for large datasets, converting images to WebP, implementing server-side pagination, and self-hosting on Cloudflare for edge CDN. WeWeb has no SSR support as of 2026 — prerendering via Prerender.io is required for SEO crawlers.

WeWeb Performance: Lighthouse Scores, Load Times, and Optimization

WeWeb generates single-page applications — the same architecture as React and Vue.js apps built by developers. SPAs have known performance characteristics: excellent interactivity after initial load, but slower time-to-first-meaningful-content because the browser must download, parse, and execute JavaScript before rendering anything. WeWeb apps additionally carry the WeWeb runtime and component library, adding baseline bundle weight. Mobile Lighthouse scores of 20-50 are common for unoptimized WeWeb apps. This tutorial covers the optimization strategies that make the biggest difference: DOM reduction, smart collection fetching, image optimization, and CDN selection. Note: WeWeb does not support server-side rendering (SSR) as of 2026 — all content is rendered client-side.

Prerequisites

  • A published WeWeb project to benchmark (you need a live URL to run Lighthouse)
  • Access to Google Lighthouse (built into Chrome DevTools → Lighthouse tab)
  • Basic understanding of WeWeb collections and how data fetching works
  • Optional: Cloudflare or Vercel account for self-hosting experiments

Step-by-step guide

1

Benchmark your current Lighthouse scores

Before optimizing, establish your baseline. Open your published WeWeb app URL in Chrome (not the editor preview). Open Chrome DevTools (F12 or Cmd+Option+I) → click the Lighthouse tab → select Mobile category (this is harder to score and more representative of real users) → click Analyze page load. Wait 30-60 seconds for the report. Record your scores for: Performance (most important — target 70+), First Contentful Paint (FCP), Largest Contentful Paint (LCP), Total Blocking Time (TBT), and Cumulative Layout Shift (CLS). Screenshot the report. Also note the Opportunities and Diagnostics sections — these show specific items causing poor scores. Run Lighthouse 3 times and average the scores, as single runs can vary by 10-15 points due to network conditions.

Expected result: You have a baseline Lighthouse report showing current scores and specific opportunities, which you will compare against after applying optimizations.

2

Reduce DOM size with Conditional Rendering

Large DOM trees are a primary cause of poor WeWeb Lighthouse scores. Every element on a page — visible or hidden via display:none — adds to the DOM and increases memory usage, style recalculation time, and layout time. Lighthouse flags pages with more than 800 DOM nodes as problematic. Audit your project: for each page, identify large sections that only some users will see (admin panels, premium content, expanded detail views, alternative UI states). Convert their visibility from CSS display binding to Conditional Rendering. Conditional Rendering uses Vue's v-if under the hood — elements do not exist in the DOM at all when the condition is false. In the editor: select the section → Settings tab (right panel) → Conditional Rendering → bind to the appropriate condition. Focus on the biggest sections first: a hidden admin panel with 50 elements has more impact than a single hidden button.

Expected result: DOM node count decreases, particularly for pages with role-based content or multi-state UIs. Lighthouse style recalculation and layout times improve.

3

Optimize collection fetching with lazy loading and on-demand fetch

By default, WeWeb collections configured on a page fetch their data when the page loads — even if the data is not immediately visible to the user. On pages with multiple collections, this creates parallel network requests at page load that compete with rendering. Audit your page's collections: Data panel → Collections → look at each collection's fetch mode. For collections that are only needed when a user takes an action (clicking a tab, opening a modal, expanding a section), change their fetch mode to 'On demand' — they will only fetch when explicitly triggered by a workflow action. For collections that contain large datasets, enable pagination (limit to 20-50 items per page). For collections used across many pages, consider 'Cached' mode — WeWeb caches the response and avoids re-fetching on every page navigation.

Expected result: Page load network waterfall shows fewer parallel requests at initial load, reducing Time to First Byte and Total Blocking Time.

4

Enable DataGrid virtual scrolling for large datasets

WeWeb's DataGrid component is built on AG Grid and supports virtual scrolling — a technique where only the rows currently visible in the viewport are rendered in the DOM, not all rows. Without virtual scrolling, a DataGrid with 1,000 rows renders 1,000 DOM rows, causing severe performance issues. To enable virtual scrolling: select your DataGrid element → open the Settings tab (right panel) → find the Row Virtualization setting → enable it. Also configure Row Height to a fixed pixel value (required for virtual scrolling to calculate row positions). With virtual scrolling enabled, a 10,000-row DataGrid renders only ~30 rows in the DOM at any given time, regardless of total row count. For data that is not in a DataGrid (e.g., a repeating container with hundreds of items), implement server-side pagination using collection pagination settings to limit items fetched.

typescript
1// Supabase SQL — server-side pagination for collections
2// Use with WeWeb collection offset/limit parameters
3// In Supabase Dashboard → SQL Editor (NOT in WeWeb)
4
5-- Example: paginated products query with filtering
6SELECT
7 id,
8 name,
9 price,
10 category,
11 created_at
12FROM products
13WHERE
14 ($1::text IS NULL OR category = $1) -- filter param
15 AND is_active = true
16ORDER BY created_at DESC
17LIMIT $2 -- page size param
18OFFSET $3; -- offset param = (page - 1) * page_size
19
20-- Count query for pagination UI
21SELECT COUNT(*) as total
22FROM products
23WHERE
24 ($1::text IS NULL OR category = $1)
25 AND is_active = true;

Expected result: DataGrid with virtual scrolling renders only visible rows, with smooth scrolling even for datasets with thousands of rows.

5

Optimize images with WebP format and proper sizing

Images are typically the largest assets on any web page and a major contributor to slow LCP (Largest Contentful Paint) scores. For images in WeWeb: first, convert all JPG and PNG images to WebP format before uploading — WebP is 25-35% smaller than JPG at equivalent quality. Use Squoosh (squoosh.app) or ImageOptim to convert and compress. When uploading images to WeWeb, verify you are uploading WebP files. For images in repeating containers (product cards, user avatars, content lists), enable lazy loading: select the Image element → Settings tab → find the Loading property → set to 'lazy'. Lazy loading defers image loading until the image is about to scroll into view. For hero images and above-the-fold content that affects LCP, do NOT lazy load them — they should load immediately. Also ensure images have explicit width and height attributes set to prevent layout shifts (CLS).

Expected result: Lighthouse shows improved LCP timing, reduced image transfer sizes in the Opportunities section, and lower Cumulative Layout Shift from properly sized images.

6

Minimize JavaScript execution time with targeted workflow design

WeWeb's workflow system executes JavaScript at runtime. Heavy workflows that run on page load, complex formula evaluations that run on every render, and large custom JavaScript actions all contribute to Total Blocking Time (TBT). To reduce JavaScript execution: audit your 'On page load' and 'On app load' workflows — these run before the page renders and block the main thread. Move any workflows that are not needed for initial rendering to 'On mounted' (runs after initial render) or to on-demand triggers. Review custom JavaScript actions for expensive operations: sorting large arrays, complex string manipulations, or deeply nested loops. Consider moving heavy computations to your backend (Supabase Edge Function or Xano) and fetching the pre-computed result instead. Also audit the NPM packages installed via the NPM plugin — each package adds to your JavaScript bundle. Remove packages you no longer use.

Expected result: Total Blocking Time decreases, page becomes interactive sooner after initial load, and Lighthouse JavaScript execution time metrics improve.

7

Self-host on Cloudflare Pages for global edge performance

WeWeb Cloud hosts on AWS infrastructure, which performs well in US and European regions but can be slower for users in Asia, South America, or Africa. Cloudflare Pages distributes your static files across 300+ edge locations globally, meaning users in any region get files served from a nearby server. To measure the difference: use WebPageTest (webpagetest.org) to run tests from multiple geographic locations against both your WeWeb Cloud URL and a Cloudflare Pages URL. To self-host on Cloudflare: set up GitHub sync in App Settings → Git Integration → connect your GitHub repo. In Cloudflare dashboard → Pages → Create a project → Connect to Git → select your WeWeb repository. Set the build command to empty (WeWeb pre-builds), output directory to / (root). Deploy. For apps with significant international user bases, self-hosting on Cloudflare Pages typically reduces Time to First Byte by 50-80% for non-US/EU users compared to WeWeb Cloud.

Expected result: WebPageTest from international locations shows significantly reduced TTFB (Time to First Byte) compared to WeWeb Cloud hosting.

8

Set up Prerender.io for SEO crawlers (WeWeb has no SSR)

WeWeb apps are single-page applications with no server-side rendering (SSR). This means when Google's crawler or social media scrapers (Facebook, Twitter, LinkedIn) request your page, they receive an empty HTML shell with a JavaScript file — not pre-rendered content. Google can index JavaScript-rendered content but with delays of days to weeks. Social media OG tags (for link previews) are particularly affected — scrapers often do not execute JavaScript. Prerender.io solves this by pre-rendering your pages to static HTML on a schedule and serving that HTML to bots while serving the SPA to real users. Integration: set up Prerender.io → configure your CDN (Cloudflare, Vercel, or Netlify) to detect bot User-Agents and route them to Prerender.io instead of your SPA. This is the recommended approach for any WeWeb app that needs search engine visibility.

typescript
1// Cloudflare Worker — route bots to Prerender.io
2// Deploy via Cloudflare Workers dashboard
3// This worker intercepts bot requests and returns pre-rendered HTML
4
5async function handleRequest(request) {
6 const url = new URL(request.url);
7 const userAgent = request.headers.get('User-Agent') || '';
8
9 const botPatterns = [
10 'Googlebot', 'bingbot', 'Slurp', 'DuckDuckBot', 'Baiduspider',
11 'YandexBot', 'facebookexternalhit', 'Twitterbot', 'LinkedInBot',
12 'WhatsApp', 'Slackbot', 'TelegramBot'
13 ];
14
15 const isBot = botPatterns.some(bot =>
16 userAgent.toLowerCase().includes(bot.toLowerCase())
17 );
18
19 if (isBot) {
20 const prerenderUrl = `https://service.prerender.io/${url.toString()}`;
21 return fetch(prerenderUrl, {
22 headers: {
23 'X-Prerender-Token': 'YOUR_PRERENDER_TOKEN',
24 'User-Agent': userAgent
25 }
26 });
27 }
28
29 return fetch(request);
30}
31
32addEventListener('fetch', event => {
33 event.respondWith(handleRequest(event.request));
34});

Expected result: Google Search Console shows your WeWeb pages with actual content in the page rendering preview. Social media link previews correctly show OG tags and images.

Complete working example

performance-optimization-checklist.md
1# WeWeb Performance Optimization Checklist
2
3## Measurement First
4- [ ] Run Lighthouse (mobile) 3x and average scores record FCP, LCP, TBT, CLS
5- [ ] Use WebPageTest for multi-geography TTFB comparison
6- [ ] Check DOM node count (target: < 800)
7- [ ] Review network waterfall identify largest assets and slowest requests
8
9## DOM Reduction (Biggest Impact)
10- [ ] Convert display:none bindings to Conditional Rendering for large sections
11- [ ] Admin panels Conditional Rendering (role-based)
12- [ ] Modal content Conditional Rendering (only render when modal opens)
13- [ ] Tab panel content Conditional Rendering (only render active tab)
14- [ ] Premium content Conditional Rendering (plan-gated)
15
16## Collection / Data Fetching
17- [ ] Modals and popups: change collection fetch mode to On Demand
18- [ ] Large collections: enable server-side pagination (20-50 items/page)
19- [ ] Reused collections across pages: enable Cached fetch mode
20- [ ] Background collections (not needed for render): defer with On Demand
21
22## DataGrid Performance
23- [ ] Enable Row Virtualization for any DataGrid with > 100 rows
24- [ ] Set fixed Row Height (required for virtual scrolling)
25- [ ] Use server-side pagination for > 1,000 rows (avoid loading all at once)
26
27## Images
28- [ ] Convert all images to WebP (squoosh.app)
29- [ ] Compress: hero < 100KB, card thumbnails < 30KB
30- [ ] Lazy load all below-the-fold images
31- [ ] Do NOT lazy load LCP element (hero image)
32- [ ] Set explicit width and height on all images
33
34## JavaScript
35- [ ] Move non-critical On page load workflows to On mounted
36- [ ] Remove unused NPM packages from NPM plugin
37- [ ] Offload heavy computations to backend (Supabase Edge Function)
38- [ ] Audit custom JavaScript actions for O(n²) loops on large arrays
39
40## Hosting
41- [ ] Self-host on Cloudflare Pages for international users
42- [ ] Configure Cloudflare cache rules for static assets
43- [ ] Set up Prerender.io for SEO crawler pre-rendering
44
45## Target Scores (Mobile Lighthouse)
46| Score Range | Status | Priority |
47|-------------|------------------|-------------------|
48| 0-49 | Poor | Immediate action |
49| 50-69 | Needs improvement| Moderate priority |
50| 70-89 | Good | Maintenance mode |
51| 90-100 | Excellent | Ideal |

Common mistakes

Why it's a problem: Running Lighthouse in the WeWeb editor preview and getting different scores than the published app

How to avoid: Always run Lighthouse on your published app URL, not the editor preview. The editor loads additional WeWeb tooling that inflates page weight. Published production builds are significantly lighter and more representative of real user experience.

Why it's a problem: Loading all collection data on page load when most of it is not immediately visible

How to avoid: Change collection fetch mode to 'On demand' for any collection that is not needed for the initial render — modal content, tabs content, expandable sections, and search results. Trigger the fetch in a workflow when the user actually needs the data.

Why it's a problem: Expecting WeWeb to support SSR or static site generation (SSG) for SEO

How to avoid: WeWeb generates client-side SPAs only — there is no SSR or SSG option as of 2026. For SEO-critical pages, use Prerender.io to serve pre-rendered HTML to search engine bots, or use a separate SSG platform (Next.js, Astro, Webflow) for content pages and WeWeb only for the app portion.

Why it's a problem: Using a repeating container for thousands of items without pagination

How to avoid: Repeating containers render all items in the DOM simultaneously. For large datasets, implement server-side pagination: limit the collection to 20-50 items, add a Paginator element, and update the collection offset variable when the user navigates pages. For tabular data specifically, use DataGrid with virtual scrolling enabled instead of repeating containers.

Best practices

  • Always benchmark with Lighthouse on mobile before and after each optimization — mobile scoring is more sensitive and represents the majority of web traffic
  • Prioritize DOM reduction over image optimization — removing unused DOM elements often has more impact than image compression alone
  • Use Conditional Rendering aggressively for any content that is not visible in the initial viewport — every element not rendered is memory and time saved
  • Self-host on Cloudflare Pages if your users are geographically distributed — the TTFB improvement for non-US/EU users is significant
  • Implement Prerender.io from day one if SEO matters to your business — retroactively fixing SPA SEO indexing issues can take months
  • Profile your collection fetching pattern for every page — the most common performance issue in WeWeb apps is over-fetching data on page load
  • Use server-side pagination and filtering for any collection that could grow over 100 items — client-side filtering of large collections is expensive and does not scale

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

My WeWeb app is scoring 35 on mobile Lighthouse. The biggest issues are Total Blocking Time (800ms) and Largest Contentful Paint (4.2s). My app has 12 collections that all fetch on page load and a DataGrid with 500 rows. What are the highest-impact optimizations I should tackle first to improve my score above 60?

WeWeb Prompt

In my WeWeb project, I have a dashboard page with 8 collections that all fetch on page load. Most of these collections are for charts and tables that are below the fold or in hidden tabs. How do I change collection fetch modes in WeWeb so only the critical data loads on page load, and the rest loads when the user actually needs it?

Frequently asked questions

Does WeWeb support server-side rendering (SSR) for better Lighthouse scores?

No. WeWeb generates client-side single-page applications (SPAs) only. There is no SSR or static site generation (SSG) option in WeWeb as of 2026. This is a known architectural limitation. For pages where SSR is critical (landing pages, blog content, SEO-sensitive pages), consider using a separate SSG platform for those pages and WeWeb only for authenticated application pages.

What is a realistic Lighthouse performance score to target for a WeWeb app?

A well-optimized WeWeb app can realistically achieve 60-80 on mobile Lighthouse with the techniques in this tutorial. Scores of 90+ are possible for simple, content-light pages but difficult to achieve for data-heavy application pages due to the SPA architecture and WeWeb runtime overhead. Desktop scores are typically 20-30 points higher than mobile scores.

Will upgrading my WeWeb hosting plan improve my Lighthouse scores?

Indirectly. Upgrading hosting plans primarily affects session limits and server capacity, not raw page load performance. The most impactful Lighthouse improvements come from code-level optimizations (DOM reduction, lazy loading, image compression). For TTFB improvements specifically, self-hosting on Cloudflare Pages (available with Essential+ seat plan) typically outperforms WeWeb Cloud regardless of hosting tier.

How do I measure Core Web Vitals for my WeWeb app in production (real user data, not just Lighthouse)?

Use Google Search Console → Core Web Vitals report for field data from real Chrome users (available after your site has enough traffic). Also check PageSpeed Insights (pagespeed.web.dev) which shows both lab data (Lighthouse) and field data (Chrome User Experience Report). The Web Vitals Chrome extension shows real-time Core Web Vital measurements as you browse your own site.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.