Preload classic layout CSS before the blocking head loader

This commit is contained in:
Jonathan Sykes
2026-10-08 08:50:51 +08:00
parent 799b1e7ed6
commit e7a7cdc6b9
3 changed files with 15 additions and 2 deletions

File diff suppressed because one or more lines are too long

View File

@@ -70,6 +70,8 @@ test('only core scripts and styles remain eager; native fallback and active layo
const {groups}=JSON.parse(readFileSync(join(__dirname,'assets.json'),'utf8'));
const background=new Set(Object.values(groups).filter(g=>g.background).flatMap(g=>g.files));
for(const match of html.matchAll(/<(?:script\b[^>]*\bsrc|link\b[^>]*\bhref)="([^"]+)"/gi)) {
// A style preload discovers bytes without applying or blocking another layout.
if(match[0].includes('rel="preload"'))continue;
const path='/'+match[1].replace(/^\//,'').split(/[?#]/)[0];
assert.ok(!background.has(path),`${path} is not eager`);
}
@@ -88,3 +90,11 @@ test('layout-independent visibility and transport defaults stay in eager CSS',()
for(const selector of ['.stg-overlay','.deck-chips','.np-btn.done .i-save','.sleep-status .sl-ic','.ab-group','.mc-tune'])assert.ok(shared.includes(selector));
assert.ok(html.includes('href="layout-base.css"'));
});
test('classic first-visit style preload is discovered before the head loader without applying another layout',()=>{
const preload=html.match(/<link\b[^>]*rel="preload"[^>]*href="theme-classic.css"[^>]*as="style"[^>]*>/);
assert.ok(preload,'classic stylesheet has an early preload');
assert.ok(html.indexOf(preload[0])<html.indexOf('src="lazy.js"'));
assert.ok(!/<link\b[^>]*rel="stylesheet"[^>]*href="theme-classic.css"/.test(html),'the selected layout remains parser-applied by the loader');
});

View File

@@ -13,7 +13,7 @@ mkdirSync(publicDir);
mkdirSync(dataDir);
mkdirSync(join(publicDir, 'fonts'));
mkdirSync(join(publicDir, 'icons'));
writeFileSync(join(publicDir, 'index.html'), '<!doctype html><script type="application/json" id="ytp-assets">{}</script><meta name="ytp-build" content="__BUILD_TAG__"><link rel="stylesheet" href="app.css"><script src="app.js"></script><script src="https://cdn.example/x.js"></script><link rel="stylesheet" href="/root.css">');
writeFileSync(join(publicDir, 'index.html'), '<!doctype html><script type="application/json" id="ytp-assets">{}</script><meta name="ytp-build" content="__BUILD_TAG__"><link rel="preload" href="app.css" as="style"><link rel="stylesheet" href="app.css"><script src="app.js"></script><script src="https://cdn.example/x.js"></script><link rel="stylesheet" href="/root.css">');
writeFileSync(join(publicDir, 'app.css'), 'body{}');
writeFileSync(join(publicDir, 'app.js'), 'window.app=true;');
writeFileSync(join(publicDir, 'root.css'), 'body{color:red}');
@@ -99,7 +99,8 @@ describe('static delivery characterization', () => {
const html = await index.text();
const { buildTag, files } = await (await fetch(`${server.base}/api/manifest`)).json();
expect(html).toContain(`<meta name="ytp-build" content="${buildTag}">`);
expect(html).toContain(`href="app.css?v=${files['/app.css'].h}"`);
expect(html).toContain(`<link rel="preload" href="app.css?v=${files['/app.css'].h}" as="style">`);
expect(html.match(new RegExp('app\\.css\\?v='+files['/app.css'].h,'g'))).toHaveLength(2);
expect(html).toContain(`src="app.js?v=${files['/app.js'].h}"`);
expect(html).toContain('https://cdn.example/x.js');
expect(html).toContain(`href="/root.css?v=${files['/root.css'].h}"`);