Anki-android: Showing the answer on this note type takes forever since release 2.9.1.

Created on 28 Oct 2019  路  26Comments  路  Source: ankidroid/Anki-Android

Reproduction Steps

In one of my note types I do a regex replace of certain special characters in JavaScript: replace(/[`~!@#$%^&*()_|-=?;'",.<>{}[]\\/]/g, ' ');

Since the latest release of AnkiDroid I noticed that this causes a heavy delay in showing the answer. This was not the case on the last major release of AnkiDroid and is also not the case on any other version of Anki (tested on AnkiMobile, PC and Mac).

I was able to narrow down the problem to the use of a few escaping characters, namely: {}[]\\/

Interestingly the problem also happens when the code is commented out.

Here are three versions of an example note type to demonstrate the problem (Please delete the "AnkiDroid_Bug"-deck after trying each version):

Version 1: Nothing is commented out, the js-code including the escaping characters is executed. Result: It takes way too long to show the answer. https://www.dropbox.com/s/gxsod665hccleta/AnkiDroid_Bug_nothing_commented_out.apkg?dl=0

Version 2: The problematic JS-code in line 14 of the answer is commented out. Result: The problem still persists. https://www.dropbox.com/s/n1rkznu2f3u24dp/AnkiDroid_Bug_line_14_commented_out.apkg?dl=0

Version 3: The problematic characters are removed, the rest of the js-code runs. Result: This version works fine. 鉁旓笍 https://www.dropbox.com/s/xm9cawa9kcgi96x/AnkiDroid_Bug_escaping_characters_removed.apkg?dl=0

Expected Result

Answer is shown right away.

Actual Result

It takes a few seconds to show the answer.

Debug info

The problem first appeared in the last major release in October, the one that is currently available on the Play Store. I think that is 2.9.1.
It is still present in 2.9.2 beta 3.

Research

Enter an [ x ] character to confirm the points below:

[x] I have read the support page and am reporting a bug or enhancement request specific to AnkiDroid

[x] I have checked the manual and the FAQ and could not find a solution to my issue

[x] I have searched for similar existing issues here and on the user forum

All 26 comments

Interesting - very thorough notes, thank you - to be clear if you revert to 2.8.4 is performance fine?

Haha, thanks for the appreciation! AnkiDroid is great, so thank _you_ for that!

Yes, 2.8.4 has no problem with these escaping characters. I'm lucky I saw that it worked flawlessly before!

I can repeat with 2.9.1, but not in 2.10alpha6

If anyone else read this bug report, the buggy template is

{{FrontSide}}

<hr id=answer>

<div id=Karte>{{R眉ckseite}}</div>

followed by the script

function _(element) {
  return document.getElementById(element);
}

inhalt = "123"
inhalt = inhalt.replace(/[`~!@#$%^&*()_|\-=?;'",.<>\{\}\[\]\\\/]/g, ' '); //The following (escaping) characters cause long loading of the answer in AnkiDroid - even when you comment out this whole line: \{\}\[\]\\\/ 
//If you remove these characters however, everything works smoothly.

//The content of this function is not important, it just takes some time to load the picture.
function load_img(output_element_id, inhalt) {

    var output = _(output_element_id);
    var img = document.createElement("img");

    img.id = "myImg";
    img.src = "http://thomaskahn.de/basiskarten/suggestions.php?action=check&inhalt=123"

    img.onerror = function() {
        _("myImg").style.display = "none";
        _("Karte").innerHTML = _("Karte").innerHTML + "(-)"
    };

    output.appendChild(img);

    function loaded() {
     _("Karte").innerHTML = _("Karte").innerHTML + "(+)"
    }

    if (img.complete) {
      loaded()
    } else {
      img.addEventListener('load', loaded)
    }

    return true
}

load_img("Karte", "info.png") //If you comment out this line the answer is shown right away, but it still disappears for a second, causing flashing.

And the version with escaping removed is

function _(element) {
  return document.getElementById(element);
}

inhalt = "123"
//inhalt = inhalt.replace(/[`~!@#$%^&*()_|\-=?;'",.<>]/g, ' '); //The problematic escaping characters which cause the long loading of the answer in AnkiDroid have been removed in this version.
//This version loads fine.

//The content of this function is not important, it just takes some time to load the picture.
function load_img(output_element_id, inhalt) {

    var output = _(output_element_id);
    var img = document.createElement("img");

    img.id = "myImg";
    img.src = "http://thomaskahn.de/basiskarten/suggestions.php?action=check&inhalt=123"

    img.onerror = function() {
        _("myImg").style.display = "none";
        _("Karte").innerHTML = _("Karte").innerHTML + "(-)"
    };

    output.appendChild(img);

    function loaded() {
     _("Karte").innerHTML = _("Karte").innerHTML + "(+)"
    }

    if (img.complete) {
      loaded()
    } else {
      img.addEventListener('load', loaded)
    }

    return true
}

load_img("Karte", "info.png") //If you comment out this line the answer is shown right away, but it still disappears for a second, causing flashing.

</script>

I can repeat with v2.9 but not with master.

I can repeat with v2.9.1 but not with master.
in 2.9.1 I tried to use the profiler, but as far as CPU goes, nothing occurs. It simply waits in android.os.MessageQueue.nativePollOnce during almost a second (which is always running, and is perfectly standard in Android as far as my google search goes.)

No other thread has any process running for more than 0.04 seconds, so they are not responsible for the waiting.
I must admit that I do not understand at all.

I can repeat with 2.9.1, but not in 2.10alpha6

@mikehardy @snoyes
I forgot to mention this: On v2.10alpha9 there is _no_ problem with slow loading but other (more severe) problems:

  1. Loading the picture doesn't work at all. The img.onerror-event (inside the load_img()-function) is always triggered. (This is the case in all versions I provided.)
  2. In the versions with the escaping characters included, there is another small bug in the alpha: Instead of the lag while revealing the answer both the question and answer disappear for a few ms, causing a flashing effect.

General comment: I think this is a really weird bug: Why are the escaping characters interpreted even when you comment them out? @Arthur-Milchior Same!

I assume you mention the image http://thomaskahn.de/basiskarten/suggestions.php?action=check&inhalt=123
If so, it's so small I don't even see how we can see whether it's loaded or not. How do you check it ?

I tried your code with master. I changed the image's url to something I can actually see.聽And the image is shown perfectly. And I see no flash, even in night mode.

On error it adds "(-)" to the answer-field (id: "Karte").

When the loading was successful, it adds "(+)".

Oh ok. Flashing means that everything dissappear and reappear again. I thought it means a big change everywhere, as when you turn on/off a light. Something hurting eyes.
Then in fact, I can reproduce it on my VM too; the flash occurs.

Ah, ok. Yeah, it's not dramatic, just slightly irritating.

Btw, this is how it's supposed to work ideally (no flashing, answer shown right away, confirmation that the image was loaded successfully appears 1 or 2 seconds later): https://www.dropbox.com/s/ebxbrrl6xz7tk7y/19-10-29-10-35-31.mp4?dl=0
(This was created with v2.9.2beta3 and the escaping characters removed.)

just saying technically this is a "re-flow" or "re-render". Not sure exactly what changed where but it's a standard Chromium WebView that's doing all the render, you might try https://github.com/ankidroid/Anki-Android/wiki/Development-Guide#html-javascript-inspection to gain insight - worst case you can get the actual HTML we sent to the WebView for render, best case (if you tether a device or run an emulator) you can actually attach the Chrome DevTools debugger to the running WebView inside the device for dynamic inspection

Just tried the first variant of the link you sent me. Chrome 78.0.3904.62 on my OnePlus 7 Pro doesn't show any of the weird symptoms that AnkiDroid shows. I will try connecting my phone via USB now.

I'm able to get that delay even after trimming the back template down to this:

{{FrontSide}}

<hr id='answer'>

<div id='Karte'>{{R眉ckseite}}</div>

<script>

// \[\]\\
var img = document.createElement('img');
img.src = "http://thomaskahn.de/basiskarten/suggestions.php?action=check&inhalt=123";

</script>

Remote debugging shows me that the Chrome version used in AnkiDroid 2.9.2 beta3 is 77.0.3865.116, so not the latest version. Could that be the reason?

Remote debugging shows me that the Chrome version used in AnkiDroid is 77.0.3865.116, so not the latest version. Could that be the reason?

What's the Chrome version used in 2.10alpha ?

The WebView should remain the same regardless of AnkiDroid version. It looks like it's on 78.x now https://play.google.com/store/apps/details?id=com.google.android.webview&hl=en_US if your phone is updating. It is a separate build from the main Chrome app but uses the same underlying Chromium engine - so they are similar but do update separately. You might be able to select what WebView is in use in developer settings

What's the Chrome version used in 2.10alpha ?

77.0.3865.116 according to Remote Debugging.

Just installed the latest updates and WebView is on version 78.0.3904.62 now. The lagging still happens.

I bet it's to do with this:

https://github.com/ankidroid/Anki-Android/blob/7235a5bc667a6c9def934d85764cedc6594814b3/AnkiDroid/src/main/assets/scripts/card.js#L112-L117

Changing \[\] to \]\[ (and removing the comment saying what the problem characters are, so there is no instance of \[ followed later by a \]) solves it.

Ergo, probably solved by #5394

Yeah - if this is not reproducible on master anymore then that seems like the likely culprit - nice @snoyes

Awesome, @snoyes !

Thanks everyone for your help!

Was this page helpful?
0 / 5 - 0 ratings