Resizing and converting images occurs both in development and production mode, so you can test with the correct image dimensions and formats as well. See the Image transformer docs for more details.
Parcel also includes lossless image optimization for JPEGs and PNGs by default in production mode, which reduces the size of images without affecting their quality. This does not require any query parameters or configuration to use. However, since the optimization is lossless, the size reduction possible may be less than if you use the quality
query param, or use a modern format such as WebP or AVIF.
Parcel automatically produces a <script type="module">
with modern JavaScript syntax, as well as a fallback <script nomodule>
for older browsers when necessary. This reduces bundle sizes for a majority of users by avoiding transpilation of features like classes, async/await, and more. See Differential bundling in the Targets documentation for more details.
Parcel supports compressing bundles using Gzip and Brotli. While many servers compress data on the fly, others require you to upload pre-compressed payloads ahead of time. This may also allow for better compression, which would be too slow to do on every network request.
Because not everyone needs it, compression is not enabled by default. To enable it, add @parcel/compressor-gzip
and/or @parcel/compressor-brotli
to your .parcelrc
.
yarn add @parcel/compressor-gzip @parcel/compressor-brotli --dev
Now you’ll get a .gz
and a .br
file along side the original uncompressed bundle. If you have more text-based file types than listed in the above example, you'll need to extend the glob accordingly.
If you don’t need the uncompressed bundle, you can also remove the "..."
from the above example to only output compressed files. For example, to only output a .gz
file, you could use the following config:
Parcel includes several optimizations related to browser and CDN caching, including content hashing, bundle manifests, and shared bundles.
Parcel automatically includes content hashes in the names of all output files, which enables long-term browser caching. Whenever the contents of a bundle changes, the hash included in the filename will be updated, triggering invalidation of CDN and browser caches.
By default, all bundles include a content hash except entries and certain dependency types that require names to be stable. For example, service workers require a stable file name to work properly, and <a>
tags in HTML reference user readable URLs.
You can also disable content hashing using the --no-content-hash
CLI flag. Note that the name will still include a hash, but it will not change on each build. You can customize bundle naming completely using Namer plugins.
Parcel uses a manifest in each entry bundle to avoid the cascading invalidation problem in many cases. This manifest includes a mapping of stable bundle ids to final content hashed filenames. When one bundle needs to reference another, it uses the bundle id rather than the content hashed name. This means that when a bundle updates, only that bundle and the entry will need to be invalidated in the browser cache and intermediary bundles will not change. This improves the cache hit rate across deployments.
In production builds, Parcel automatically optimizes the bundle graph in your application to reduce duplication and improve cacheability. When multiple parts of your application depend on the same common modules, they are automatically deduplicated into a separate bundle. This allows commonly used dependencies to be loaded in parallel with your application code and cached separately by the browser.
For example, if multiple pages in your app depend on react
and lodash
, they might be moved into a separate bundle rather than duplicated in each page. This way, when a user navigates from one page to another, they only need to download the additional code for that page rather than re-downloading those libraries which are already cached.
See the Code splitting docs for more details on how to configure this.
Parcel includes some tools to help you analyze bundle sizes.
By default, Parcel outputs a bundle report in the terminal when building for production. It includes the size and build time for each output bundle. To see more details about what files make up each bundle, you can use the --detailed-report
CLI option. By default, it shows up to 10 files in each bundle, sorted by size. You can also pass a number to increase this, e.g. --detailed-report 20
.
The @parcel/reporter-bundle-analyzer
plugin can be used to generate an HTML file containing a tree map that shows the relative size of each asset in every bundle visually. You can run it using the --reporter
CLI option.
parcel build src/index.html --reporter @parcel/reporter-bundle-analyzer
This generates a folder parcel-bundle-reports
in your project root with an HTML file for every target:
You can also add it to "reporters"
in your .parcelrc
file if you want to run the bundle analyzer on every build automatically.
The @parcel/reporter-bundle-buddy
plugin can be used to generate a report that is compatible with Bundle Buddy. You can run it using the --reporter
CLI option.
parcel build src/index.html --reporter @parcel/reporter-bundle-buddy
Now upload the files in the dist
directory to the Bundle Buddy website.