Hi all, we’ve run into something with RichTextEditor and would like to check whether it’s intended.
RichTextEditor seems to send its whole Delta value to the server after every pause in typing, even when the application only uses the HTML value and never calls asDelta(). With inline images the Delta is large, and on a slow connection the UI waits for minutes. Three questions:
- Is the Delta meant to be synchronised on every change when the application only uses the HTML value?
- Is there a supported way to turn the Delta sync off, or to make it follow the value-change mode?
- Is there anything else we should set, or a different way to use the component, that avoids this?
setValueChangeMode(...) makes no difference to it (table below). We see it in 24.7.3 and 24.9.13.
Measured (a 0.75 MB body with 10 inline images, typing 40 characters at normal speed, then clicking a button):
| Set-up | Requests | Uploaded |
|---|---|---|
| Default (no value-change mode set) | 9 | 6.77 MB |
ValueChangeMode.ON_BLUR |
9 | 6.77 MB |
ValueChangeMode.EAGER |
9 | 12.03 MB |
With the upload throttled to 80 KB/s, the first sync (770 KB) took 9.7 s. While it was uploading, 7 more queued and went with the button click as one 6.2 MB request, which took 78 s. The UI was unresponsive until it finished. Setting the value from the server with asHtml().setValue(...) also sends one full copy of the Delta back, before anything is typed.
Minimal example (about 0.94 MB of images: 9 requests and 8.27 MB for 40 characters; at 80 KB/s, the last request was 7.5 MB and took 95 s):
@Route("")
public class RteView extends VerticalLayout {
public RteView() throws IOException {
RichTextEditor editor = new RichTextEditor();
StringBuilder html = new StringBuilder("<p>Type here</p>");
for (int i = 0; i < 10; i++) {
html.append("<p><img src=\"data:image/png;base64,")
.append(noisePng(200, 120)).append("\"></p>");
}
editor.asHtml().setValue(html.toString());
Button send = new Button("Send",
e -> Notification.show("HTML length: " + editor.getHtmlValue().length()));
add(editor, send);
}
private static String noisePng(int w, int h) throws IOException {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Random r = new Random();
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
img.setRGB(x, y, r.nextInt(0xFFFFFF));
}
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(img, "png", out);
return Base64.getEncoder().encodeToString(out.toByteArray());
}
}
Open the browser’s developer tools on the Network tab, filtered to uidl, and type a few words with pauses. Each pause sends an mSync of value (the full Delta, images included) with a value-changed event.
Vaadin 24.9.13, Java 17, Spring Boot 3.5.0, Chrome.
Thanks in advance for any pointers.