Cutting a PWA homepage from 4.8 MB to 70 KB
Published
On 2026-10-09 the dev.to account Shahzaib published a report on PdfWord, a PDF tools site the post describes as free, no-signup and client-side, stating that the installed PWA took a long time to open on phones and that users complained. The post calls what followed a 20-minute fix that cut 98.5% of the weight, and it covers two separate changes: what the landing page downloads, and what the service worker precaches on install (the post).
What the measurement found
Section titled “What the measurement found”The post’s first move is a measurement rather than an optimisation. It states that the author measured what the homepage actually downloads before any change was made (the post).
The library weights the post lists
Section titled “The library weights the post lists”The post’s table gives html2pdf.bundle.min.js at 884 KB, xlsx.full.min.js at
861 KB, docx.min.js at 725 KB, pdf-lib.min.js at 512 KB, pptxgen.bundle.js at
466 KB, jspdf.umd.min.js at 410 KB, and pdf.min.js at 312 KB, followed by a row
reading “plus 25 more scripts”. The total the post prints under that table is 4.8 MB of
JavaScript on a landing page
(the post).
What the homepage actually needed
Section titled “What the homepage actually needed”The post’s account of the page’s job is that the homepage is just cards that link to tool pages, and that it needed none of the libraries in that table. Its explanation for their presence is that every library was loaded “just in case”, and it adds that the page also carried 22 dead inline tool panels from an older design (the post).
What the post removed
Section titled “What the post removed”The fix the post describes is subtraction on the landing page, with the loading of heavy dependencies pushed to the pages that use them (the post).
The deletions on the homepage
Section titled “The deletions on the homepage”The post states that it deleted the 22 dead tool panels from the homepage, noting that
dedicated tool pages already existed and putting 25 KB of dead HTML on the deletion,
and that it removed all 33 heavy <script> tags from the homepage. Its description of
the new loading rule is that each tool page still loads only the libraries it needs,
which the post labels selective per-page loading
(the post).
The file that stayed
Section titled “The file that stayed”One script survived the pass. The post states that it kept one file, common.js at
15 KB, for navigation, the theme toggle, and filters. The result it prints for the page
is 54 KB of HTML plus 15 KB of JavaScript, which it gives as roughly 70 KB in total,
down from 4.8 MB
(the post).
The service worker change
Section titled “The service worker change”The post reports a second change on the service worker side (the post).
From a library precache to an app shell precache
Section titled “From a library precache to an app shell precache”The post states that it also found the service worker was precaching about 2 MB of libraries on install, that it trimmed the precache to the app shell only at about 120 KB, and that heavy libraries now cache on-demand when their tool page is first opened. It adds that HTML uses a network-first strategy so updates reach installed apps without reinstalls (the post).
MDN documents the caching mechanisms those moves use. On precaching, MDN states that
when a service worker is installed the browser fires an install event in the service
worker’s global scope, and that at this point the service worker can precache
resources, fetching them from the network and storing them in the cache. MDN also
states that precaching is an appropriate strategy for resources that the PWA is certain
to need, that will not change for this version of the app, and that need to be fetched
as quickly as possible, giving the basic user interface of the app as its example and
adding that if this is precached then the app’s UI can be rendered on launch without
needing any network requests
(MDN, Caching).
On caching a resource the first time it is requested, MDN states that when a service
worker’s fetch event fires, the service worker may forward the request to the network
and cache the resulting response, either if the cache did not already contain a
response or to update the cached response with a more recent one. On the strategy the
post names for HTML, MDN describes “network first” as trying to retrieve the resource
from the network, returning the response and updating the cache if the request
succeeds, and trying the cache if it fails, and states that this is useful for requests
for which it is important to get the most fresh response possible but for which a
cached resource is better than nothing
(MDN, Caching).
Versioning the cache
Section titled “Versioning the cache”The post states the rule it now follows as bumping the service worker cache version on every deploy, and gives the failure it is guarding against: installed apps serve stale files forever (the post).
MDN states the same practice in its own words. Its page on the Cache interface says
that items in a Cache do not get updated unless explicitly requested and do not
expire unless deleted, that you are responsible for implementing how your script
handles Cache updates, and that you should make sure to version caches by name and
use the caches only from the version of the script that they can safely operate on. It
also states that you are responsible for periodically purging cache entries
(MDN, Cache).
MDN’s caching guide names where that purge belongs. It states that a PWA should clean
up any old versions of its cache in the service worker’s activate event, because when
this event fires the service worker can be sure that no previous versions of the
service worker are running, so old cached data is no longer needed
(MDN, Caching).
The results the post reports
Section titled “The results the post reports”The post gives three results. It reports a page load of 422 ms, attributing the figure to Cloudflare Web Analytics on real devices. It reports Core Web Vitals as 100% Good across LCP, INP, and CLS. And it states that the PWA opens instantly on 4G. Its closing advice is to audit what a landing page actually needs, and its characterisation of the pattern it removed is that “just in case” script tags are the silent killer of mobile performance (the post).
The three metric names in that second result have published targets. web.dev states that Largest Contentful Paint measures loading performance and that to provide a good user experience LCP should occur within 2.5 seconds of when the page first starts loading; that Interaction to Next Paint measures interactivity and that pages should have an INP of 200 milliseconds or less; and that Cumulative Layout Shift measures visual stability and that pages should maintain a CLS of 0.1 or less. It adds that a good threshold to measure is the 75th percentile of page loads, segmented across mobile and desktop devices, and that tools assessing Core Web Vitals compliance should consider a page passing if it meets the recommended targets at the 75th percentile for all three metrics (web.dev, Web Vitals).
Why it matters for PWA developers
Section titled “Why it matters for PWA developers”The transferable mechanism in the post is the install-time fetch. MDN describes the
service worker’s install handler as an opportunity to fetch resources from the
network and store them in the cache, a step that runs when the service worker installs
rather than when a page navigates
(MDN, Caching).
MDN also states a criterion for what belongs in that precache. It names resources the PWA is certain to need, that will not change for this version of the app, and that need to be fetched as quickly as possible, and gives the app’s basic user interface as the example (MDN, Caching).
The cache-versioning rule the post adopts has a documented basis. MDN states that items
in a Cache are not updated unless explicitly requested and do not expire unless
deleted, that caches should be versioned by name and used only from the version of the
script that can safely operate on them, and in the same place that how long a Cache
lives is browser dependent and that a browser may delete all of an origin’s Cache
Storage
(MDN, Cache).
Finally, web.dev’s framing of Core Web Vitals is a 75th-percentile threshold per metric, segmented across mobile and desktop (web.dev, Web Vitals), which is not the method the post states for its own load figure (the post).
Related entries on this site
Section titled “Related entries on this site”- Performance: the post’s subject is the startup path of an installed app and the Core Web Vitals metrics it reports against, and this page is where OpenPWA documents those metrics and the budgets around them.
- Storage: the change the post makes on the service worker side is about what occupies the cache and when it is re-keyed, and this page is where the origin-scoped stores, their quotas, and their eviction rules are covered.
- Capabilities: the libraries the post moved off the landing page exist to drive platform features from a tool page, and this page is where OpenPWA tracks which of those features a PWA can reach.
Open and unverified
Section titled “Open and unverified”- Which browsers and versions the 422 ms figure was collected from is not stated by the post, so the timing cannot be pinned to an engine.
- How the Core Web Vitals result was collected, and whether it reflects the 75th percentile threshold web.dev describes, is not stated by the post.
- Which pages the reported page load covers, and whether it is the landing page alone or the site, is not resolved by the post’s wording.
- Whether the 4.8 MB figure was measured over the network or summed from file sizes is not stated, so the 98.5% figure the post prints cannot be traced to a method.
- Whether the app shell precache the post describes is cleaned up in the
activateevent, which MDN names as the place for that work, is not addressed. - What the on-demand caching of the heavy libraries does to the origin’s storage
footprint over time is not discussed; MDN states that how long a
Cachelives is browser dependent and that a browser may delete all of an origin’s Cache Storage (MDN, Cache). - Whether the network-first strategy the post adopted for HTML has a documented offline fallback in this app is not stated.
Sources
Section titled “Sources”- How I Cut My Homepage from 4.8MB to 70KB (and Made My PWA Open Instantly) (dev.to)
- Caching (developer.mozilla.org)
- Cache (developer.mozilla.org)
- Web Vitals (web.dev)