[2.x] perf: frontend performance improvements — preconnect hints, fetchpriority, FOUC fix, viewport#4561
Merged
Merged
Conversation
…rity, FOUC fix, viewport - Add fetchpriority="low" to JS preload hints in FrontendServiceProvider - Add loading="eager" fetchpriority="high" decoding="async" to forum and admin logo images in blade templates (LCP improvement) - Add sessionStorage-based CSS loading: warm visits inject stylesheets synchronously before first paint to eliminate FOUC; cold visits use async preload path and set sessionStorage keys on load; stale keys from old URLs are pruned automatically - Add Document::makePreconnects() to auto-generate preconnect and dns-prefetch hints for any cross-origin CSS, JS, or preload URLs - Add explicit preconnect hints for FontAwesome CDN and Kit URLs in FrontendServiceProvider - Remove maximum-scale=1 and minimum-scale=1 from viewport meta in Meta.php, basic.blade.php, and install/app.php (accessibility: allows user zoom on mobile) - Remove IE11 X-UA-Compatible meta from installer
ekumanov
added a commit
to ekumanov/framework
that referenced
this pull request
Apr 19, 2026
…n iOS Safari iOS Safari silently drops programmatic scrollTop writes while a momentum (inertial) scroll is in flight, which causes PostStream to visibly jump when loadPrevious() prepends older posts during a flick scroll upward. Routing the restore through `window.scrollTo(x, y)` instead of jQuery's `$window.scrollTop(y)` goes through a different WebKit code path that halts the in-flight momentum and applies the new position, fixing the jump without side effects on other platforms. This behavior was unmasked by flarum#4561 (viewport meta change): on beta.8 the viewport included `maximum-scale=1, minimum-scale=1`, which put iOS in a simpler scroll pipeline where scrollTop writes typically landed; once user-zoom is allowed the zoom/scroll coordination layer starts dropping those writes. Fixes flarum#4587.
2 tasks
4 tasks
imorland
added a commit
that referenced
this pull request
May 14, 2026
…lesheet (#4664) The dual-path strategy from #4561 (sessionStorage warm cache + async preload cold path) relied on JS-injected <link rel="stylesheet"> elements blocking paint, which they do not by spec. The result was a flash of unstyled content on cross-origin asset hosts (S3 / CloudFront most visibly), on every cold tab, and intermittently on warm visits too. - makeHead() now emits a standard <link rel="stylesheet"> for forum/admin CSS. Parser-discovered, render-blocking, ~single-digit ms on a CDN. - The sessionStorage warm-path script and the noscript fallback are removed; the inline critical CSS stays as a safety net so the body has a theme-accurate background while the stylesheet is in flight. - JS preloads switch from fetchpriority="low" to "high" — now that the stylesheet blocks paint, the SPA boot is the next critical-path item. - New Document::$preHead bucket for content that must render before the stylesheet (used by the inline data-theme script so dark-mode users never see a light-flash if the browser paints before CSS arrives). Document::$head[] semantics are unchanged: items still render after the stylesheet, so admin-supplied <style>/<link> overrides correctly win the cascade.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
fetchpriorityon preloads and logo images — JS preload hints getfetchpriority="low"so they don't compete with CSS and fonts. Forum and admin logo<img>tags getloading="eager" fetchpriority="high" decoding="async"as they are typically the LCP element.sessionStorage CSS loading (FOUC fix) — On warm visits where CSS is already browser-cached, stylesheets are injected synchronously via JS before first paint, eliminating the flash of unstyled content. Cold visits use the existing async preload path and stamp sessionStorage keys on load. Stale keys from old CSS URLs are pruned automatically on each visit.
Automatic preconnect hints —
Document::makePreconnects()scans the page's CSS, JS, and preload URLs and emits<link rel="preconnect" crossorigin>+<link rel="dns-prefetch">for any cross-origin origins. Explicit hints for FontAwesome CDN and Kit URLs are also added inFrontendServiceProvider.Viewport meta fix — Removes
maximum-scale=1, minimum-scale=1from the viewport meta tag inMeta.php,basic.blade.php, andinstall/app.php. These attributes prevent user zoom on mobile, which is an accessibility issue. Theinitial-scale=1is retained.IE11 meta removed — The
X-UA-Compatiblemeta tag has been removed from the installer; IE11 has been end-of-life since June 2022.