Drupal CSS and JavaScript aggregation on modern core

Drupal core handles CSS and JavaScript aggregation on current versions, so AdvAgg is no longer the tool to plan around. This page explains what core does, what remains for your theme and what to confirm before you rely on it.

On this page

What Drupal core aggregation does and when you still need to plan for it

If your site is slow on the front end and someone installed AdvAgg to fix it, the first thing to know is that Drupal core has aggregated CSS and JavaScript itself since Drupal 10.1. For that purpose, AdvAgg is obsolete: it duplicates a job core now does, and keeping it adds a contributed dependency that must be tested on every update. On a modern core, the aggregation controls sit on the Performance page at /admin/config/development/performance, where you enable the Aggregate CSS files and Aggregate JavaScript files options and then clear caches. Before you remove AdvAgg, record its current settings and confirm which of its features the site actually uses, so the removal is a planned change with a tested rollback.

Core aggregation does not settle front-end performance on its own, and teams still need to plan asset work for three reasons. First, the theme and contributed modules decide how many libraries load on each template, so unused CSS and JavaScript attached to every page will be aggregated and still shipped. Second, third-party tags for analytics, consent and chat load outside aggregation and often weigh more than the Drupal files. Third, the Drupal line matters: Drupal 11 is the current major version, and Drupal 10 reaches end of life on December 9, 2026. Ask your team to confirm which Drupal line each site runs before you scope any asset work, because the answer changes the upgrade sequence.

Start with a measured baseline on a staging copy of production. Use browser developer tools to list the stylesheets and scripts loaded on your highest-traffic templates, and compare page weight and request counts with aggregation enabled and disabled. Then assign each finding an owner: theme developers for library dependencies, the marketing or content team for tags, and the platform team for the cache and server settings covered on the sibling pages. Check your upgrade timing against the Drupal core release schedule so that front-end changes are made once, on the version you intend to keep.

Which aggregation approach fits which situation

This table compares four ways to handle CSS and JavaScript delivery on Drupal: core aggregation, retained AdvAgg on older versions, CDN or reverse proxy caching of asset files, and theme-level build tooling. Read each row for when the option fits, what it leaves unsolved and what to confirm before choosing. The main takeaway is that these layers stack, so most sites combine core aggregation with edge caching and keep build tooling for source quality rather than as a substitute for aggregation.

ApproachWhen it fitsWhat it does not solveWhat to confirm before choosing
Core CSS and JavaScript aggregationDrupal 10.1 or later sites that want the default bundling and minification without an extra contributed moduleDelivery from a single origin, cache lifetimes at the edge, and the size of individual theme or library filesWhether your site's current core version includes the aggregation behavior you expect and that your theme declares libraries correctly
Retained AdvAgg on older versionsSites still on a Drupal version that predates core aggregation changes and that cannot yet upgradeThe module is treated as obsolete for modern core, so it is not a path for new builds or current upgradesYour exact Drupal version, the module release in use, and a dated plan to remove it during the upgrade
CDN or reverse proxy caching of asset filesSites with traffic spread across regions or heavy anonymous traffic where assets should be served from the edgeAggregation logic, unused CSS, or render-blocking resources inside the page itselfCache headers sent for aggregated files, how the CDN keys cache entries, and whether purging is needed when a theme deploys
Theme-level build toolingThemes with large component libraries where the team wants source maps, linting, tree shaking or a managed bundleCore aggregation already merges and minifies; a build step does not replace it, and it adds a pipeline to maintainWhich build tool your theme team already runs, who owns the output, and how library definitions point to built files
Front-end performance work in the themePages where loading order, unused styles, deferred scripts and image sizing drive the measured problemServer-side bundling or edge delivery problems, which need configuration outside the themeCurrent measurements from your own pages and which assets load on each template before any change is scoped

Why AdvAgg is obsolete on modern Drupal core

The contributed AdvAgg module was installed on many Drupal 7 and Drupal 8 sites to fill gaps in how core combined and cached CSS and JavaScript files. Core aggregation now covers that role on current versions, so on Drupal 10.1 and later, treat AdvAgg as obsolete unless a specific, documented need says otherwise. Do not decide this from memory. Check the module's Drupal.org project page for its current status and supported core versions, then compare its features with the core change records for your target version. On the site, confirm that the css.preprocess and js.preprocess keys in system.performance match the baseline your performance plan expects, and that aggregated files load correctly after a cache rebuild.

