August 4, 2025
DISCLAIMER: This analysis is for educational purposes only. All trademarks mentioned are property of their respective owners. Catchmetrics is not affiliated with Polymarket or any other companies mentioned. Views expressed are solely those of the author, CatchMetrics Ltd.
JavaScript bundle size is particularly critical - large bundles slow down load times, degrade user experience, and harm SEO rankings. Our recent analysis of Polymarket.com, a popular Next.js application, revealed how their JavaScript bundle ballooned to an astonishing 9 MB (minified, uncompressed). According to our previous blog post where we looked into data from 300,000 sites using Next.js that lands them in the 98th percentile, indicating significant optimization opportunities. Here's our detailed breakdown and recommendations to prevent similar issues.
In Next.js, "bundle size" refers to the total size of all JavaScript files sent to the browser during the initial page load. Large bundle sizes can significantly delay load times, negatively impacting user experience and search engine optimization. Typically, these excessive sizes arise due to several factors including inefficient module imports, inclusion of unused or redundant code, insufficient utilization of tree-shaking techniques (which help eliminate unused code during build time), and inadequate implementation of code-splitting strategies (which divide JavaScript into smaller chunks that load only when required). Effectively managing these areas ensures optimal application performance and enhanced user interactions.
Bundle size isn’t an abstract build‑time metric - it directly surfaces in Core Web Vitals(CWV) data. The screenshot below comes from CrUX Vis for Polymarket’s origin on mobile devices.
Metric | 75th‑percentile value | Status | Trend |
---|---|---|---|
Largest Contentful Paint (LCP) | ~4.7 s | Poor (red) | Brief improvement Apr - May 2025 → regressing again by June 2025 |
Interaction to Next Paint (INP) | ~497 ms | Needs Improvement (amber) | Uptick to poor in late 2024, improved in Apr – May 2025, now holding steady |
Cumulative Layout Shift (CLS) | 0.07 | Good (green) | Sharp improvement in Jan 2025, got worse in March - June, fixed in July 2025 |
Why CLS is fine: layout stability is dominated by visual assets and CSS, both of which Polymarket handles reasonably well. The site’s pain points are squarely tied to JavaScript weight and main‑thread blocking.
METHODOLOGY DISCLAIMER: This analysis was conducted using only publicly accessible web assets that are served to all users visiting the website. No proprietary information, private source code, or internal systems were accessed. All findings are based on standard web development analysis techniques applied to public resources.
To investigate Polymarket’s bundle size issues, we:
This process also restored many code comments that were included in the public source maps. We did not have access to any private source or build process documentation as part of this experiment. As such, there may be errors or omissions, but we thought it was a very interesting approach to demonstrating common Next.js bundle optimization opportunities.
Our analysis uncovered several critical practices significantly inflating their bundle size:
Instead of selectively importing only what's needed, the entire Lodash library was imported unnecessarily. This typically happens when developers use default or wildcard imports like import _ from 'lodash', which pulls in the entire library - even if only a single utility function like capitalize or isEqual is needed. Lodash includes a large number of utility methods that can significantly bloat a bundle when fully included. By switching to named imports for only the used methods, or by leveraging modular alternatives such as lodash-es or per-method packages, this issue can be avoided and bundle size can be dramatically reduced. We’ve also explored this topic more broadly in our own guide on optimizing bundle size in Next.js. Check out the "Lodash Optimisation and Tree‑Shaking" section in our blog post: Optimizing Next.js performance: bundles, lazy loading, and images.
Bad example:
import _, { capitalize } from "lodash";
Good example:
import { isEqual, capitalize } from "lodash";
Selective imports allow effective tree-shaking, substantially reducing bundle size.
Using import * as syntax disables tree-shaking in modern JavaScript build tools, such as Webpack or SWC, because the bundler cannot determine which parts of the library are actually used. As a result, the entire module - including all functions, utilities, and side-effect code - is included in the final bundle, regardless of what your application needs. This dramatically inflates the bundle size and slows down performance, especially on initial load. The issue becomes more pronounced when working with large UI libraries, analytics SDKs, or polyfill-heavy modules. We’ve also explored this topic more broadly in our own guide on optimizing bundle size in Next.js. Check out the "Avoiding Wildcard (import *) Imports" section in our blog post: Optimizing Next.js performance: bundles, lazy loading, and images. Major affected libraries in Polymarket's case include:
Typical examples:
import * as Sentry from "@sentry/nextjs";
import * as LabelPrimitive from "@radix-ui/react-label";
import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
import * as amplitudeClient from "@amplitude/analytics-browser";
import * as amplitudeServer from "@amplitude/analytics-node";
import * as RPNInput from "react-phone-number-input";
import * as yup from "yup";
Polymarket utilized 16 barrel files, which hinder tree-shaking and unnecessarily enlarge bundles. Barrel files are modules that re-export several components or functions from different parts of the codebase using a single export * from syntax. While they can simplify import paths and improve code organization, they come at the cost of tree-shaking efficiency. Since bundlers can't determine which specific exports are used when everything is exported, the entire contents of those modules usually get included in the final bundle - even if only one utility is actually needed. This results in larger JavaScript payloads and slower page loads, especially for apps with extensive shared utilities or component libraries. We’ve also explored this topic more broadly in our own guide on barrel file optimizations: https://www.catchmetrics.io/blog/nextjs-bundle-size-improvements-optimize-your-performance. This is a sample barrel file from Polymarket.com:
export * from "./store";
export * from "./helpers";
export * from "./provider";
export * from "./selectors";
export * from "./types";
export * from "./adapters";
export * from "./init";
Download our service guide to understand how we can help you optimise your site speed
Polymarket.com uses a total of an estimated 277 third-party libraries, which is unfortunately not unusual for a modern web application, especially one with real-time features, complex UI components, and analytics integration. However, 43 of these libraries remain above 100 kB even after tree-shaking - highlighting potential opportunities for size reduction and performance gains. Large third-party dependencies are often the most substantial contributors to bundle bloat, particularly when they're used inconsistently or imported inefficiently. We’ve also explored this topic more broadly in our own guide on optimizing bundle size in Next.js. Check out the "Replacing Large Libraries with Smaller Alternatives" section in our blog post: Stop Shipping Bloat: Practical Bundle Diet for Next.js Developers. Below we highlight some of the most significant contributors, along with strategies for minimizing their impact on the bundle:
Viem (~350 kB minified) / @ethersproject (~900 kB minified):
Sentry (~400 kB minified):
Lodash (~70 kB minified):
@radix-ui packages (~700 kB minified):
Recharts (~570 kB minified):
@amplitude packages (~400 kB minified):
Animation Libraries (framer-motion ~185 kB / motion ~92 kB minified):
html2canvas (~197 kB minified):
date-fns (~77 kB minified):
country-flag-icons (~350 kB minified):
Another often overlooked source of payload bloat in Next.js apps is the __NEXT_DATA__ script - an inline JSON blob that powers server-rendered or statically generated pages. In the case of Polymarket.com, this page-data weighs in at an astonishing 2.4 MB, which is nearly the entire HTML payload (2.5 MB total). This kind of data-heavy output can drastically delay time-to-interactive, especially on slower networks or mobile devices.
In the case of Polymarket.com, getStaticProps is used to prefetch a large number of queries via prefetchQuery and prefetchInfiniteQuery methods. While the implementation does include pruning of returned data using lists of allowed keys for objects like markets, events, and series, the total amount of structured content returned across queries remains extremely large. Even with pruning logic in place, the combination of many concurrent prefetches, deeply nested object graphs, and repetitive query patterns causes the resulting HTML to balloon in size. Because this JSON blob is injected into the page during SSR and parsed on the client, it directly impacts initial load and interactivity.
To address this:
We break this down further in our blog post: Next.js Page Data Deep Dive and Performance Insights.
While third-party libraries account for a significant portion of bundle size, there are a few other practical strategies Polymarket - and similar apps - can adopt to further enhance performance:
Another optimization opportunity lies in caching strategy. Polymarket.com currently returns the following cache-control header for its HTML documents:
cache-control: public, max-age=0, must-revalidate
If you're concerned about your site's bundle sizes and want to ensure the best possible performance, reach out to us at Catch Metrics! We can help and give you a free health check of your NextJS site.
LEGAL NOTICE: This analysis constitutes fair use for educational and commentary purposes. All code snippets shown are for illustrative purposes only. Performance metrics and optimization recommendations are based on publicly available information and general best practices. Actual results may vary. No warranty or guarantee is provided regarding the accuracy or completeness of this analysis. Readers should conduct their own assessments before making technical decisions.
Download our service guide to understand how
we can help you optimise your site speed