diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f8a68bc4596fcec15a6c0871332d240aaaa31d16..a0128ec733a0389db2d13cefe704236af6fd0917 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -69,7 +69,6 @@ variables:
 # Stages    #
 #############
 stages:
-  - 🏗️ Build
   - 🪄 Lint
   - 🗜️ Test
 
@@ -96,11 +95,7 @@ default:
 
 .with-composer: &with-composer
   needs:
-    - '📦️ Composer'
-
-.with-yarn: &with-yarn
-  needs:
-    - '📦️ Yarn'
+    - '🧹 PHP Coding standards (PHPCS)'
 
 .default-job-settings-lint: &default-job-settings-lint
   rules:
@@ -240,65 +235,22 @@ default:
   needs: [ '[Daily] PHP 8.3 SQLite 3.45' ]
   <<: [ *run-daily ]
 
-################
-# Build Jobs for linting
-################
-
-'📦️ Composer':
-  variables:
-    KUBERNETES_CPU_REQUEST: "1"
-  stage: 🏗️ Build
-  cache:
-    key:
-      files:
-        - ./composer.json
-        - ./composer.lock
-    paths:
-      - ./vendor
-  artifacts:
-    expire_in: 1 week
-    expose_as: 'web-vendor'
-    paths:
-      - vendor/
-  script:
-      - composer validate
-      - composer install --optimize-autoloader
-      - if [ -n "$COMPOSER_UPDATE" ]; then
-          composer update --optimize-autoloader;
-          composer outdated;
-        fi
-
-'📦️ Yarn':
-  variables:
-    KUBERNETES_CPU_REQUEST: "2"
-  stage: 🏗️ Build
-  cache:
-    key:
-      files:
-        - ./core/package.json
-        - ./core/yarn.lock
-    paths:
-      - ./core/node_modules
-  artifacts:
-    expire_in: 1 week
-    expose_as: 'yarn-vendor'
-    paths:
-      - core/node_modules/
-  script:
-    - cd core
-    - corepack enable
-    - yarn install
-
 ################
 # Lint Jobs
 ################
 
 '🧹 PHP Static Analysis (phpstan)':
-  <<: [ *with-composer, *default-job-settings-lint ]
+  <<: [ *default-job-settings-lint ]
   stage: 🪄 Lint
   variables:
     KUBERNETES_CPU_REQUEST: "16"
   script:
+    - composer validate
+    - composer install --optimize-autoloader
+    - if [ -n "$COMPOSER_UPDATE" ]; then
+        composer update --optimize-autoloader;
+        composer outdated;
+      fi
     - vendor/bin/phpstan --version
     # Rely on PHPStan caching to execute analysis multiple times without performance drawback.
     # Output a copy in junit.
@@ -324,19 +276,28 @@ default:
       - core/.phpstan-baseline.php
 
 '🧹 PHP Coding standards (PHPCS)':
-  <<: [ *with-composer, *default-job-settings-lint ]
+  <<: [ *default-job-settings-lint ]
   stage: 🪄 Lint
   variables:
     KUBERNETES_CPU_REQUEST: "16"
   script:
+    - composer validate
+    - composer install --optimize-autoloader
+    - if [ -n "$COMPOSER_UPDATE" ]; then
+        composer update --optimize-autoloader;
+        composer outdated;
+      fi
     - vendor/bin/phpcs --version
     - composer phpcs -- -s --report-full --report-summary --report-\\Micheh\\PhpCodeSniffer\\Report\\Gitlab=phpcs-quality-report.json
   artifacts:
+    expire_in: 1 week
+    expose_as: 'web-vendor'
+    paths:
+      - vendor/
     reports:
       codequality: phpcs-quality-report.json
 
 '🧹 JavaScript linting (eslint)':
-  <<: [ *with-yarn ]
   stage: 🪄 Lint
   variables:
     KUBERNETES_CPU_REQUEST: "2"
@@ -356,6 +317,7 @@ default:
   script:
     - cd core
     - corepack enable
+    - yarn install
     - yarn run check:ckeditor5
     - yarn run lint:core-js-passing --format gitlab
   artifacts:
@@ -363,7 +325,6 @@ default:
       codequality: eslint-quality-report.json
 
 '🧹 CSS linting (stylelint)':
-  <<: [ *with-yarn ]
   stage: 🪄 Lint
   variables:
     KUBERNETES_CPU_REQUEST: "2"
