Chromium Code Reviews| Index: third_party/WebKit/LayoutTests/intersection-observer/README |
| diff --git a/third_party/WebKit/LayoutTests/intersection-observer/README b/third_party/WebKit/LayoutTests/intersection-observer/README |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..100f794de8a45ccc135768e646520f6e0ea7d49f |
| --- /dev/null |
| +++ b/third_party/WebKit/LayoutTests/intersection-observer/README |
| @@ -0,0 +1,70 @@ |
| +All of the IntersectionObserver tests feature the following idiom: |
| + |
| +<script> |
| +var observer = new IntersectionObserver(...) |
| +function test_function() { |
| + var entries = observer.takeRecords(); |
| + // Verify entries |
| +} |
| +onload = function() { |
| + observer.observe(target); |
| + requestAnimationFrame(() => { requestAnimationFrame(test_function) }); |
| +} |
| + |
| +Subsequent steps in the test use a single RAF to give the observer a chance to |
| +generate notifications, but the double RAF is required in the onload handler. |
| +Here's the chain of events: |
| + |
| +- onload |
| + - observer.observe() |
| + - First RAF handler is registered |
| +- BeginFrame |
| + - RAF handlers run |
| + - Second RAF handler is registered |
| + - UpdateAllLifecyclePhases |
| + - IntersectionObserver generates notifications |
| +- BeginFrame |
| + - RAF handlers run |
| + - Second RAF handler verifies observer notifications. |
| + |
| +#------------------------------------------------------------------------------- |
| + |
| +All of the IntersectionObserver tests end with: |
| + |
| +requestIdleCallback(finishJSTest, {timeout: 100}); |
| + |
| +To avoid leaking DOM objects, the tests must ensure that all posted tasks have |
| +run before exiting. IntersectionObserverController requests an idle callback |
| +through the document's ScriptedIdleTaskController with a timeout of 100ms. That |
| +callback must be allowed to run before the test finishes to avoid a leak. |
| + |
| +ScriptedIdleTaskController posts two tasks to the WebScheduler: one to run at |
| +the next idle time, and another to run when the timeout expires. |
| +crbug.com/595155 explains that when one of those tasks runs, it does not release |
|
ojan
2016/03/21 18:19:39
Somewhere in here should be a TODO that we can rem
szager1
2016/03/21 18:27:49
It's the other bug that needs to be fixed; added a
|
| +its reference to the ScriptedIdleTaskController, which is needlessly kept alive |
| +until the both tasks have fired. If a test exits before both tasks have fired, |
| +it will have a DOM leak. |
| + |
| +crbug.com/595152 explains that when running without the threaded compositor -- |
| +as the layout tests do -- idle tasks are never serviced. They will still run |
| +when their timeout expires, but the idle task posted by |
| +ScriptedIdleTaskController will never run. |
| + |
| +Fixing the first bug means that requestIdleCallback will not leak as long as it |
| +actually runs before exit. The second bug means that when running without the |
| +threaded compositor, requestIdleCallback will only ever run when its timeout |
| +expires. |
| + |
| +The upshot of all of this is that the only way to ensure that |
| +IntersectionObserver tests don't leak is to ensure that their idle tasks all run |
| +before the tests exit, and those idle tasks will only run when their 100ms |
| +timeout expires. |
| + |
| +Note that all of this still holds when observer.takeRecords() is called before |
| +the idle task runs. In that case, the idle task is not cancelled (because the |
| +idle task needs to service all observers tracked by a given |
| +IntersectionObserverController); when the idle task runs, it's simply a no-op. |
| +There is no way in javascript to detect that such a no-op has occurred, but |
| +using requestIdleCallback with a timeout of 100 should be guaranteed to run |
| +after the IntersectionObserverController's idle task has run, as long as |
| +ScriptedIdleTaskController honors first-in-first-out semantics. |