Bug 306900
| Summary: | BFCache fails to restore pages when iframe performs cross-site navigation (Site Isolation=Off, BFCache=On) | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Basuke Suzuki <basuke> |
| Component: | New Bugs | Assignee: | Basuke Suzuki <basuke> |
| Status: | RESOLVED FIXED | ||
| Severity: | Normal | CC: | webkit-bug-importer |
| Priority: | P2 | Keywords: | InRadar |
| Version: | WebKit Nightly Build | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
Basuke Suzuki
When an iframe navigates to a cross-site URL, a new BackForwardList entry is created with a new BackForwardItemIdentifier (itemID). However, the BackForwardCache (BFCache) uses this itemID as its key, causing a mismatch between:
- The itemID used when saving to BFCache (old itemID from before iframe navigation)
- The itemID used when restoring from BFCache (new itemID after iframe navigation)
This results in BFCache misses even though the main frame content hasn't changed.
Steps to Reproduce
1. Navigate to page A with an iframe (same-site HTML)
2. Navigate the iframe to a cross-site page B
3. Navigate the main frame to page C (no iframe)
4. Go back → Step 2 is displayed correctly
5. Go back again → Expected: Step 1 should be restored from BFCache, Actual: Page is reloaded (BFCache miss)
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Basuke Suzuki
Root Cause Analysis
The Problem
WebKit maintains two types of identifiers:
1. BackForwardItemIdentifier (itemID): Identifies an entire BackForwardList entry (page-level)
2. BackForwardFrameItemIdentifier (frameItemID): Identifies individual frames within an entry (frame-level)
Current (incorrect) behavior:
Step 1: Initial load
BackForwardList[0]: itemID=5-27, mainFrame.frameItemID=5-28
Step 2: iframe cross-site navigation
BackForwardList[1]: itemID=5-92, mainFrame.frameItemID=5-28 ← NEW itemID, SAME frameItemID
MainFrame.HistoryController.m_currentItem still points to itemID=5-27
Step 3: Main frame navigation
BFCache.add(MainFrame.history().currentItem())
→ Saves itemID=5-27, frameItemID=5-28 ← OLD itemID!
Step 4: Back navigation
UIProcess requests: itemID=5-92, frameItemID=5-28
BFCache searches for: itemID=5-92
→ NOT FOUND (only itemID=5-27 exists)
→ BFCache miss
Key Insight
The main frame's content doesn't change during iframe navigation, so its frameItemID remains constant across BackForwardList entries. However, a new itemID is generated for the entire BackForwardList entry.
The BFCache should use frameItemID (frame-level identifier) instead of itemID (page-level identifier) as its key.
Basuke Suzuki
rdar://169563332
Basuke Suzuki
Pull request: https://github.com/WebKit/WebKit/pull/57831
EWS
Committed 306880@main (94edb16b0b9c): <https://commits.webkit.org/306880@main>
Reviewed commits have been landed. Closing PR #57831 and removing active labels.