Cut it Up
Varun Vachhar
Director, UI Architecture at Rangle.io
✂️
Cut it Up 2
Bundling
What is code splitting?
Splitting applications
Code splitting strategies
Optimizing lazy loading
Outline
01
02
03
04
05
01
02
03
04
05
Bundling
Cut it Up 3
Cut it Up
The process of compiling small pieces
of code into something larger and more
complex, such as a library or
application.
Bundling
4
Cut it Up
Task Runners
Bundling
Used to automate tasks in your
development workflow. You can use
them to process, concatenate and
minify assets of a certain type.
5
Cut it Up
Used to bundle several modules into
one or more optimized bundles for the
browser. Most notable bundlers are
Webpack, Parcel and Rollup.
Bundlers
Bundling
6
Everything is a Module!
● All files – CSS, HTML, SCSS, PNG, etc.
● ES2015 import statements
● require() statements
● @import statement in stylesheets
● Image url in a stylesheet or HTML
Cut it Up
Bundling
7
Cut it Up
Less to Learn
CLIs make it easy to create an
application that works, right out of the
box and generates optimized bundles
which are ready to deploy.
Bundling
❯ vue create my-project
❯ npx create-react-app my-app
❯ ng new my-project
8
Cut it Up Uniqlo Design System
Webpack
Bundling
Loaders 🖨🖨
Transform files into modules
Plugins 🔌
Customize or enhance the webpack
build process in a variety of ways.
module.exports = {
entry: '📄 Entry',
output: '📦 Output',
module: {
rules: ['🖨🖨
Loaders'],
},
plugins: ['🔌 Plugins'],
};
01
02
03
04
05
Cut it Up 10
What Is Code
Splitting?
* The need for mobile speed: How mobile latency impacts publisher revenue
53%*
Of mobile site visits were abandoned if a
page took longer than 3 seconds to load.
Load Times
12
Instead of shipping all the JavaScript to the user on
first load, split your bundle into multiple chunks
and only send what is necessary at the very
beginning.
Cut it Up 13
Code Splitting
Cut it Up 14
Code Splitting
HTML
Main JS Chunk
CSS
Lazy-load chunks
as the user navigates
chunk #1 chunk #2 chunk #3
interactive
Splitting
Applications
01
02
03
04
05
Cut it Up 15
Cut it Up 16
import math from './math';
document.getElementById('#calculate')
.addEventListener('click', e => {
e.preventDefault();
math.calculateResult();
});
Static Imports
main.js
Cut it Up 17
Dynamic Imports
document.getElementById('#calculate')
.addEventListener('click', e => {
e.preventDefault();
import('./math').then(math => {
math.calculateResult();
});
});
main.js
math.js
When Webpack comes across the
import() syntax, it automatically starts
code-splitting your app.
Cut it Up
Code Splitting
18
Cut it Up 19
Static Components — React
import Photos from './Photos';
const Album = (
<div>
<Photos />
</div>
);
Cut it Up 20
Async Components — React
const Photos = React.lazy(() => import('./Photos'));
const Album = (
<div>
<Photos />
</div>
);
Cut it Up 21
Async Components — Vue
<template>
<div> <album></album> </div>
</template>
<script>
export default {
components: { album: () => import('./Album') }
};
</script>
Code Splitting
Strategies
01
02
03
04
05
Cut it Up 22
Cut it Up
Code splitting requires a bit of extra
effort as you have to decide what and
where to split.
Bundling
23
Cut it Up
Great option to get started with code-
splitting.
Break the application into chunks per
route, and then load that chunk when
the user navigates to that route.
Route Based
Code Splitting Strategies
24
about.js blog.jsmain.js
home.js
const Home = React.lazy(() => import('./Home'));
const About = React.lazy(() => import('./About'));
const Blog = React.lazy(() => import('./Blog));
25
Route Based Code-Splitting — React
const App = () => (
<Router>
<React.Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/blog" component={Blog}/>
</Switch>
</React.Suspense>
</Router>
);
26
const Home = () => ({ component: import('./Home'), loading: Loader });
const About = () => ({ component: import('./About'), loading: Loader });
const Blog = () => ({ component: import('./Blog), loading: Loader });
const router = new VueRouter({
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/blog, component: Blog },
],
});
Route Based Code-Splitting — Vue
Cut it Up
Chunk Dependencies
28
Cut it Up
Automatically identifies modules which
should be split and avoids duplicated
dependencies across chunks.
Split Chunks Plugin
Code Splitting Strategies
29
optimization: {
splitChunks: {
chunks: 'all',
name: false,
}
}
Chunks are code which is broken apart from main bundle into their
own files.
● Vendor — dependency code coming from node_modules
● Common — code which is shared between different chunks
● Async — code which can be lazy-loaded
Cut it Up
Chunks
30
Cut it Up
Split components that load content on
demand or are hidden by default —
Tabs, Modals and Alerts
On-demand Content
Code Splitting Strategies
31
Cut it Up
Multi-step features such as checkout
flows which continue based clicks
should be split per step.
Isolate Process Flows
Code Splitting Strategies
32
Optimizing
Lazy Loading
01
02
03
04
05
Cut it Up 33
Cut it Up
A browser mechanism that prefetches
documents that the user might visit in
the near future
Prefetch
Optimizing Lazy Loading
34
Cut it Up
Detects visibility of an element
Intersection Observer
Optimizing Lazy Loading
35
from Faster Page-Loads by Chidume Nnamdi
Optimistically & Idly
Prefetch Resources
An IntersectionObserver is
registered for all links
Waits until the browser is idle
Prefetches URLs to the links
Optimizing Lazy Loading
36
Cut it Up
Or, use Quicklink
github.com/GoogleChromeLabs/quicklink
Optimizing Lazy Loading
37
Cut it Up
01
Your app was likely bootstrapped using a
CLI and using webpack for bundling.
Summary
38
02
Do enable route based code-splitting and
consider splitting on-demand
components.
03
Leverage the Split Chunks Plugin to avoid
duplication of code across chunks.
04
Optimistically and idly prefetch the split
chunks.
Thank you!
varun.ca
@winkerVSbecks
Cut it Up Rangle.io

Cut it up

  • 1.
    Cut it Up VarunVachhar Director, UI Architecture at Rangle.io ✂️
  • 2.
    Cut it Up2 Bundling What is code splitting? Splitting applications Code splitting strategies Optimizing lazy loading Outline 01 02 03 04 05
  • 3.
  • 4.
    Cut it Up Theprocess of compiling small pieces of code into something larger and more complex, such as a library or application. Bundling 4
  • 5.
    Cut it Up TaskRunners Bundling Used to automate tasks in your development workflow. You can use them to process, concatenate and minify assets of a certain type. 5
  • 6.
    Cut it Up Usedto bundle several modules into one or more optimized bundles for the browser. Most notable bundlers are Webpack, Parcel and Rollup. Bundlers Bundling 6
  • 7.
    Everything is aModule! ● All files – CSS, HTML, SCSS, PNG, etc. ● ES2015 import statements ● require() statements ● @import statement in stylesheets ● Image url in a stylesheet or HTML Cut it Up Bundling 7
  • 8.
    Cut it Up Lessto Learn CLIs make it easy to create an application that works, right out of the box and generates optimized bundles which are ready to deploy. Bundling ❯ vue create my-project ❯ npx create-react-app my-app ❯ ng new my-project 8
  • 9.
    Cut it UpUniqlo Design System Webpack Bundling Loaders 🖨🖨 Transform files into modules Plugins 🔌 Customize or enhance the webpack build process in a variety of ways. module.exports = { entry: '📄 Entry', output: '📦 Output', module: { rules: ['🖨🖨 Loaders'], }, plugins: ['🔌 Plugins'], };
  • 10.
    01 02 03 04 05 Cut it Up10 What Is Code Splitting?
  • 12.
    * The needfor mobile speed: How mobile latency impacts publisher revenue 53%* Of mobile site visits were abandoned if a page took longer than 3 seconds to load. Load Times 12
  • 13.
    Instead of shippingall the JavaScript to the user on first load, split your bundle into multiple chunks and only send what is necessary at the very beginning. Cut it Up 13 Code Splitting
  • 14.
    Cut it Up14 Code Splitting HTML Main JS Chunk CSS Lazy-load chunks as the user navigates chunk #1 chunk #2 chunk #3 interactive
  • 15.
  • 16.
    Cut it Up16 import math from './math'; document.getElementById('#calculate') .addEventListener('click', e => { e.preventDefault(); math.calculateResult(); }); Static Imports main.js
  • 17.
    Cut it Up17 Dynamic Imports document.getElementById('#calculate') .addEventListener('click', e => { e.preventDefault(); import('./math').then(math => { math.calculateResult(); }); }); main.js math.js
  • 18.
    When Webpack comesacross the import() syntax, it automatically starts code-splitting your app. Cut it Up Code Splitting 18
  • 19.
    Cut it Up19 Static Components — React import Photos from './Photos'; const Album = ( <div> <Photos /> </div> );
  • 20.
    Cut it Up20 Async Components — React const Photos = React.lazy(() => import('./Photos')); const Album = ( <div> <Photos /> </div> );
  • 21.
    Cut it Up21 Async Components — Vue <template> <div> <album></album> </div> </template> <script> export default { components: { album: () => import('./Album') } }; </script>
  • 22.
  • 23.
    Cut it Up Codesplitting requires a bit of extra effort as you have to decide what and where to split. Bundling 23
  • 24.
    Cut it Up Greatoption to get started with code- splitting. Break the application into chunks per route, and then load that chunk when the user navigates to that route. Route Based Code Splitting Strategies 24 about.js blog.jsmain.js home.js
  • 25.
    const Home =React.lazy(() => import('./Home')); const About = React.lazy(() => import('./About')); const Blog = React.lazy(() => import('./Blog)); 25 Route Based Code-Splitting — React const App = () => ( <Router> <React.Suspense fallback={<div>Loading...</div>}> <Switch> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> <Route path="/blog" component={Blog}/> </Switch> </React.Suspense> </Router> );
  • 26.
    26 const Home =() => ({ component: import('./Home'), loading: Loader }); const About = () => ({ component: import('./About'), loading: Loader }); const Blog = () => ({ component: import('./Blog), loading: Loader }); const router = new VueRouter({ routes: [ { path: '/', component: Home }, { path: '/about', component: About }, { path: '/blog, component: Blog }, ], }); Route Based Code-Splitting — Vue
  • 27.
    Cut it Up ChunkDependencies 28
  • 28.
    Cut it Up Automaticallyidentifies modules which should be split and avoids duplicated dependencies across chunks. Split Chunks Plugin Code Splitting Strategies 29 optimization: { splitChunks: { chunks: 'all', name: false, } }
  • 29.
    Chunks are codewhich is broken apart from main bundle into their own files. ● Vendor — dependency code coming from node_modules ● Common — code which is shared between different chunks ● Async — code which can be lazy-loaded Cut it Up Chunks 30
  • 30.
    Cut it Up Splitcomponents that load content on demand or are hidden by default — Tabs, Modals and Alerts On-demand Content Code Splitting Strategies 31
  • 31.
    Cut it Up Multi-stepfeatures such as checkout flows which continue based clicks should be split per step. Isolate Process Flows Code Splitting Strategies 32
  • 32.
  • 33.
    Cut it Up Abrowser mechanism that prefetches documents that the user might visit in the near future Prefetch Optimizing Lazy Loading 34
  • 34.
    Cut it Up Detectsvisibility of an element Intersection Observer Optimizing Lazy Loading 35
  • 35.
    from Faster Page-Loadsby Chidume Nnamdi Optimistically & Idly Prefetch Resources An IntersectionObserver is registered for all links Waits until the browser is idle Prefetches URLs to the links Optimizing Lazy Loading 36
  • 36.
    Cut it Up Or,use Quicklink github.com/GoogleChromeLabs/quicklink Optimizing Lazy Loading 37
  • 37.
    Cut it Up 01 Yourapp was likely bootstrapped using a CLI and using webpack for bundling. Summary 38 02 Do enable route based code-splitting and consider splitting on-demand components. 03 Leverage the Split Chunks Plugin to avoid duplication of code across chunks. 04 Optimistically and idly prefetch the split chunks.
  • 38.
  • 39.
    Cut it UpRangle.io

Editor's Notes

  • #3 How many of you work build apps or websites with JS on a daily basis? How many of you rely on webpack as a build tool?
  • #5 Bundling is the process of combining and optimizing multiple modules into one or more production ready bundles. Modules as in JS modules — essentially multiple files
  • #6 Such as Grunt and Gulp Manually control the order Fairly rudimentary approach
  • #7 Webpack Parcel Dependency graph which maps every module your project needs and generates one or more bundles.
  • #8 Treat everything as a module Loaders — transform files into modules
  • #9 Most major JS frameworks now have CLIs Set up build tooling for you They all use webpack Less for you to learn
  • #10 You don’t need to be an expert in webpack CLIs do the heavy lifting Just a rough understanding of how build tools work Going to be focusing on webpack in this talk but, same concepts apply to parcel
  • #11 What exactly is code splitting and why should you care about it
  • #12 This was our approach to shipping JS. Didn’t consider if the user can handle that or not Sending large JavaScript payloads impacts the speed of your site significantly.
  • #13 On desktop 50% of users are likely to abandon if site doesn’t load in 2 seconds https://www.thinkwithgoogle.com/intl/en-154/insights-inspiration/research-data/need-mobile-speed-how-mobile-latency-impacts-publisher-revenue/
  • #15 As the user navigates the app asynchronously loads chunks of JS
  • #16 Reduce JavaScript payloads with code-splitting
  • #17 Fairly common to work with JS modules Import syntax to import code from one module to another Here the code for math.js will just be included in the main.js bundle
  • #18 Bundlers support another syntax — dynamic import Import as a function Asynchronous, returns a promise Here math.js is a chunk — loaded asynchronously when this code is executed
  • #19  You don’t need to do anything else
  • #21 Use dynamic import + React.lazy to turn a regular component into an async component Webpack will code-split it out into its own chunk We can use the Async component just like a regular component
  • #22 Supports async components without the need of any utility
  • #23 Different types of code-splitting and how you can apply it to your work
  • #25 Building a blog with home, about and blog pages
  • #26 Suspense lets components “wait” for something before rendering. While waiting or in case of failure render fallback
  • #27 Loading just like suspense. Can even give fallback components for error states
  • #29 What about shared dependency code? Eg react is used by all these chunks — is it duplicated? Not a good option — we are splitting but, now shipping more code than we need to Webpack allows you to generate common or vendor chunks
  • #30 Add the following to your webpack config As long as your dependencies remain the same, the chunk name is consistent. Which means you can cache it! Again, this is something you get for free if you use CLI The plugin gives you a lot of options to control how chunks are generated and how large they can be
  • #33 Why load step 10 when the user is just viewing step 2 of the flow The code that makes up the module does not get included into the initial bundle and is now lazy loaded, or provided to the user only when it is needed after the form submission. To further improve page performance, preload critical chunks to prioritize and fetch them sooner. link rel="prefetch"
  • #34 We’ve split our application into chunks, but how do we load these chunks in the most optimal way
  • #35 Use it to load chunks that you know a lot of users request Doesn’t impact initial load time
  • #36 Detect whether an element is visible in the viewport or not Does it in a very performant way!
  • #37 Combining these two APIs we can… As those links scroll into the view you trigger prefetch for that url https://blog.bitsrc.io/faster-page-loads-by-prefetching-links-during-idle-time-5abe42dacf9 https://www.gatsbyjs.org/blog/2019-04-02-behind-the-scenes-what-makes-gatsby-great/#route-based-code-splitting