Page MenuHomePhabricator

Investigate complexity of integrating lazy loading of images
Closed, ResolvedPublic

Description

Task to determine the LOE and path for integrating page libary's lazy loading functionality into iOS app.

Acceptance criteria for integration:

  • Article data use decreases for users who do not scroll down articles
  • Images load smoothly and quickly as the user scrolls
  • content doen't reposition or affect the TOC or "current section" logic as images lazy load

Event Timeline

I identified some issues with our WIP iOS lazy load integration which impact image widening and theme transforms in ways we may not be able to easily work around w/o increasingly wonky hacks. (on top of our already slightly wonky WIP integration)

The first issue is widening's current kickoff assumes images are present in the dom.
"Repaint-hell" side-effects:

  • widening currently causes doc reflow(s) but it's rarely noticeable because usually you only see at most one or 2 images when the first part of the article appears
  • if we switch widening to happen when image is lazily loaded, we'd get reflows while scrolling any time image is lazily loaded, not just once up-front when it's not usually very noticeable. we'd also likely get ultra-jumpiness when making a TOC selection further down the page (multiple resizes for each image the TOC selection scrolls us past would trigger reflows which would cause unwanted scrolling right after the web view scrolls you your TOC selection section. this problem would get progressively worse on slower connections as well because resizes would be even more spread out in time because image fetches take longer)

The second issue is the theme transform also needs images to be present for it to be able to run its classification logic on the image elements.

To be able to effectively do either of these transforms with our current WIP "modify the html in native code" approach would be wonky because both transforms have JS logic which touches the DOM to make classification decisions - i.e. should this image be widened, does this image presume a white background when themes are applied, etc. We can't easily move that logic to native code - and doing so would be unDRY'ing it :(

These issues don't really exist in the Android JS loading method. Direct access to the JS image elements means these transformations can be achieved while these elements are still "headless" state, but with all needed DOM context.

There may be work-arounds with our current approach, but I wanted to chat before going too far down that path (or switching approaches). I'm also holding off on submitting today's changes to page lib for now - if we do switch to JS loading approach those changes won't be needed...

I don't think it would be very hard to take a stab at switching the app back to using the Android JS loading method - one pretty slick way to handle it would be

  • making the bundled web server able to serve up JSON response containing an array w/each element containing section HTML for a given article (this HTML could also contain the image tags w/o us having to convert them to placeholder spans - the lazy load transform will be able to do its "convert images to placeholders" thing normally)
  • we could leave the index.html which the bundled server delivers as-is but we'd just stop injecting the article HTML into its content div
  • an index.html JS load event would then be wired up to make a request to the bundled server for the article section HTML JSON array
  • section HTML would be converted to headless document fragments
  • all of our transforms could then be ran on the headless fragments
  • once fragments are "transformed" they'd then be appended to the now-empty content div of index.html

One neat side-effect of this is it would be more easily switched to a "lead-section/non-lead-section" two step load in the future (for quicker first paint - as Android does)

Another one is the document fragment construction and transformation logic itself could later be consolidated between iOS and Android and migrated to the page lib so both apps could share that logic as well.

I'm totally down for doing all the wiring mentioned above if we go down that path. Though I'd probably ask for help making the bundled web sever able to deliver the JSON containing the array of section HTML, if that approach seems reasonable.

Parked in 'blocked or waiting' pending further discussion and product feedback.

@JMinor