The main risk is carrying the module through an upgrade. A contributed module that changes how assets are generated, served or cleared can conflict with core behavior during a major version change, and it may not be tested against the core and PHP versions you are moving to. Drupal 10 reaches end of life on December 9, 2026, and Drupal 12 is scheduled for the week of December 7, 2026 and requires PHP 8.5 or later. A site still running AdvAgg will reach that upgrade with one more dependency to verify. Run the Upgrade Status module to flag contributed projects that do not support the target version, and record AdvAgg's status alongside the other contributed modules in the upgrade plan, instead of assuming it is harmless because the site has been stable.

Before removal, inventory every place AdvAgg is used. Find the package with composer show drupal/advagg, search exported configuration for advagg keys, and check whether any custom code, theme library or hosting rule depends on its file names or cache behavior. Plan the removal in a branch, deploy it through your normal configuration and release process, clear caches, and test pages that load the largest CSS and JavaScript bundles for both anonymous and authenticated users. If a CDN or reverse proxy sits in front of the site, confirm how asset paths will be purged after the change, because stale copies at the edge can keep serving old files. Plan theme-level front-end performance work as a separate workstream.

How to audit and confirm asset aggregation on a live site

This sequence confirms which Drupal version and PHP runtime the site uses, checks the aggregation settings, removes any leftover AdvAgg installation, clears caches, and verifies the output in staging before the change reaches production. The result is a documented record that the site serves core-aggregated CSS and JavaScript and behaves correctly for real users.

  1. Confirm the Drupal version and PHP runtime

    Identify the running Drupal core version and the PHP version on every web node, using drush status and the Status report at /admin/reports/status. Compare both against the Drupal.org PHP requirements: Drupal 10 requires PHP 8.1 or later, Drupal 11 requires PHP 8.3 or later, and Drupal 12 requires PHP 8.5 or later. The step is complete when the team has a written record of core version, PHP version and any node that differs from the others. Confirm the current core release status with the Drupal core release schedule before deciding what the site should target.

  2. Review the performance aggregation settings

    Open the Performance page at /admin/config/development/performance and record whether CSS and JavaScript aggregation are enabled, along with the cache and page compression settings. Check the theme and library definitions in *.libraries.yml files for any custom aggregation logic that overrides core behavior. The step is complete when the settings are exported or screenshotted and the team knows whether aggregation is on in every environment, since a site with it disabled will serve unaggregated assets regardless of the module set.

  3. Find and remove AdvAgg if it is installed

    List installed modules with drush pm:list --status=enabled and search the output and the composer.json file for advagg. If the module is present, uninstall it through the admin interface or with drush pm:uninstall advagg, then remove the package with Composer and delete any AdvAgg-specific settings from configuration. Core aggregation replaces the functions AdvAgg provided for most sites, so the aim is removal rather than replacement. The step is complete when no AdvAgg code is loaded on any environment and the configuration export has no AdvAgg keys left behind.

  4. Clear caches on every web node

    Rebuild caches with drush cache:rebuild on each web node, and clear any reverse proxy, CDN or opcode cache that sits in front of the application. Multi-server sites need this run on each node, or the old aggregated file names may persist on the nodes that were not cleared. The step is complete when each node reports a successful rebuild and the first request to a sample page returns references to newly generated aggregated file names, which confirms the rebuild reached the served assets.

  5. Verify aggregated asset output in staging

    On a staging copy with production-like configuration, load a representative set of pages and inspect the HTML source for <link> and <script> tags pointing to files under the public assets path. Confirm that the file count is reduced compared with an unaggregated baseline and that the file names change after a CSS or JavaScript change. The step is complete when the team has a recorded list of pages, the asset URLs served for each, and the baseline comparison, which shows what core aggregation produces on this site.

  6. Test page behavior and front-end functionality

    Run the agreed test pages through the core user flows, including logged-in and anonymous views, forms, menus, media, and any JavaScript-driven components such as sliders or modals. Check the browser console for errors and confirm that scripts load in the expected order, since aggregation can change execution order when libraries depend on each other. The step is complete when the test script passes on at least the supported browsers the business uses, and every defect is logged with its page and asset reference.

  7. Record the result and repeat the check after releases

    Write a short audit record covering the Drupal version, PHP version, aggregation settings, AdvAgg status, cache steps, staging results and any open defects. Repeat the verification after each core update, theme release or module change, because a new library version can change asset names or ordering. The step is complete when the record is stored with the release documentation and the owner of the front-end stack has agreed the recheck trigger in writing.

Front-end performance work that stays in the theme

Aggregation combines files and minifies them, but the size of what it combines is set by the theme. A theme that ships a large framework stylesheet, a full icon font or several JavaScript libraries sends that weight to every visitor, however tidy the aggregated output looks. Reducing it starts with an inventory of what each page actually loads and why.

  • Unused styles: Core aggregation does not remove selectors that no template uses. Purge unused CSS during the build, or scope component styles so they load only where the component renders.
  • Bundled JavaScript libraries: Check whether the theme pulls in a full library for one feature, and whether a core or contributed library already provides that behavior.
  • Per-route differences: Split assets by template or component where page types differ widely, so an article does not load search or checkout widgets.
  • Build tooling: Keep the compile step, such as a bundler or Sass pipeline, reproducible in version control so output sizes can be compared between releases.

Check the transferred size of CSS and JavaScript on your top templates before and after each change, using the browser's network panel or a lab tool your team already trusts.

Security and operational considerations for aggregated assets

Aggregated CSS and JavaScript sits on the critical path of every page, so a policy gap, a stale release or a broken asset directory affects all visitors at once. The cards below cover the security and operational checks that keep core aggregation safe and predictable over the life of the site.

Content Security Policy and inline scripts

Aggregated bundles are served as files, but inline <style> and <script> blocks added by themes, modules or tag managers still need a policy. Core's aggregation changes which files a page loads, so a policy written against old filenames can block the new bundles. Check the policy against the rendered page after each change, and list every third-party script origin the theme depends on before tightening script-src.

Third-party scripts in the aggregate

Libraries declared with external URLs are not merged into local bundles, so they load separately and outside your aggregation controls. Each external script runs with the same privileges as your own code. Keep an inventory of external libraries in the theme's *.libraries.yml files, and review it whenever a module adds a widget or analytics tag.

Staying on a supported core release

Security fixes for core and contributed projects ship on a fixed cadence, and Drupal's security releases come out on Wednesdays. A theme or module that pins an old core constraint can block the update that carries a fix. Confirm that your theme's core_version_requirement allows the current supported release, and schedule updates so security releases are applied within the same week.

Maintaining the theme after core updates

Core aggregation logic changes between minor releases, and custom libraries that depend on load order or on specific aggregate behavior can break silently. Treat the theme as code with its own tests. Run a visual regression and a JavaScript console check on key templates after every core update, before the update reaches production.

Cache clears and aggregate regeneration

Aggregated files are generated on demand and then reused, so a full cache clear forces every visitor's first request to rebuild bundles. On a busy site this shows up as slow first loads and extra load on the web server. Plan deploy steps so the cache clear and a warm-up request run in the same release window, and test the timing on a staging copy of production traffic.

File permissions on the asset directory

Core writes aggregated files to the public files directory, usually under sites/default/files/css and sites/default/files/js. If the web server user cannot write there, pages can fall back to unaggregated assets or fail to render. If deployment tooling resets ownership, the same failure returns. Confirm the write permission for the PHP user, and check that the deployment process preserves it in each environment, including containers with read-only root filesystems.

Questions teams ask about Drupal asset aggregation

What drives the cost of a Drupal front-end performance review?

The cost follows the written scope, and the main drivers are the number of page templates to measure, the number of themes and libraries loaded on each page, and whether the review covers only asset delivery or also rendering and third-party scripts. Some costs are one-time, such as the review and any agreed fixes. Others recur if you keep a retainer for regression checks after releases. Your internal costs are staff time for access, test accounts and decisions. Ask for a quote that lists the page types measured, the devices and network profiles tested, the environments covered, and whether fixes are included or only recommendations. DeployOpen does not publish prices, so the quote follows from that scope.

How long does a Drupal asset aggregation audit take to complete?

The length depends on how many page templates and content types need measurement, how many themes and modules add assets, and whether a staging environment with production-like content is available from the start. A typical audit moves through an inventory of loaded CSS and JavaScript, a baseline measurement for each page type, analysis of what each library contributes, written findings, and optionally a verification pass after fixes. Delays usually come from waiting for access or representative content rather than from the analysis itself. Ask for a timeline in the written scope with milestones tied to when you provide access and staging, so both sides can see what affects the schedule.

What access and staging must we provide for a performance review?

Most reviews need a short list of inputs before work starts:

  • Read access to the codebase, including the custom theme, the Composer files and the module list.
  • A staging environment that matches production in code and configuration, with representative content and media.
  • Test accounts for anonymous visitors and for each role that sees a different page.
  • Read access to web server, reverse proxy or CDN configuration, if any of these alter asset URLs or headers.
  • A named contact who can approve theme changes and decide on fixes.

If production data is copied to staging, confirm with your data protection owner how personal data is removed or masked before the copy leaves production.

Can our internal team run a Drupal asset aggregation review themselves?

Yes, a team with solid Drupal theming and front-end skills can run the review, and many do. The work is mostly measurement and reading how each page declares and loads its libraries. The usual blind spots are authenticated pages, cache contexts that change which assets a visitor receives, and scripts injected by tag managers or other modules. Internal teams also tend to carry the review alongside release work. An external reviewer adds an independent view and fixed deliverables. Decide before starting who will own the fixes and the regression checks after each release, because those tasks outlast the review itself.

Is removing AdvAgg from a Drupal 11 site risky?

The risk is manageable when you test before you remove anything. AdvAgg duplicates aggregation behavior that core now provides, so the removal is mainly about confirming that the same files load in the same order on each page type. Watch for changed asset file names, which can break CDN rules or hard-coded references, for third-party scripts that depended on AdvAgg's handling, and for theme libraries that were only working because of an aggregation side effect. Compare loaded assets before and after on staging, clear caches, and check the browser console on key templates. Drupal 11 is the current major version, and Drupal 10 reaches end of life on December 9, 2026, so confirm which core version you run before planning the change. The Drupal core release schedule lists those dates.

How does theme complexity change the effort for asset work?

Effort rises with the number of libraries, base and sub-themes, component libraries and JavaScript that runs on page load without a declared library. Each extra dependency means another place where an asset can load on pages that do not need it, and another place where two libraries can conflict. A small theme with a few libraries is usually quick to trace. A theme with a component system, several base themes and many contributed modules that attach their own assets takes longer, because each dependency needs to be mapped to the pages that use it. Ask the reviewer to state how many themes, components and attached libraries are in scope, since those counts shape the quote more than page count alone.

Which front-end performance work stays in the theme after core aggregation?

Core aggregation combines and compresses files, but it does not decide which files a page needs. That decision stays in the theme and in the modules that attach libraries:

  • Declaring libraries at the level of each component, so pages load only the CSS and JavaScript they use.
  • Deferring or loading non-critical scripts after the first render, and removing unused CSS where the design allows it.
  • Setting image dimensions, formats, lazy loading and responsive sources in templates and image styles.
  • Governing third-party scripts through a tag management process with an owner and a review date.
  • Checking that cache headers and edge purging keep updated assets in step with the theme.

How DeployOpen scopes and supports Drupal performance work

Asset performance work starts with a written scope. Before any change to aggregation or front-end assets, DeployOpen and the client agree in writing which pages, themes and contributed modules are in scope, which browsers and traffic profiles matter, and what evidence will show the work is finished. For this topic that means naming the theme libraries that add CSS and JavaScript, the preprocess_css and preprocess_js settings in the environment, any contributed modules that still alter aggregation, and the baseline measurements taken before changes. A fixed-scope agreement makes these decisions explicit, so the client can compare the proposal with an internal estimate and see which items are one-time work and which recur.

Changes are delivered inside the client's own infrastructure. Configuration, theme code and any removal of obsolete modules are committed to the client's Git repository and deployed through the client's own pipeline to their staging and production environments, whether those run on cloud accounts, data centers or air-gapped networks. DeployOpen documents each setting that changed, the reason for it and the rollback step, and hands over the verification evidence: before and after page reports, the cache rebuild procedure after deploys, and the list of assets that remain in the theme. The client keeps ownership of the repository, the hosting and the credentials throughout. Ask the proposal to state who runs which deployment step and where logs are kept.

Ongoing support and upgrades are available as retainers. Asset behavior can shift with each Drupal core release, so the scope should say who checks aggregation and theme output after each bugfix or security release. The Drupal core release schedule sets the cadence for those releases, and DeployOpen can cover that monitoring, regression checks and upgrade work under a retainer agreed separately from the initial scope. Performance results are not guaranteed by this page, so ask any partner, DeployOpen included, to define the measurements and acceptance criteria in the written scope before work begins.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.