@@ -382,6 +343,7 @@ default:
   script:
     - corepack enable
     - cd core
+    - yarn install
     - yarn run build:css --check
     - yarn run lint:css --color --custom-formatter=node_modules/stylelint-formatter-gitlab
   artifacts:
@@ -389,7 +351,7 @@ default:
       codequality: stylelint-quality-report.json
 
 '📔 Spell-checking':
-  <<: [ *with-yarn, *default-job-settings-lint ]
+  <<: [ *default-job-settings-lint ]
   stage: 🪄 Lint
   variables:
     KUBERNETES_CPU_REQUEST: "2"
@@ -401,8 +363,21 @@ default:
       fi;
     - cd core
     - corepack enable
+    - yarn install
     - git diff ${CI_MERGE_REQUEST_TARGET_BRANCH_SHA:-$CI_MERGE_REQUEST_DIFF_BASE_SHA} --name-only 2>1 > /dev/null || (echo "Warning, cannot find changed files, converting to full clone." & (git fetch --unshallow --quiet && echo "Fetch successful."))
     - git diff ${CI_MERGE_REQUEST_TARGET_BRANCH_SHA:-$CI_MERGE_REQUEST_DIFF_BASE_SHA} --name-only | sed "s_^_../_" | yarn run spellcheck:core --no-must-find-files --file-list stdin
+  cache:
+    key:
+      files:
+        - ./core/package.json
+        - ./core/yarn.lock
+    paths:
+      - ./core/node_modules
+  artifacts:
+    expire_in: 1 week
+    expose_as: 'yarn-vendor'
+    paths:
+      - core/node_modules/
 
 '📔 Validatable config':
   <<: [ *default-job-settings-lint ]
@@ -412,6 +387,7 @@ default:
     _TARGET_PHP: "8.3-ubuntu"
   # Run on MRs if config schema files have changed, or manually.
   rules:
+    - if: $PERFORMANCE_TEST != "1"
     - if: $CI_PIPELINE_SOURCE == "merge_request_event"
       changes:
         - "**/config/schema/*.schema.yml"
diff --git a/.gitlab-ci/pipeline.yml b/.gitlab-ci/pipeline.yml
index aff508da840e43edefe7d75d17bfb42d6ed944e1..ca02ebd76547576de1846dd5b47c83ea8c09c17b 100644
--- a/.gitlab-ci/pipeline.yml
+++ b/.gitlab-ci/pipeline.yml
@@ -47,14 +47,14 @@ default:
 .with-composer: &with-composer
   needs:
     - pipeline: $PARENT_PIPELINE_ID
-      job: '📦️ Composer'
+      job: '🧹 PHP Coding standards (PHPCS)'
 
 .with-composer-and-yarn: &with-composer-and-yarn
   needs:
     - pipeline: $PARENT_PIPELINE_ID
-      job: '📦️ Composer'
+      job: '🧹 PHP Coding standards (PHPCS)'
     - pipeline: $PARENT_PIPELINE_ID
-      job: '📦️ Yarn'
+      job: '📔 Spell-checking'
 
 variables:
   FF_NETWORK_PER_BUILD: 1
@@ -248,7 +248,7 @@ variables:
     - <<: *with-database
 
 '🚲 Performance tests':
-  <<: [ *with-composer, *default-job-settings ]
+  <<: [ *default-job-settings ]
   rules:
     - if: $PERFORMANCE_TEST == "1"
   variables:
@@ -266,6 +266,7 @@ variables:
       [[ $_TARGET_DB == mysql* ]] && export SIMPLETEST_DB=mysql://$MYSQL_USER:$MYSQL_PASSWORD@database/$MYSQL_DATABASE?module=mysql
       [[ $_TARGET_DB == mariadb* ]] && export SIMPLETEST_DB=mysql://$MYSQL_USER:$MYSQL_PASSWORD@database/$MYSQL_DATABASE?module=mysql
       [[ $_TARGET_DB == pgsql* ]] && export SIMPLETEST_DB=pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@database/$POSTGRES_DB?module=pgsql
+    - composer install --optimize-autoloader
     - export OTEL_COLLECTOR="$OTEL_COLLECTOR"
     - mkdir -p ./sites/simpletest ./sites/default/files ./build/logs/junit /var/www/.composer
     - chown -R www-data:www-data ./sites ./build/logs/junit ./vendor /var/www/