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
Benchmark your current Lighthouse scores
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.
Reduce DOM size with Conditional Rendering
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.
Optimize collection fetching with lazy loading and on-demand fetch
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.
Enable DataGrid virtual scrolling for large datasets
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.
1// Supabase SQL — server-side pagination for collections2// Use with WeWeb collection offset/limit parameters3// In Supabase Dashboard → SQL Editor (NOT in WeWeb)45-- Example: paginated products query with filtering6SELECT 7 id,8 name,9 price,10 category,11 created_at12FROM products13WHERE 14 ($1::text IS NULL OR category = $1) -- filter param15 AND is_active = true16ORDER BY created_at DESC17LIMIT $2 -- page size param18OFFSET $3; -- offset param = (page - 1) * page_size1920-- Count query for pagination UI21SELECT COUNT(*) as total22FROM products23WHERE 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.
Optimize images with WebP format and proper sizing
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.
Minimize JavaScript execution time with targeted workflow design
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.
Self-host on Cloudflare Pages for global edge performance
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.
Set up Prerender.io for SEO crawlers (WeWeb has no SSR)
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.
1// Cloudflare Worker — route bots to Prerender.io2// Deploy via Cloudflare Workers dashboard3// This worker intercepts bot requests and returns pre-rendered HTML45async 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': userAgent25 }26 });27 }28 29 return fetch(request);30}3132addEventListener('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
1# WeWeb Performance Optimization Checklist23## Measurement First4- [ ] Run Lighthouse (mobile) 3x and average scores — record FCP, LCP, TBT, CLS5- [ ] Use WebPageTest for multi-geography TTFB comparison6- [ ] Check DOM node count (target: < 800)7- [ ] Review network waterfall — identify largest assets and slowest requests89## DOM Reduction (Biggest Impact)10- [ ] Convert display:none bindings to Conditional Rendering for large sections11- [ ] 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)1516## Collection / Data Fetching17- [ ] Modals and popups: change collection fetch mode to On Demand18- [ ] Large collections: enable server-side pagination (20-50 items/page)19- [ ] Reused collections across pages: enable Cached fetch mode20- [ ] Background collections (not needed for render): defer with On Demand2122## DataGrid Performance23- [ ] Enable Row Virtualization for any DataGrid with > 100 rows24- [ ] Set fixed Row Height (required for virtual scrolling)25- [ ] Use server-side pagination for > 1,000 rows (avoid loading all at once)2627## Images28- [ ] Convert all images to WebP (squoosh.app)29- [ ] Compress: hero < 100KB, card thumbnails < 30KB30- [ ] Lazy load all below-the-fold images31- [ ] Do NOT lazy load LCP element (hero image)32- [ ] Set explicit width and height on all images3334## JavaScript35- [ ] Move non-critical On page load workflows to On mounted36- [ ] Remove unused NPM packages from NPM plugin37- [ ] Offload heavy computations to backend (Supabase Edge Function)38- [ ] Audit custom JavaScript actions for O(n²) loops on large arrays3940## Hosting41- [ ] Self-host on Cloudflare Pages for international users42- [ ] Configure Cloudflare cache rules for static assets43- [ ] Set up Prerender.io for SEO crawler pre-rendering4445## 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.
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?
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.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation