Insight | Apr 10, 2023
What’s Next for Drupal 10?
By Nathaniel Catchpole
Drupal 10 was recently released, and the momentum hasn’t stopped there. New features and API improvements are already landing, ready for Drupal 10.1.x.
A few of the enhancements include improving performance with better CSS and Javascript aggregation, reducing the headache of writing new code, and paving the way forward with community initiatives to squash bugs and fix issues.
Third and Grove’s resident core committer takes a look ahead.
Drupal 10.0
Views responsive grid
This feature is already available in Drupal 10.0.0, but it couldn’t be added to Drupal 9.5 due to Internet Explorer 11 support, so if you haven’t updated to Drupal 10, you won’t have seen it yet. Responsive grid allows you to specify the maximum number of columns, the minimum grid cell width and the gutter spacing. When the grid cells resize to a point where they’re below the minimum width, the grid will reflow to have fewer columns. Alternatively, the grid will expand to fit as many columns as permitted while keeping the grid width above the minimum value. This saves time for developers and website owners by enabling them to configure a feature that previously required custom code or contributed modules in just a couple of minutes.
Drupal 10.1
Better CSS and JavaScript aggregation
Drupal core has shipped with CSS and JavaScript aggregation for over a decade. However, the implementation had a number of issues and pre-dated Drupal’s library API.
- Before, aggregates had to be built by the main page request.This resulted in stampedes on cold caches since no page could be served until aggregates were built and for individual pages could take hundreds of milliseconds to execution time.
- There was no built-in JavaScript minification in core.
In Drupal 10.1, completely rewritten aggregation generation logic solves both of these issues.
- Aggregates are now built by a dedicated route, with the main request only responsible for generating the aggregate URL based on libraries, theme, language and grouping logic. This change resolves the cold cache stampede as well as making things more robust against race conditions
- JavaScript minification is now provided in core, using the very reliable Peast JavaScript AST parser.
This should massively reduce, if not eliminate, the need to install contributed modules to minify JavaScript. There is also renewed work to pre-minify core Javascript and use dependencies instead of weights to make things even more efficient, which will hopefully land in a later Drupal 10 release.
Constructor property promotion
When writing new Drupal code, one of the most annoying things can be the amount of boilerplate required when defining a constructor. Property declarations which are almost identical to @param documentation.
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity repository.
*
* @var \Drupal\Core\Entity\EntityRepositoryInterface
*/
protected $entityRepository;
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The typed config manager.
*
* @var \Drupal\Core\Config\TypedConfigManagerInterface
*/
protected $typedConfigManager;
/**
* The active configuration storage.
*
* @var \Drupal\Core\Config\StorageInterface
*/
protected $activeStorage;
/**
* The event dispatcher.
*
* @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* The extension path resolver.
*
* @var \Drupal\Core\Extension\ExtensionPathResolver
*/
protected $extensionPathResolver;
/**
* Creates ConfigManager objects.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory.
* @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager
* The typed config manager.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The string translation service.
* @param \Drupal\Core\Config\StorageInterface $active_storage
* The active configuration storage.
* @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher.
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
* The entity repository.
* @param \Drupal\Core\Extension\ExtensionPathResolver $extension_path_resolver
* The extension path resolver.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config_manager, TranslationInterface $string_translation, StorageInterface $active_storage, EventDispatcherInterface $event_dispatcher, EntityRepositoryInterface $entity_repository, ExtensionPathResolver $extension_path_resolver) {
$this->entityTypeManager = $entity_type_manager;
$this->configFactory = $config_factory;
$this->typedConfigManager = $typed_config_manager;
$this->stringTranslation = $string_translation;
$this->activeStorage = $active_storage;
$this->eventDispatcher = $event_dispatcher;
$this->entityRepository = $entity_repository;
$this->extensionPathResolver = $extension_path_resolver;
}
Since Drupal 10 requires PHP 8.1, we can get rid of most of that boilerplate, so that exactly the same constructor looks like this instead:
/**
* Creates ConfigManager objects.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The configuration factory.
* @param \Drupal\Core\Config\TypedConfigManagerInterface $typedConfigManager
* The typed config manager.
* @param \Drupal\Core\StringTranslation\TranslationInterface $stringTranslation
* The string translation service.
* @param \Drupal\Core\Config\StorageInterface $activeStorage
* The active configuration storage.
* @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $eventDispatcher
* The event dispatcher.
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entityRepository
* The entity repository.
* @param \Drupal\Core\Extension\ExtensionPathResolver $extensionPathResolver
* The extension path resolver.
*/
public function __construct(
protected EntityTypeManagerInterface $entityTypeManager,
protected ConfigFactoryInterface $configFactory,
protected TypedConfigManagerInterface $typedConfigManager,
protected TranslationInterface $stringTranslation,
protected StorageInterface $activeStorage,
protected EventDispatcherInterface $eventDispatcher,
protected EntityRepositoryInterface $entityRepository,
protected ExtensionPathResolver $extensionPathResolver,
) {}
Much more compact with the same amount of actual implementation. This has already been adopted for new code, there’s a bit more involved to apply it to existing code.
PHP attributes
Since Drupal 8.0, Drupal has used annotations, a parseable code comment format, for defining metadata, for example for entity types. PHP 8 ships with attributes - native support for the same kinds of metadata, with less parsing overhead. Drupal 10 doesn’t yet support attributes, but we’re hoping to in Drupal 10.1 or as soon as possible, so we can start transitioning away from annotations before the libraries we rely on for parsing drop support for it.
Tidier issue queues
Drupal’s bugsmash and needs review queue initiatives have been making great progress triaging Drupal’s very long backlog. We’ve gone from around 7,000 bug reports to just over 5,000, and from around 2,700 issues needing review to around 250. Issues that have been stalled for years have been moved on and in some cases fixed. If you’d like to see old issues closed, get involved!
Further ahead
There’s lots coming up, with Project browser and Automatic updates both getting closer to the point where they can be added as experimental core modules. Look out for these in Drupal 10.2 or 10.3.
Drop us a line
Have a project in mind?
Contacting Third and Grove may cause awesomeness. Side effects include a website too good to ignore. Proceed at your own risk.