perf: reuse a stationary reading mask during scrolling
Keep native document geometry while translating content behind one viewport fade. Preserve navigation, focus, media preloading, and Static cleanup without changing 3D quality or render resolution. Validated assets, types, production builds, prerendered artifacts and transfer budgets; compared 64 layouts and checked 87 live interactions plus uncached media and repeated cleanup. High improved from 71.7 to 101.4 FPS at DPR 1 and 47.8 to 62.2 FPS in the full-size DPR 1.5 window, with occasional sub-60 intervals still remaining.
This commit is contained in:
@@ -223,60 +223,64 @@ onUnmounted(() => removePageListeners());
|
||||
/>
|
||||
</header>
|
||||
|
||||
<main id="portfolio-content" class="portfolio-main" tabindex="-1">
|
||||
<HeroJourney :identity="content.identity" :email="content.contact.email" @explore="navigation.onSectionLinkClick" />
|
||||
<div class="reading-stage">
|
||||
<div class="reading-viewport">
|
||||
<main id="portfolio-content" class="portfolio-main" tabindex="-1">
|
||||
<HeroJourney :identity="content.identity" :email="content.contact.email" @explore="navigation.onSectionLinkClick" />
|
||||
|
||||
<PortfolioSection id="profile" :layout="sectionLayouts.profile" :heading="sectionLabel('profile')">
|
||||
<p>{{ content.profile.introduction }}</p>
|
||||
<dl class="profile-facts">
|
||||
<template v-for="fact in content.profile.screeningFacts" :key="fact.label">
|
||||
<dt>{{ fact.label }}</dt>
|
||||
<dd>{{ fact.value }}</dd>
|
||||
</template>
|
||||
</dl>
|
||||
</PortfolioSection>
|
||||
<PortfolioSection id="profile" :layout="sectionLayouts.profile" :heading="sectionLabel('profile')">
|
||||
<p>{{ content.profile.introduction }}</p>
|
||||
<dl class="profile-facts">
|
||||
<template v-for="fact in content.profile.screeningFacts" :key="fact.label">
|
||||
<dt>{{ fact.label }}</dt>
|
||||
<dd>{{ fact.value }}</dd>
|
||||
</template>
|
||||
</dl>
|
||||
</PortfolioSection>
|
||||
|
||||
<PortfolioSection id="experience" :layout="sectionLayouts.experience" :heading="sectionLabel('experience')">
|
||||
<ExperienceTimeline :experience="content.experience" :systems-operations="content.systemsOperations" />
|
||||
</PortfolioSection>
|
||||
<PortfolioSection id="experience" :layout="sectionLayouts.experience" :heading="sectionLabel('experience')">
|
||||
<ExperienceTimeline :experience="content.experience" :systems-operations="content.systemsOperations" />
|
||||
</PortfolioSection>
|
||||
|
||||
<PortfolioSection id="infrastructure" :layout="sectionLayouts.infrastructure" :heading="sectionLabel('infrastructure')">
|
||||
<InfrastructureDiagram :infrastructure="content.infrastructure" />
|
||||
</PortfolioSection>
|
||||
<PortfolioSection id="infrastructure" :layout="sectionLayouts.infrastructure" :heading="sectionLabel('infrastructure')">
|
||||
<InfrastructureDiagram :infrastructure="content.infrastructure" />
|
||||
</PortfolioSection>
|
||||
|
||||
<PortfolioSection id="selected-builds" :layout="sectionLayouts['selected-builds']" eyebrow="Selected work" :heading="sectionLabel('selected-builds')">
|
||||
<div class="project-stage__projects">
|
||||
<ProjectCaseStudy
|
||||
v-for="(project, index) in content.projects.selected"
|
||||
:key="project.id"
|
||||
:project="project"
|
||||
:priority="index < 2 ? 'primary' : 'supporting'"
|
||||
:allow-automatic-video="motion.policy.value.allowAutomaticVideo"
|
||||
/>
|
||||
</div>
|
||||
</PortfolioSection>
|
||||
<PortfolioSection id="selected-builds" :layout="sectionLayouts['selected-builds']" eyebrow="Selected work" :heading="sectionLabel('selected-builds')">
|
||||
<div class="project-stage__projects">
|
||||
<ProjectCaseStudy
|
||||
v-for="(project, index) in content.projects.selected"
|
||||
:key="project.id"
|
||||
:project="project"
|
||||
:priority="index < 2 ? 'primary' : 'supporting'"
|
||||
:allow-automatic-video="motion.policy.value.allowAutomaticVideo"
|
||||
/>
|
||||
</div>
|
||||
</PortfolioSection>
|
||||
|
||||
<PortfolioSection id="additional-work" :layout="sectionLayouts['additional-work']" :heading="sectionLabel('additional-work')">
|
||||
<div class="compact-projects">
|
||||
<ProjectCard
|
||||
v-for="project in content.projects.additional"
|
||||
:key="project.id"
|
||||
:project="project"
|
||||
:allow-automatic-video="motion.policy.value.allowAutomaticVideo"
|
||||
/>
|
||||
</div>
|
||||
</PortfolioSection>
|
||||
<PortfolioSection id="additional-work" :layout="sectionLayouts['additional-work']" :heading="sectionLabel('additional-work')">
|
||||
<div class="compact-projects">
|
||||
<ProjectCard
|
||||
v-for="project in content.projects.additional"
|
||||
:key="project.id"
|
||||
:project="project"
|
||||
:allow-automatic-video="motion.policy.value.allowAutomaticVideo"
|
||||
/>
|
||||
</div>
|
||||
</PortfolioSection>
|
||||
|
||||
<PortfolioSection id="toolkit" :layout="sectionLayouts.toolkit" :heading="sectionLabel('toolkit')">
|
||||
<ToolkitGrid :groups="content.toolkit" />
|
||||
</PortfolioSection>
|
||||
<PortfolioSection id="toolkit" :layout="sectionLayouts.toolkit" :heading="sectionLabel('toolkit')">
|
||||
<ToolkitGrid :groups="content.toolkit" />
|
||||
</PortfolioSection>
|
||||
|
||||
<PortfolioSection id="contact" :layout="sectionLayouts.contact" eyebrow="Destination" :heading="sectionLabel('contact')">
|
||||
<footer>
|
||||
<ContactDestination :contact="content.contact" />
|
||||
</footer>
|
||||
</PortfolioSection>
|
||||
</main>
|
||||
<PortfolioSection id="contact" :layout="sectionLayouts.contact" eyebrow="Destination" :heading="sectionLabel('contact')">
|
||||
<footer>
|
||||
<ContactDestination :contact="content.contact" />
|
||||
</footer>
|
||||
</PortfolioSection>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<DriveControls
|
||||
:policy="displayedPolicy"
|
||||
:maximum-quality="controlsReady ? motion.maximumQuality.value : 'high'"
|
||||
|
||||
Reference in New Issue
Block a user