redfin / react-server

:rocket: Blazing fast page load and seamless navigation.
https://react-server.io/
Apache License 2.0
3.89k stars 184 forks source link

Download critical assets faster with <link rel="preload"> #253

Open bartkusa opened 8 years ago

bartkusa commented 8 years ago

(Issue derived from failed pull-request https://github.com/redfin/react-server/pull/60)

LABjs does not always download JS bundles eagerly. Nobody knows why.

We can work around this by using (or "prefetch"?) to eagerly fetch resources. I ran some experiments that indicate it would speed up Time-to-Interactive between 0.5s and 1.0s for Redfin's mobile Chrome users, in semi-realistic conditions.

The trick is building a good API for marking assets (JS, CSS, images, maybe even XHRs) as critical/preloadable.

kcjonson commented 8 years ago

Likewise, I think we may needs parts of this work for client side transitions. I'm imagining that we use prefetch to grab the CSS bundles eagerly for some set of routes so that when a client transition occurs its a seamless transition. The hard part is determining which ones should be prefetched...

Edit: Found #77 which is pretty much this.

gigabo commented 7 years ago

Related: https://github.com/redfin/react-server/pull/850

CC @lidawang

doug-wade commented 7 years ago

Check out how sweet next.js prefetching is

import Link from 'next/prefetch'
// example header component
export default () => (
  <nav>
    <ul>
      <li><Link href='/'><a>Home</a></Link></li>
      <li><Link href='/about'><a>About</a></Link></li>
      <li><Link href='/contact'><a>Contact</a></Link></li>
    </ul>
  </nav>
)
dfabulich commented 7 years ago

The discussion in this bug seems confused. link rel=preload and rel=prefetch have nothing to do with each other. https://css-tricks.com/prefetching-preloading-prebrowsing/

preload (previously known as subresource) is a hint to the browser's HTML parser to immediately begin downloading scripts that LAB will eventually request as part of the same page load. http://caniuse.com/#feat=link-rel-preload preload is currently only supported in Google Chrome, but Apple has enabled support in the Safari Technical Preview, so it will presumably become available in iOS/Safari 11 later this year. rel=preload support would improve performance on Google Chrome today.

prefetch is a hint to wait for an idle moment to begin downloading other off-page resources that we predict the user will want. http://caniuse.com/#feat=link-rel-prefetch It's supported on Chrome, Firefox, and IE11, but not Safari. In the past, we've used prefetching on Redfin's home page to request map JS, or on the map to request LDP JS. prefetch is a bit perilous because it's making a prediction about what the user will want to do next; it can be a waste of bandwidth/battery.

bartkusa commented 7 years ago

Update: I tried running an experiment on my Redfin dev box. The results weren't promising.

• When I ran tests locally w/ Chrome, our homepage downloaded its JS twice. I think the preload-request fires first, then the LABjs-request fires second, and the browser doesn't dedupe that request for some reason. • When I ran our private WebPageTest instance against my changes in a VM, I didn't see any difference in the waterfall. It looked like the browser ignored my preload directive. Maybe it's a bug w/ our WPT instance, or the browsers it uses? (Also, it was a pain in the butt to get WPT to block 3rd-party assets like Facebook and Google Analytics, but necessary for reducing deviation in e2e tests.)

I encourage others to repro and prove me wrong. My changes are in Redfin's main repo, pull request 27572 (declined).