Intent to Implement: Display Locking

337 views
Skip to first unread message

Vladimir Levin

unread,
Sep 10, 2018, 7:40:31 PM9/10/18
to blink-dev, Chris Harrelson

Contact emails

vmp...@chromium.org, chri...@chromium.org


Explainer

Short version: https://github.com/chrishtr/display-locking/blob/master/README.md

Long version: https://github.com/chrishtr/display-locking/blob/master/explainer.md


TAG review: https://github.com/w3ctag/design-reviews/issues/306


Summary

Display Locking is a proposal to add a script API which locks a DOM element for display. When an element is locked, its visual representation on the page does not change as a result of DOM mutations. Instead, the DOM is mutated and its structure can be inspected and modified in script.


When the lock is committed, a commit promise is returned and  the user-agent starts to process the needed steps for visual presentation cooperatively. That is, it performs style, layout, compositing, and paint steps without jank. When this process is done and the element (and its subtree) are ready to be displayed, the commit promise is resolved, giving the developer an opportunity to inspect DOM properties that are determined during layout, and possibly re-acquire the lock. If the lock is not re-acquired, the element and its subtree are presented to the screen.


While the element is locked, there are options of what is actually displayed to screen. If an element was in the DOM at the time of the lock acquisition, one option is to keep presenting the same visual state even though the subtree DOM might be mutated. If a new element is locked and inserted into the DOM, then the visual representation of the element and its subtree is blank. The following issues track progress on solidifying these steps:

https://github.com/chrishtr/display-locking/issues/8

https://github.com/chrishtr/display-locking/issues/12


WICG thread: https://discourse.wicg.io/t/proposal-display-locking/2905

WhatWG thread: https://github.com/whatwg/html/issues/4010


Motivation

Websites frequently rely on dynamic content to present information. This means that DOM is often manipulated using script to present rich and dynamic content. There are cases when this can cause slow rendering phase updates, including script to update views, style updates, layout, and paint. This, in turn, causes jank or noticeable delay when presenting content, because rendering phase is updated synchronously with user interactions and requestAnimationFrame script.


The following are a few of the common patterns that can cause jank:

  • Resizing multi-pane UI with complex layout within each pane (e.g. IDEs)

  • Adding widgets with complex DOM.

  • Dynamically displaying content based on the current value of text input.

  • Measuring layout of otherwise hidden DOM with intent of sizing containers.


This proposal, if implemented, reduces the jank by allowing the patterns to be used while locking parts of the DOM. The locked subtrees, when processed cooperatively, do not contribute to jank.


Risks

Interoperability and Compatibility

This is a new feature, meaning that existing web content is unaffected by the new API. It should be easy to detect the availability of this feature. If a user-agent does not implement the API, then most common patterns can still be implemented although they may cause jank.


Edge: No signals

Firefox: No signals

Safari: No signals

Web developers: Positive (positive feedback from ReactJS and Polymer).


Ergonomics

The cases outlined in examples are small modifications to otherwise regular JavaScript code, so it should be easy to adopt this feature. Conversely it should also be easy to stop using this feature, with the risk of increasing jank.


Activation

This feature should be easy to use as-is, or as a part of a library.


Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

Yes.


Link to entry on the feature dashboard

https://www.chromestatus.com/feature/4613920211861504


Requesting approval to ship?

No.


Daniel Bratell

unread,
Sep 11, 2018, 10:35:39 AM9/11/18
to blink-dev, Vladimir Levin, Chris Harrelson
This seems to be a large feature in terms of implementation complexity, spec complexity and maintenance complexity. Can it be made testable? 

Lots of questions (input events, nested locks, starvation because dom is faster then layout, script querying layout...) popped up while reading about it but you seem to be aware of most of them so I guess it's just about keeping fingers crossed.

Are there any reasonable alternatives to solving the "layout takes longer than 16 ms" problem that you have considered and maybe discarded?

/Daniel
--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CADsXd2N4QYvW1OY6Fk66YW1WpQJzd3M0mL1hD3ZwrUFDb1Co7A%40mail.gmail.com.



--
/* Opera Software, Linköping, Sweden: CEST (UTC+2) */

Vladimir Levin

unread,
Sep 11, 2018, 2:33:29 PM9/11/18
to bra...@opera.com, blink-dev, Chris Harrelson

Thanks for the feedback!

On Tue, Sep 11, 2018 at 7:35 AM Daniel Bratell <bra...@opera.com> wrote:
This seems to be a large feature in terms of implementation complexity, spec complexity and maintenance complexity. Can it be made testable? 

I think the feature looks complex based on what happens when the lock acquired and committed, but I find an important aspect of this is that the performance improvement is somewhat of an implementation detail. That is, the actual new API surface is pretty small and it guarantees that the locked subtree is not changed when DOM is mutated (this on its own is an important performance characteristic, see *** below). When the lock is released, eventually content will present atomically. Now, this gives quite a bit of room for the user-agent to make this perform well and not jank, but I'm sure that the initial launch will not make all of the cases perform as well as it could. After that, we can iterate and handle more and more cases in the implementation without changing the exposed API. 

As for your question of testability, I think we can test the expected visual behavior pretty easily (eg. locked element with DOM changed did not visually change the previous display; unlocked element after commit promise is resolved presented the content properly), but testing the performance is definitely a challenge.


Lots of questions (input events, nested locks, starvation because dom is faster then layout, script querying layout...) popped up while reading about it but you seem to be aware of most of them so I guess it's just about keeping fingers crossed.

I agree that there are a lot of questions to consider. I think we've talked about most of the important cases and have a proposed solution (there are a few issues filed on github about various cases). But I agree with the general sentiment that I think we can manage to handle them in a predictable way. I encourage you to file more github issues on topics that we may have missed (based on existing github issues)


Are there any reasonable alternatives to solving the "layout takes longer than 16 ms" problem that you have considered and maybe discarded?

*** One of the key observations that we made is that some major performance problems that pages have is not actually because of layout, paint, etc. It is the script itself that takes a substantial amount of time to generate the DOM that it needs to display. Most of the time, it can't chunk this work or yield script easily because partial DOM updates would become visible, which is not something these pages want. Display locking allows the subtree to be modified in increments, allowing script to yield, which means that the page remains responsive and at the same time when the lock is committed all of the DOM changes display atomically.

Specifically to the question of alternatives, we certainly talked about things like having off-thread layout, but a lot of these discussions end up being stopped short because DOM updates have to be atomic. This feature is different in that it explicitly allows the DOM updates to be asynchronous. We are also discussing having a declarative version of this API, where the developer can specify an attribute which would use display locking when displaying the element and its subtree. I don't think of that as an alternative, however, but more of an enhancement.

Let me know if this addresses your concerns or if you have other questions!

Thanks,
Vlad

Yoav Weiss

unread,
Sep 12, 2018, 12:29:02 AM9/12/18
to Vladimir Levin, Chris Harrelson, blink-dev, bra...@opera.com
C'est une

On Tue, Sep 11, 2018, 20:33 Vladimir Levin <vmp...@chromium.org> wrote:

Thanks for the feedback!

On Tue, Sep 11, 2018 at 7:35 AM Daniel Bratell <bra...@opera.com> wrote:
This seems to be a large feature in terms of implementation complexity, spec complexity and maintenance complexity. Can it be made testable? 
. the best y b hmm
I think the feature looks complex based on WhatsApp happens when the lock acquired and I'mcommitted, but I find an important aspect of this is that the performance improvement is somewhat of an implementation detail. That is, the actual new API surface is pretty small and it guarantees that the locked subtree is not changed when DOM is mutated (this on its own is an important performance characteristic, see *** below). When the lock is released, eventually content will present atomically. Now, this gives quite a bit of room for the user-agent to make this perform well and not jank, but I'm sure that the initial launch will not make all of the cases perform as well as it could. After that, we can iterate and handle more and more cases in the implementation without changing the exposed API. 

Yoav Weiss

unread,
Sep 21, 2018, 8:37:55 AM9/21/18
to Vladimir Levin, Chris Harrelson, blink-dev, bra...@opera.com


On Wed, Sep 12, 2018 at 6:28 AM Yoav Weiss <yo...@yoav.ws> wrote:
C'est une

Apologies. I have no idea what I was trying to write, and pretty sure I wasn't trying to write it *here*. Please ignore.

Chris Harrelson

unread,
Aug 23, 2019, 3:26:12 PM8/23/19
to Yoav Weiss, Vladimir Levin, blink-dev, Daniel Bratell
Quick update: in the past year we've gathered a whole bunch of design and implementation experience, plus feedback from some early adopters.

Based on this, the API shape has significantly changed, though it still supports many of the same use cases. Look for new intents-to-implement shortly for the two major pieces of the new shape (content-size and rendersubtree).

Chris

Reply all
Reply to author
Forward
0 new messages