During performance testing, one of the bottlenecks to making faster use of the FormattedText API in performance-critical scenarios was the creation cost of data-model objects.
Ultimately the goal of the data model is to run a "format" pass from text runs that already exist in JavaScript string form. Collecting these into platform objects simply to then run a "format" pass on them is now recognized to be an unnecessary step.
The prior reason for having an express data model was to enable persistent text (e.g., similar to DOM's Text nodes) to be used for memory-resident updates. However, experience with Text nodes helps us understand that in most cases, the Text node object itself is irrelevant—what is often needed is the JavaScript string from the Text node in order to mutate, aggregate, and change the text. In the DOM, such string changes need to be presented via Layout, and the only way to do that is to re-add them into DOM Text nodes in an attached document tree. In canvas-based scenarios, rendering is not accomplished through the DOM, but through explicit drawing calls—therefore having a DOM Text node-like data model really does not accomplish much.
This proposal updates the FormattedText data model to be based on JavaScript strings for its content.
The expression of Formats (via CSS) can still be useful with platform-persistent objects. Leveraging CSS is ultimately convenient because we anticiapte running layout algorithms on a worker anyway, meaning alternative representations of style/formatting need to ultimately be translated into content the layout engine can understand, and CSS is a well-trod path for expressing this. Issue #27 has some good recommendations for isolating the style for re-usability, which we agree will have positive performance outcomes given that formats are less-likely to rapidly change, and do need some form of persistence if any re-use is desired. It could make sense that an author's styling system (expressed likely as key/value style type pairs in JavaScript) could be translated into persistent style objects (and while this iteration continues to use CSS, we are not opposed to this possibility). In any case, some translation into a form not native to the application would be ultimately required regardless of the shape that the API ends up being (property based or CSS based). Issue #34 also hints at a reusable style application, though per that issue, Selector-based matching isn't applicable when elements are not in use, making a StyleSheet-based approach unfit.
We also propose changes that create a persistent style object that can be used in the data model.
Proposed Changes (Data model)
FormattedText - removed as a container object for the data model (name will be reused)
FormattedTextRun - removed in favor of vanilla strings
FormattedTextStyle - new container to hold persistent CSS properties (wrapper over a StylePropertyMapReadOnly which is not presently 'new-able')
FormattedText - (name reused) replacement for FormattedTextParagraph in the metrics model. This interface will have the static method format which will consume the new data model.
Data Model Updates (the "un-data model")
During performance testing, one of the bottlenecks to making faster use of the
FormattedText
API in performance-critical scenarios was the creation cost of data-model objects.Ultimately the goal of the data model is to run a "format" pass from text runs that already exist in JavaScript string form. Collecting these into platform objects simply to then run a "format" pass on them is now recognized to be an unnecessary step.
The prior reason for having an express data model was to enable persistent text (e.g., similar to DOM's
Text
nodes) to be used for memory-resident updates. However, experience withText
nodes helps us understand that in most cases, theText
node object itself is irrelevant—what is often needed is the JavaScript string from the Text node in order to mutate, aggregate, and change the text. In the DOM, such string changes need to be presented via Layout, and the only way to do that is to re-add them into DOMText
nodes in an attached document tree. In canvas-based scenarios, rendering is not accomplished through the DOM, but through explicit drawing calls—therefore having a DOMText
node-like data model really does not accomplish much.This proposal updates the
FormattedText
data model to be based on JavaScript strings for its content.The expression of Formats (via CSS) can still be useful with platform-persistent objects. Leveraging CSS is ultimately convenient because we anticiapte running layout algorithms on a worker anyway, meaning alternative representations of style/formatting need to ultimately be translated into content the layout engine can understand, and CSS is a well-trod path for expressing this. Issue #27 has some good recommendations for isolating the style for re-usability, which we agree will have positive performance outcomes given that formats are less-likely to rapidly change, and do need some form of persistence if any re-use is desired. It could make sense that an author's styling system (expressed likely as key/value style type pairs in JavaScript) could be translated into persistent style objects (and while this iteration continues to use CSS, we are not opposed to this possibility). In any case, some translation into a form not native to the application would be ultimately required regardless of the shape that the API ends up being (property based or CSS based). Issue #34 also hints at a reusable style application, though per that issue, Selector-based matching isn't applicable when elements are not in use, making a StyleSheet-based approach unfit.
We also propose changes that create a persistent style object that can be used in the data model.
Proposed Changes (Data model)
FormattedText
- removed as a container object for the data model (name will be reused)FormattedTextRun
- removed in favor of vanilla stringsFormattedTextStyle
- new container to hold persistent CSS properties (wrapper over aStylePropertyMapReadOnly
which is not presently 'new-able')FormattedText
- (name reused) replacement forFormattedTextParagraph
in the metrics model. This interface will have the static methodformat
which will consume the new data model.