Skip to content

Latest commit

 

History

History
212 lines (191 loc) · 5.23 KB

deck.mdx

File metadata and controls

212 lines (191 loc) · 5.23 KB

import { CodeSurfer } from 'mdx-deck-code-surfer' export { future as theme } from 'mdx-deck/themes' import { Split } from 'mdx-deck/layouts' import { Appear, Image, Head } from 'mdx-deck' import nightOwl from "prism-react-renderer/themes/nightOwl"

<title>Better Performance with Lazy-Loading and Code-Splitting</title>

Better Performance with Lazy-Loading and Code-Splitting

Stockholm ReactJS Meetup - September 2018

About me

👋 I'm Jose and I work as an Engineer in Spotify

🚀 I like building & using web sites with good performance

@jmperezperez on Twitter


Performance in the age of components


What we'll talk about

  1. Create a component to perform lazy-loading
  2. Apply the component to other use cases
  3. Loading polyfills on-demand
  4. Existing implementations
---

Improving performance of our sites by loading only what is needed


export default Split

const Page = () => {
  <div>
    <Header />
    <Gallery />
    <Map />
    <Footer />
  </div>;
};
Most times you would include all the scripts and CSS needed to render all sections as soon as the user visits the page. Until recently it was difficult to define a module’s dependencies, and load what was needed.

- How likely is it for the user to see the header?
- What about the map?

How to load only what is needed?

  • Track dependencies (YUI Loader, RequireJS → ES6 + dynamic imports)
  • Lazy-loading (Scroll + Resize listeners → IntersectionObserver)

Lazy-loading is ❤️


Lazy-Loading has trade-offs too 💔


export default Split

Don’t lazy load above the fold

export default Split

Lazy load a bit earlier than when it’s needed

Invisible content in some scenarios

  • printing the page
  • RSS readers
  • SEO

A small component to detect when an area is visible


Compositional Patterns


<CodeSurfer title="High Order Components" theme={nightOwl} code={require("!raw-loader!./snippets/comp-pattern-hoc.mdx")} />

<CodeSurfer title="Function as Child Component aka Render Callback" theme={nightOwl} code={require("!raw-loader!./snippets/comp-pattern-child.mdx")} />


<CodeSurfer title="Our Component ⬇️" theme={nightOwl} code={require("!raw-loader!./snippets/comp-basic.mdx")} steps={[ { ranges: [[6, 6], [24, 28], [32,32]]}, { ranges: [[4, 4], [9, 12], [29, 31]]}, { ranges: [[14, 18]]}, ]} />

<CodeSurfer title="Using it" theme={nightOwl} code={require("!raw-loader!./snippets/comp-basic-use.mdx")} />

<CodeSurfer title="Stateless Child Component ⬇️" theme={nightOwl} code={require("!raw-loader!./snippets/gallery-stateless.mdx")} steps={[ { ranges: [[1, 1], [5, 9]], notes: "Using isVisible ➡️️" } ]} />

TIP 💡 : make sure that you reserve the area for the lazy-loaded component

<CodeSurfer title="Stateful Child Component ⬇️" theme={nightOwl} code={require("!raw-loader!./snippets/map.mdx")} steps={[ { ranges: [[30, 38]]}, { ranges: [[8, 28]]} ]} />

<CodeSurfer title="Moving state to the Observer component" theme={nightOwl} code={require("!raw-loader!./snippets/has-been-visible.mdx")} />

More use cases


<CodeSurfer theme={nightOwl} code={require("!raw-loader!./snippets/conference-data.mdx")} steps={[ { ranges: [[9, 21]] } ]} />

Polyfilling IntersectionObserver on-demand


<CodeSurfer title="Disabling lazy-loading if IO is not supported" theme={nightOwl} code={require("!raw-loader!./snippets/disable-lazy-loading.mdx")} steps={[ { ranges: [[6, 6], [12, 12]] } ]}/>

<CodeSurfer title="Requesting a polyfill on demand" theme={nightOwl} code={require("!raw-loader!./snippets/polyfill-on-demand.mdx")} steps={[ { ranges: [[4, 8]] } ]}/> />

Safari requests the polyfill for intersection-observer on demand.

No need to ship it to browsers that support it natively.


Code Splitting, CSS-in-JS & more

  • react-router and Next.js have made code-splitting easy to implement
  • lazy-loading can be applied to other resources (SVGs, CSS)
  • With CSS-in-JS we take code splitting further, loading CSS on demand
--- ## Useful implementations - [thebuilder/react-intersection-observer](https://github.com/thebuilder/react-intersection-observer) - [researchgate/react-intersection-observer](https://github.com/researchgate/react-intersection-observer) --- ## Conclusion Componentization makes code-splitting and loading assets on-demand easier than ever! --- ## Buzz words → Useful tools ES6 + CSS-in-JS + bundlers = High Performance Sites --- ## Thanks! [@jmperezperez](https://twitter.com/jmperezperez) / [jmperezperez.com](https://jmperezperez.com)