Closed Bug 1671962 Opened 4 years ago Closed 4 years ago

Iframes loaded from restored session are loaded out of order when Fission enabled

Categories

(Core :: DOM: Navigation, defect, P2)

x86_64
Linux
defect

Tracking

()

RESOLVED FIXED
84 Branch
Fission Milestone M6c
Tracking Status
firefox84 --- fixed

People

(Reporter: geeknik, Assigned: smaug)

References

Details

(Keywords: nightly-community)

Attachments

(1 file)

Session restore + Fission enabled iframes don't play well together. Create an html page that has 3-5 iframes in a row like so:

<iframe src=http://whatever id=1></iframe><iframe src=http://whatever id=2></iframe><iframe src=http://whatever id=3></iframe><iframe src=http://whatever id=4></iframe><iframe src=http://whatever id=5></iframe>

Load the page in a clean Nightly profile. Now make sure that Nightly is configured to Restore previous session. Close Nightly. Re-open Nightly. The loaded content in the iframes are now likely out of order even though the HTML code doesn't look altered. F5 usually fixes that.

For example here is my test code:
<iframe src='file:///tmp/fuzzer.html' id=1></iframe><iframe src='http://drudgereport.com' id=2></iframe><iframe src='https://v8.github.io/test262/website/default.html#' id=3></iframe>

And here is the out of order iframes displayed in Nightly: https://i.imgur.com/ukegpCo.png

Blocks: fission-dogfooding
No longer blocks: fission
Severity: -- → S2
Fission Milestone: --- → M6c
Priority: -- → P2

We appear to be relying on the order in which the loads finish when building the children array. When we navigate to a page with multiple iframes, we kick off the loads for those frames in parallel, and add the corresponding loading entries to CanonicalBrowsingContext in the correct order, but then commit each entry based on when the load finishes (this happens when we call nsDocShell::MoveLoadingToActiveEntry in nsDocShell::Embed).

It was hard to find actual sites that consistently load slow enough to reproduce this reliably, so the following setup demonstrates it a little better:

# save this to server.py
# run `python3 server.py`
# GET requests to http://localhost:8000 will respond with some html after 5 seconds

from http.server import HTTPServer, BaseHTTPRequestHandler
import time

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        time.sleep(5)
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(b"<html><body><h1>hello</h1></body></html>")

if __name__ == "__main__":
    HTTPServer(("localhost", 8000), Handler).serve_forever();
<!DOCTYPE html>
<body>
  <iframe src="http://localhost:8000"></iframe>
  <iframe src="http://example.com/"></iframe>
</body>

You'll notice that the second frame finishes loading way before the first, and that the example.com SessionHistoryEntry is in front of the localhost one in the top-level SessionHistoryEntry::mChildren array. Closing the tab and then re-opening it will demonstrate the problem (the example.com document is loaded into the first frame, instead of the second).

We collect the children here. I'm wondering if we can just sort this array by entry ID? smaug probably has a better idea of what to do here.

Flags: needinfo?(bugs)

(In reply to :kashav from comment #1)

I'm wondering if we can just sort this array by entry ID?

diff --git a/toolkit/modules/sessionstore/SessionHistory.jsm b/toolkit/modules/sessionstore/SessionHistory.jsm
--- a/toolkit/modules/sessionstore/SessionHistory.jsm
+++ b/toolkit/modules/sessionstore/SessionHistory.jsm
@@ -321,7 +321,7 @@ var SessionHistoryInternal = {
       }
 
       if (children.length) {
-        entry.children = children;
+        entry.children = children.sort((a, b) => a.ID - b.ID);
       }
     }

This does appear to fix things for what it's worth, but there's probably a more correct solution here.

Component: Session Restore → DOM: Navigation
Product: Firefox → Core
Version: Trunk → unspecified
Assignee: nobody → bugs
Status: NEW → ASSIGNED
Flags: needinfo?(bugs)

FWIW, commit doesn't happen when load finishes. It happens when we start getting data from the network.

Regressions: 1673947
Attachment #9184107 - Attachment description: Bug 1671962 - Iframes loaded from restored session are loaded out of order when Fission enabled → Bug 1671962 - Iframes loaded from restored session are loaded out of order when Fission enabled, r=peterv
Pushed by opettay@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/84ed543cd810
Iframes loaded from restored session are loaded out of order when Fission enabled, r=peterv
Flags: needinfo?(bugs)
No longer regressions: 1673947
Pushed by opettay@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/a0b3e0a2cbbf
Iframes loaded from restored session are loaded out of order when Fission enabled, r=peterv
Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → 84 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: