|
32 | 32 | ShadowNode const &sourceShadowNode, |
33 | 33 | ShadowNodeFragment const &fragment) |
34 | 34 | : ConcreteViewShadowNode(sourceShadowNode, fragment) { |
| 35 | + // Carry the persisted RCTMarkdownUtils over from the source node so the |
| 36 | + // MarkdownParser memo cache survives the frequent cloning that happens |
| 37 | + // during layout and re-render cycles. |
| 38 | + const auto &source = |
| 39 | + static_cast<const MarkdownTextInputDecoratorShadowNode &>(sourceShadowNode); |
| 40 | + markdownUtils_ = source.markdownUtils_; |
| 41 | + |
35 | 42 | initialize(); |
36 | 43 | makeChildNodeMutable(); |
37 | 44 |
|
|
182 | 189 | const auto defaultNSTextAttributes = |
183 | 190 | RCTNSTextAttributesFromTextAttributes(defaultTextAttributes); |
184 | 191 |
|
185 | | - // this can possibly be optimized |
| 192 | + // Lazily create and persist the RCTMarkdownUtils instance so the MarkdownParser |
| 193 | + // one-entry memo cache (keyed on text + parserId) survives repeated Yoga measure |
| 194 | + // callbacks. Previously a fresh utils/parser was allocated on every call, |
| 195 | + // discarding the cache and forcing a full JSI re-parse each time. |
| 196 | + if (!markdownUtils_) { |
| 197 | + RCTMarkdownUtils *freshUtils = [[RCTMarkdownUtils alloc] init]; |
| 198 | + markdownUtils_ = std::shared_ptr<void>( |
| 199 | + (__bridge_retained void *)freshUtils, [](void *p) { CFRelease(p); }); |
| 200 | + } |
| 201 | + RCTMarkdownUtils *utils = (__bridge RCTMarkdownUtils *)markdownUtils_.get(); |
| 202 | + |
186 | 203 | RCTMarkdownStyle *markdownStyle = |
187 | 204 | [[RCTMarkdownStyle alloc] initWithStruct:decoratorProps.markdownStyle]; |
188 | | - RCTMarkdownUtils *utils = [[RCTMarkdownUtils alloc] init]; |
189 | | - [utils setMarkdownStyle:markdownStyle]; |
190 | | - [utils setParserId:[NSNumber numberWithInt:decoratorProps.parserId]]; |
| 205 | + NSNumber *parserId = [NSNumber numberWithInt:decoratorProps.parserId]; |
191 | 206 |
|
192 | 207 | // convert the attibuted string stored in state to |
193 | 208 | // NSAttributedString |
|
228 | 243 |
|
229 | 244 | // apply markdown |
230 | 245 | NSMutableAttributedString *newString = [nsAttributedString mutableCopy]; |
231 | | - [utils applyMarkdownFormatting:newString withDefaultTextAttributes:defaultNSTextAttributes]; |
| 246 | + [utils applyMarkdownFormatting:newString |
| 247 | + withDefaultTextAttributes:defaultNSTextAttributes |
| 248 | + markdownStyle:markdownStyle |
| 249 | + parserId:parserId]; |
232 | 250 |
|
233 | 251 | // create a clone of the old TextInputState and update the |
234 | 252 | // attributed string box to point to the string with markdown |
|
240 | 258 |
|
241 | 259 | // apply markdown |
242 | 260 | NSMutableAttributedString *newString = [nsAttributedString mutableCopy]; |
243 | | - [utils applyMarkdownFormatting:newString withDefaultTextAttributes:defaultNSTextAttributes]; |
| 261 | + [utils applyMarkdownFormatting:newString |
| 262 | + withDefaultTextAttributes:defaultNSTextAttributes |
| 263 | + markdownStyle:markdownStyle |
| 264 | + parserId:parserId]; |
244 | 265 |
|
245 | 266 | // create a clone of the old TextInputState and update the |
246 | 267 | // attributed string box to point to the string with markdown |
|
0 commit comments