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

Prevent render till css fulfilled from cache or zim #385

Closed

Conversation

Jaifroid
Copy link
Member

Please try out this PR, @mossroy, which fixes #381 for jQuery mode. I've tested load of the Stackoverflow home page in Edge, Chromium and Firefox in jQuery mode (I haven't tried to load that page in IE, because IE is very slow on normal ZIMs, but other ZIM files work fine in IE with this code). I've also tested the code on FFOS, but not with that ZIM.

It works like this: if (some of) the CSS files are cached, then preload them into the html string before injecting the string into the iframe. If they are not cached (or if some of them aren't), then inject the HTML but keep the iframe hidden until all the CSS files have been fulfilled from the ZIM. Then render the iframe. Since browsers don't render content where style.display == "none", we can take advantage of this behaviour to prevent rendering until all CSS is available and injected through one method or other.

The code is based on a more complete caching solution I've been developing as a replacement for the clunky (but functional) caching-in-the-filesystem that I was doing this time last year for Kiwix JS Windows. The more complete solution uses indexedDB or localStorage to persist the cached assets between ZIM loads (in jQuery and ServiceWorker), and includes the ZIM filename in the cacheKey. It is too big a change to contemplate just for this issue, however, so I've adapted relevant bits.

But you'll notice some embryonic features that will make it easier to develop the following:

  1. Addition of JavaScript to the cache (hence I've renamed it assetsCache) -- this will be absolutely vital if we ever hope to support JavaScript;
  2. Asynchronous cache calls (necessary for indexedDB).

You'll also notice that the assetsCache is declared app-wide. This is so that we don't need to pass it around between app.js and uiUtil.js (and a future cache.js) in function calls. Here we're still erasing it between ZIM loads. If you don't like this and have a better way to avoid passing the cache around, please suggest!

The per-ZIM persistent cache really makes the app fly, b.t.w.!

mossroy and others added 2 commits May 30, 2018 14:58
Instead of calling displayArticleInForm like in jQuery mode.
I also removed some tests on jQuery/ServiceWorker modes in displayArticleInForm, as this function is now only used in jQuery mode.
And I renamed it to displayArticleContentInIframe

Fixes #382
@Jaifroid Jaifroid self-assigned this May 30, 2018
@Jaifroid Jaifroid requested a review from mossroy May 30, 2018 16:50
@Jaifroid
Copy link
Member Author

@mossroy With that Stackoverflow home page, I've noticed that this line makes it extremely burdensome on the CPU to load a new page. Presumably jQuery is going through each and every one of the tag links and removing event listeners. If I comment out that line, then clicking on one of the tags opens the tag reasonably fast. With it in, we get a serious lock-up before the new page eventually loads.

I realize we're going round in circles here (we put this in to avoid the dead objects error). This page is not typical, so maybe we don't need to do anything about it. The longer-term solution is #367 (Remove jQuery), so that we don't have the overhead of jQuery's legacy caching of objects.

@Jaifroid
Copy link
Member Author

NB Above issue affects Firefox, not Chromium or Edge. Strange.
I have a version of this PR which eliminates loadCSSJQuery() and loads all CSS up-front into the HTML string, not just the CSS available in the cache at the time. Would this be preferable?

@Jaifroid
Copy link
Member Author

Just quickly, I thought to compare/benchmark a simplified version which doesn't preload anything into the html string, but merely prevents rendering until the CSS is ready (using loadCSSJQuery). It's in this branch:

https://github.com/kiwix/kiwix-js/tree/Prevent-render-without-preload

This code is less disruptive to our current way of doing things. It may not be quite so performant once CSS is in the cache. But maybe for a V2.3 release, it is a more palatable change. Let me know if you'd like me to PR that branch instead of this.

@mossroy
Copy link
Contributor

mossroy commented Jun 1, 2018

Please create a PR for this second branch.
Its code is much simpler, which seems less risky as a last step before a release.
A few minor remarks on it :

  • please use jQuery to display the content, to be consistent with the other places where we change this visibility
  • the cssCount and cssFullfilled variables are not technically related to the CSS cache in this version. Maybe they could be simple variables inside loadCSSJQuery function and renderIfCSSFulfilled function might a function declared inside loadCSSJQuery (in order to have access to these variables). This way, the CSS cache would be independent from this optimization.

@Jaifroid
Copy link
Member Author

Jaifroid commented Jun 1, 2018

Agreed, closing.

@Jaifroid Jaifroid closed this Jun 1, 2018
@Jaifroid Jaifroid deleted the Prevent-render-till-CSS-fulfilled-from-cache-or-ZIM branch January 9, 2023 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Serious performance regression on rendering the index page of stackoverflow.com_eng_all_2017-05.zim
2 participants