Bug 137407 - window.performance object resets script-applied properties
Summary: window.performance object resets script-applied properties
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore JavaScript (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac (Intel) Other
: P2 Normal
Assignee: Chris Dumez
URL: http://jsfiddle.net/dss8wudw/3/
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-03 14:50 PDT by e.a. nakashima
Modified: 2016-09-12 14:25 PDT (History)
15 users (show)

See Also:


Attachments
Patch (4.20 KB, patch)
2016-09-12 13:09 PDT, Chris Dumez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description e.a. nakashima 2014-10-03 14:50:34 PDT
To polyfill certain browser APIs that are not fully implemented in WebKit, including the User Timing API, it's useful to be able to add properties to the `window.performance` object, using code like `window.performance.mark = function() { [implementation here] }`. In Safari 8 we're seeing a behavior where the `window.performance` object is periodically reset, removing all properties applied with scripts. The point when the reset occurs can vary, but it seems to correlate to: 

- opening and closing the developer tools (console)
- a change in the document readyState
- triggering certain DOM events, e.g. clicking back on the document after you've opened the developer tools

Admittedly it's questionable whether to consider this a bug, since it's typically considered a best practice to not modify built-in browser-provided objects. But it would be really helpful to be able to do this reliably in the case of polyfills.

Steps to Reproduce:

1. Set a property of `window.performance` in a script or in the console. For example, `window.performance.example = "example"`
2. `console.log(window.performance.example)` and see "example" printed
3. Open and close the developer tools (console) a few times.
4. `console.log(window.performance.example)` and see "undefined" printed

See this JS Fiddle http://jsfiddle.net/dss8wudw/3/ for demo setup.

Expected Results:
Ideally `window.performance` properties would remain set unless they are modified by a script (or the user refreshes or navigates to a new page). The value of `window.performance.example` should remain `"example"` until we delete it or set it to something else.

Configuration:

Browser: Safari Version 8.0 (10600.1.22)
OS: Mac OS X 10.10
Device: MacBook Air (11-inch, Mid 2012)
Comment 1 Alex Christensen 2014-10-04 11:26:53 PDT
I think this is an issue with the JavaScript bindings and not with the underlying C++ object that is wrapped, and it may be intentionally resetting something.  Are there other built-in browser-provided objects that have similar behavior?  I unfortunately don't have access to build WebKit on Yosemite right now, but I could look into something that behaves similarly on Mavericks.
Comment 2 Alexey Proskuryakov 2014-10-04 11:54:14 PDT
Bug 122770 could be an example, it fixed the same problem for window.crypto.
Comment 3 krinklemail 2015-09-14 15:08:39 PDT
Downstream report from Wikimedia where this caused fatal
exceptions for Safari users reading Wikipedia:
https://phabricator.wikimedia.org/T112287#1638614

Test case:
http://codepen.io/Krinkle/debug/YywQJb

It has three checkpoints:
1) Immediately after definition.
2) From a <script src> loaded script.
3) After window.onload.

In Safari 8.0.8, sometimes 'performance.mark' is defined at all thee, sometimes only at #1, sometimes at #1 and #2.
Comment 4 Derk-Jan Hartman 2015-09-14 15:15:42 PDT
Also confirmed as a problem in Version 9.0 (10601.1.56) btw.
Comment 5 Godfrey Chan 2016-09-12 11:00:31 PDT
There is still an issue in 9.1.3
Comment 6 Chris Dumez 2016-09-12 12:22:29 PDT
I'll take a look soon.
Comment 7 Chris Dumez 2016-09-12 13:09:04 PDT
Created attachment 288603 [details]
Patch
Comment 8 Darin Adler 2016-09-12 13:54:39 PDT
We can recommend a workaround for affected sites if they want to work properly with older versions of WebKit. I think that putting this line of code in will work around the bug:

    window.keepPerformanceAlive = window.performance;
Comment 9 Darin Adler 2016-09-12 13:55:20 PDT
Note, that’s just a guess. Someone would need to test to be sure that works!
Comment 10 WebKit Commit Bot 2016-09-12 14:25:17 PDT
Comment on attachment 288603 [details]
Patch

Clearing flags on attachment: 288603

Committed r205823: <http://trac.webkit.org/changeset/205823>
Comment 11 WebKit Commit Bot 2016-09-12 14:25:23 PDT
All reviewed patches have been landed.  Closing bug.