Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preloading card content #7902

Closed
Arthur-Milchior opened this issue Dec 15, 2020 · 12 comments
Closed

Preloading card content #7902

Arthur-Milchior opened this issue Dec 15, 2020 · 12 comments
Labels
Keep Open avoids the stale bot

Comments

@Arthur-Milchior
Copy link
Member

This bug tracks notions of pre loading a card content.

In my day to day use of ankidroid, the slowest part is currently showing cards with dozen of mathjax formulas, and more rarely cards with big medias. Displaying mathjax became noticeably faster with #7782 but there is still some small noticeable lag when a card is loaded. During this fraction of second, no text nor media is displayed.

Once the reviewer ask the scheduler for the next card using getQueue the card question and answer is preloaded. That was a long process, and I'm very thankful to you David for your help to ensure that it was done correctly. However, even when the question is preloaded, it still contains mathjax with \[foo\], and media with [audio:bar], so there is still some work to do, to transform all of this into proper html that cand be displayed. And more importantly, there is work to do to preload the images, the audio, to precompute the mathjax rendering, so that it can immediately be displayed on the screen.

All of the precomputation is done in the abstract flash card viewer and all result are saved in members of the abstract flash card viewer. It seems clear to me that the members should be moved to a class related to the card, so that the precomputation can be done without any impact to the flash card viewer. I believe this require to create a new class C, and that the scheduler's getCard should return an object of type C.
I think that C should inherits from Card so that no type has to be changed, appart from the one in flash card viewer and in Scheduler, and that when the card c is preloaded in the queue, it does all computations mentionned above that were previously done in the flash card viewer. The viewer then uses the member of c instead of using its own members.

The main problem is that Collection.getCard(id) return a Card, so there is no "clean" way to deal with this change, even if it's easy to do in in an unclean way, using directly C's constructor.
There is also the way to ask C to contain a card object, the problem here is that everything that query scheduler's get card will need to change it's type. Or we need to duplicate the scheduler getCard's so that it can return either C or Card.

Once this is done, the problems reamining will be to actually load the data in a way that can be used by the browser, and to preload mathjax content and save the result. One way to do it would be to use standard browser's preloading feature, and just changing the browser's content instead of opening an entirely new page each time. However, this is risky as far as card with javascript goes, this could get unexpected side effect.

@mikehardy
Copy link
Member

Just a quick thought, without having a webview truly fully rendered in the background and just waiting to re-paint on the page by moving to foreground (or similar) there will always be delay.

The core question for me is: can we have multiple webviews (or multiple "pages" in a webview) such that when it's time to display the next card we have one already fully rendered and just ready to snap into place in the viewport?

Without seeing some prototype demonstration of this, I don't want to spend a single second on structural work in the code to get close to it, because without that final bit it will be for nothing I think

@Arthur-Milchior
Copy link
Member Author

Why do you think that caching the next card in the current webview won't work? That would require to rewrite some of the code, and so require potentially more work than getting fully rendered webview. But I see no reason to believe that the following solution would not work.

In the webview, use multiple span. On span is visible with current displayed content. The two other spans are hidden and contains the one or two possible next contents.
I totally admit that, if card contains javascript then it may breaks things, so it can be useful to have an option to deactivate it. And css should not be preloaded, as it may affect the whole document. But that does not seems to mean the idea can't work.

Note that the audio and video are not played by the webview. So being able to open the file in advance would be useful, independently of the rendering question.

@mikehardy
Copy link
Member

This will need a technical demonstration. Also, how to handle card flip where I believe the WebView is discarded? I'm not saying it can't or won't work. I'm saying before any structural work is even considered, a prototype demonstration should be made that has the content fully rendered and ready to go in a WebView somehow, such that it is just swapped in without needing re-layout or re-flow. Without that, nothing else is important in my opinion

@Arthur-Milchior
Copy link
Member Author

So, I assume a presentation when I replace the card by some arbitrary fixed content should be okay, right?
Because I can't easily replace a card by next card, or even by the answer side, without doing the kind of computation I want to move.

@mikehardy
Copy link
Member

Correct - just prototype, although having it be something ridiculously heavy (like your dozens of mathjax formulas) to demonstrate that they are obviously fully rendered and, making it so they can swap back and forth really quickly (so we could easily see any sort of flicker or re-layout / re-flow) is critical, to make sure the style you prototype really will work. After seeing that as the desired output of any pre-render, we can figure out how to generate with whatever structural changes may be needed

@david-allison

This comment has been minimized.

@david-allison
Copy link
Member

We also have to consider the fact that the user may have timing-related code in the cards, which may not want to be executed before the card is displayed.

I'd imagine that images could work via either inlining them in the code, or via loading them into memory and intercepting the requests to return the memory stream - it's questionable if this is going to be faster than what the browser can do given that it's a primary concern.

@Arthur-Milchior
Copy link
Member Author

We also have to consider the fact that the user may have timing-related code in the cards, which may not want to be executed before the card is displayed.

I totally agree, that's why I tried to mention this case with

I totally admit that, if card contains javascript then it may breaks things, so it can be useful to have an option to deactivate it.

I would love to be able to deactive javascript temporarily to avoid this problem. But since mathjax uses JS, that would not help at all.

Correct - just prototype, although having it be something ridiculously heavy (like your dozens of mathjax formulas)

  1. This is not ridiculous!
  2. Of course, I expected to do cases with big images and case with mathjax

@github-actions
Copy link
Contributor

Hello 👋, this issue has been opened for more than 2 months with no activity on it. If the issue is still here, please keep in mind that we need community support and help to fix it! Just comment something like still searching for solutions and if you found one, please open a pull request! You have 7 days until this gets closed automatically

@github-actions
Copy link
Contributor

Hello 👋, this issue has been opened for more than 2 months with no activity on it. If the issue is still here, please keep in mind that we need community support and help to fix it! Just comment something like still searching for solutions and if you found one, please open a pull request! You have 7 days until this gets closed automatically

@github-actions github-actions bot added the Stale label Apr 16, 2021
@mikehardy mikehardy removed the Stale label Apr 16, 2021
@dae
Copy link
Contributor

dae commented Aug 31, 2023

@Arthur-Milchior a few years have passed - how do things perform after you update to the latest main branch?

@BrayanDSO
Copy link
Member

Closing in favor of #14302

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Keep Open avoids the stale bot
Projects
None yet
Development

No branches or pull requests

5 participants