[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,340 @@
|
||||
---
|
||||
id: web-origin-trial-platform
|
||||
title: Origin Trials / Platform APIs — modern browser
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [web, browser, vibe-coding]
|
||||
tech_stack: { language: "TS", applicable_to: ["Frontend"] }
|
||||
applied_in: []
|
||||
aliases: [origin trial, Chrome flags, platform API, Web Bundles, FedCM, Topics API, Storage Buckets]
|
||||
---
|
||||
|
||||
# Origin Trials / Modern Platform APIs
|
||||
|
||||
> Browser 의 새 API 가 origin trial 식 (early access). **FedCM, Topics, Storage Buckets, Compute Pressure, Document PIP**.
|
||||
|
||||
## 📖 핵심 개념
|
||||
- Origin trial: 6 month-1 year, opt-in.
|
||||
- Token 가 specific origin 만.
|
||||
- Browser flag: 개발자 전용.
|
||||
- 진짜 launch 가 모든 user.
|
||||
|
||||
## 💻 코드 패턴
|
||||
|
||||
### Origin trial 등록
|
||||
```html
|
||||
<!-- HTML -->
|
||||
<meta http-equiv='origin-trial' content='YOUR_TOKEN_HERE' />
|
||||
|
||||
<!-- 또는 HTTP header -->
|
||||
Origin-Trial: YOUR_TOKEN_HERE
|
||||
```
|
||||
|
||||
→ Chrome / Edge developer site 가 token 발급.
|
||||
|
||||
### FedCM (Federated Credential Management)
|
||||
```ts
|
||||
// Sign in with Google (modern)
|
||||
const credential = await navigator.credentials.get({
|
||||
identity: {
|
||||
providers: [{
|
||||
configURL: 'https://accounts.google.com/gsi/fedcm.json',
|
||||
clientId: 'YOUR_CLIENT_ID',
|
||||
}],
|
||||
},
|
||||
}) as IdentityCredential;
|
||||
|
||||
const token = credential.token;
|
||||
```
|
||||
|
||||
→ 3rd-party cookie 종료 의 답.
|
||||
|
||||
### Topics API (privacy ad)
|
||||
```ts
|
||||
// Browser 가 user 의 interest topic 자동 추론.
|
||||
const topics = await document.browsingTopics();
|
||||
// → ['/Sports/Soccer', '/News/Politics']
|
||||
```
|
||||
|
||||
→ 3rd-party cookie 의 ad alternative.
|
||||
ETP / Privacy Sandbox.
|
||||
|
||||
### Storage Buckets
|
||||
```ts
|
||||
// 기존: localStorage / IndexedDB 가 1 origin 의 1 storage.
|
||||
// 새: 매 bucket 의 own quota / persistence.
|
||||
|
||||
const bucket = await navigator.storageBuckets.open('user-data', {
|
||||
durability: 'strict',
|
||||
persisted: true,
|
||||
});
|
||||
|
||||
const idb = bucket.indexedDB;
|
||||
const cache = await bucket.caches.open('v1');
|
||||
```
|
||||
|
||||
→ Per-feature storage. Eviction 따로.
|
||||
|
||||
### Compute Pressure
|
||||
```ts
|
||||
const observer = new PressureObserver((records) => {
|
||||
for (const r of records) {
|
||||
console.log(r.source, r.state); // 'cpu', 'nominal' / 'fair' / 'serious' / 'critical'
|
||||
}
|
||||
});
|
||||
|
||||
await observer.observe('cpu', { sampleInterval: 1000 });
|
||||
```
|
||||
|
||||
→ "User 가 CPU 가 hot" → quality ↓.
|
||||
Video call / game 친화.
|
||||
|
||||
### Document Picture-in-Picture
|
||||
```ts
|
||||
const pipWindow = await documentPictureInPicture.requestWindow({
|
||||
width: 400,
|
||||
height: 300,
|
||||
});
|
||||
|
||||
pipWindow.document.body.appendChild(myElement);
|
||||
```
|
||||
|
||||
→ HTML 가 PIP. Video 만 X (전 element).
|
||||
Video call, music player.
|
||||
|
||||
### Web Bundles (resource bundle)
|
||||
```html
|
||||
<link rel='resourcebundle' href='resources.wbn' />
|
||||
```
|
||||
|
||||
→ 1 file 가 multiple resource. Subresource cache 친화.
|
||||
|
||||
### Speculation rules (preload navigation)
|
||||
```html
|
||||
<script type='speculationrules'>
|
||||
{
|
||||
"prerender": [{
|
||||
"where": { "href_matches": "/products/*" },
|
||||
"eagerness": "moderate"
|
||||
}]
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
→ Anchor hover 시 prerender. Click = instant.
|
||||
|
||||
### Anchor positioning (CSS)
|
||||
```css
|
||||
.tooltip {
|
||||
position: absolute;
|
||||
position-anchor: --my-button;
|
||||
top: anchor(bottom);
|
||||
left: anchor(center);
|
||||
}
|
||||
|
||||
#my-button {
|
||||
anchor-name: --my-button;
|
||||
}
|
||||
```
|
||||
|
||||
→ Floating UI 의 native (Chrome 125+).
|
||||
|
||||
### View timeline (scroll animation)
|
||||
```css
|
||||
@keyframes fade-in {
|
||||
from { opacity: 0; transform: translateY(20px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.fade {
|
||||
animation: fade-in linear;
|
||||
animation-timeline: view();
|
||||
animation-range: entry 0% cover 50%;
|
||||
}
|
||||
```
|
||||
|
||||
→ Scroll 위치 따라 animation. JS 없음.
|
||||
|
||||
### Container queries (modern)
|
||||
```css
|
||||
.card {
|
||||
container-type: inline-size;
|
||||
container-name: card;
|
||||
}
|
||||
|
||||
@container card (min-width: 400px) {
|
||||
.title { font-size: 2rem; }
|
||||
}
|
||||
```
|
||||
|
||||
→ Media query 가 container 의 size.
|
||||
|
||||
### View Transitions (cross-doc, MPA)
|
||||
```html
|
||||
<meta name='view-transition' content='same-origin'>
|
||||
```
|
||||
|
||||
```css
|
||||
@view-transition {
|
||||
navigation: auto;
|
||||
}
|
||||
```
|
||||
|
||||
→ MPA 가 SPA 같은 transition.
|
||||
→ [[Web_View_Transitions_Cross_Doc]].
|
||||
|
||||
### CSS @scope
|
||||
```css
|
||||
@scope (.card) to (.children) {
|
||||
h2 { color: blue; }
|
||||
}
|
||||
```
|
||||
|
||||
→ CSS-in-JS 의 native alternative.
|
||||
|
||||
### CSS nesting
|
||||
```css
|
||||
.card {
|
||||
padding: 16px;
|
||||
|
||||
& h2 { font-size: 1.5rem; }
|
||||
|
||||
&:hover { background: #eee; }
|
||||
}
|
||||
```
|
||||
|
||||
→ Sass 비슷, native.
|
||||
|
||||
### Popover API
|
||||
```html
|
||||
<button popovertarget='my-popover'>Open</button>
|
||||
<div id='my-popover' popover='auto'>Content</div>
|
||||
```
|
||||
|
||||
→ Modal 의 native. Light dismiss / focus.
|
||||
|
||||
### Dialog (mature)
|
||||
```html
|
||||
<dialog id='my-dialog'>
|
||||
<p>Hello</p>
|
||||
<button onclick='this.closest("dialog").close()'>Close</button>
|
||||
</dialog>
|
||||
|
||||
<button onclick='document.getElementById("my-dialog").showModal()'>Open</button>
|
||||
```
|
||||
|
||||
### URLPattern API
|
||||
```ts
|
||||
const pattern = new URLPattern({ pathname: '/users/:id' });
|
||||
const match = pattern.exec('https://example.com/users/123');
|
||||
console.log(match?.pathname.groups.id); // '123'
|
||||
```
|
||||
|
||||
→ Router 의 native.
|
||||
|
||||
### Web Codecs
|
||||
```ts
|
||||
const decoder = new VideoDecoder({
|
||||
output: (frame) => { /* draw to canvas */ },
|
||||
error: (e) => console.error(e),
|
||||
});
|
||||
|
||||
decoder.configure({ codec: 'avc1.640028' });
|
||||
decoder.decode(chunk);
|
||||
```
|
||||
|
||||
→ Low-level video decode. Real-time / WebRTC.
|
||||
|
||||
### Web GPU (mature)
|
||||
```ts
|
||||
const adapter = await navigator.gpu.requestAdapter();
|
||||
const device = await adapter!.requestDevice();
|
||||
// Compute / render.
|
||||
```
|
||||
|
||||
→ ML inference, 3D.
|
||||
→ [[Frontend_WebGPU_Patterns]].
|
||||
|
||||
### Browser support
|
||||
```
|
||||
- Chrome / Edge: 가장 빠름.
|
||||
- Firefox: 일부 ship, 일부 안.
|
||||
- Safari: 가장 보수적.
|
||||
|
||||
→ Progressive enhancement.
|
||||
```
|
||||
|
||||
### Polyfill
|
||||
```ts
|
||||
// Container queries: postcss-container-queries (build-time).
|
||||
// Popover: floating-ui + dialog.
|
||||
// View Transitions: 자동 fallback (DOM 가 즉시 변경).
|
||||
```
|
||||
|
||||
### Chrome flags (개발자)
|
||||
```
|
||||
chrome://flags/
|
||||
- Enable specific feature.
|
||||
- 매 user 가 다른.
|
||||
|
||||
→ Production 가정 X. Origin trial 가 답.
|
||||
```
|
||||
|
||||
### Origin trial 의 lifecycle
|
||||
```
|
||||
1. Proposal (W3C).
|
||||
2. Implementation (Chrome).
|
||||
3. Origin trial (6 month-1 year, opt-in).
|
||||
4. Ship default 또는 deprecate.
|
||||
5. 다른 browser ship.
|
||||
|
||||
→ "Future-proof" check (caniuse.com).
|
||||
```
|
||||
|
||||
### Production usage
|
||||
```
|
||||
Modern web app 가:
|
||||
- View Transitions (Astro, Next).
|
||||
- Container Queries (Tailwind 4).
|
||||
- Popover (Radix).
|
||||
- Dialog (HTML5).
|
||||
- URL Pattern (router).
|
||||
|
||||
→ Modern feature 가 점진 mainstream.
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준
|
||||
| Feature | 추천 |
|
||||
|---|---|
|
||||
| 3rd-party cookie 종료 | FedCM |
|
||||
| Privacy ad | Topics API |
|
||||
| Storage organize | Storage Buckets |
|
||||
| Battery / quality | Compute Pressure |
|
||||
| HTML PIP | Document PIP |
|
||||
| Modal | Popover / Dialog |
|
||||
| Router | URL Pattern |
|
||||
| Video low-level | Web Codecs |
|
||||
| Container query | CSS Container Queries |
|
||||
| Anchor position | CSS Anchor |
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Origin trial production assume**: 끝나면 깨짐.
|
||||
- **Polyfill 없음 (older browser)**: 깨짐.
|
||||
- **Caniuse 안 봄**: 가정.
|
||||
- **Chrome flag prod**: 다른 user 안 됨.
|
||||
- **Token expire 무시**: 1 year 후 break.
|
||||
|
||||
## 🤖 LLM 활용 힌트
|
||||
- Origin trial = early access (token).
|
||||
- View Transitions / Container / Popover = mature.
|
||||
- FedCM / Topics = 3rd-party cookie 종료 답.
|
||||
- Caniuse 가 reality.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[Web_View_Transitions_Cross_Doc]]
|
||||
- [[Frontend_View_Transitions_Deep]]
|
||||
- [[Web_File_System_Access]]
|
||||
Reference in New Issue
Block a user