Skip to content

Commit

Permalink
Fabric: Fixes in Android TextLayoutManager for better caching perform…
Browse files Browse the repository at this point in the history
…ance

Summary:
The is how it works:
* Text is a quite special component with special properties and constraints. Some of them are:
It's expensive to measure (layout) text. It's expensive to measure and expensive to pass AttributedString via JNI.
* When we measure text, we don't concerned about maximum height, only maximum height is important. (Even though theoretically, there are text layout systems that can balance these constraints (max height and width) trying to find a perfect result, we don't use such complex (and expensive) layout engines for building UIs).

Yoga, as a flexbox engine, does not aware of such constraints, so it requests remeasuring of text components quite often, so we have an RN built-in text measure cache system just for text measurements that suit these constraints. This way when Yoga requests a text measuring, we always measure with `Inf` height and store that result in the cache. And when Yoga requests another measure with the same width but a different height we retrieve the value from the cache and then just clamp it.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: mdvacca

Differential Revision: D26696637

fbshipit-source-id: f65b275d33c77073bc2359cbf0a741ddcf05d8d4
  • Loading branch information
shergin authored and facebook-github-bot committed Feb 28, 2021
1 parent 5f1012c commit f276214
Showing 1 changed file with 8 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include "TextLayoutManager.h"

#include <limits>

#include <react/jni/ReadableNativeMap.h>
#include <react/renderer/attributedstring/conversions.h>
#include <react/renderer/core/conversions.h>
Expand All @@ -29,12 +31,15 @@ TextMeasurement TextLayoutManager::measure(
LayoutConstraints layoutConstraints) const {
auto &attributedString = attributedStringBox.getValue();

return measureCache_.get(
auto measurement = measureCache_.get(
{attributedString, paragraphAttributes, layoutConstraints},
[&](TextMeasureCacheKey const &key) {
return doMeasure(
attributedString, paragraphAttributes, layoutConstraints);
});

measurement.size = layoutConstraints.clamp(measurement.size);
return measurement;
}

TextMeasurement TextLayoutManager::measureCachedSpannableById(
Expand Down Expand Up @@ -126,6 +131,8 @@ TextMeasurement TextLayoutManager::doMeasure(
AttributedString attributedString,
ParagraphAttributes paragraphAttributes,
LayoutConstraints layoutConstraints) const {
layoutConstraints.maximumSize.height = std::numeric_limits<Float>::infinity();

int attachmentsCount = 0;
for (auto fragment : attributedString.getFragments()) {
if (fragment.isAttachment()) {
Expand Down

0 comments on commit f276214

Please sign in to comment.