Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in...
Transcript of Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in...
![Page 1: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/1.jpg)
Build-time Optimizationsin Frontend Engineering
Evan YouJSConf China 2017
![Page 2: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/2.jpg)
Frontend used to have no build steps...
![Page 3: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/3.jpg)
ModuleBuild Systems
CompilationInfrastructure
Compile-to-JSLanguages
CSS Processors
Today
![Page 4: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/4.jpg)
Make Code Smaller
![Page 5: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/5.jpg)
Minifiers: essentially Compilers
![Page 6: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/6.jpg)
Source Code Target Codecompiler
![Page 7: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/7.jpg)
Target Code
ParserAST
Codegen
Source Code
![Page 8: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/8.jpg)
Target Code
ParserAST
Codegen
Source Code
Transforms!Analysis!
Optimizations!
![Page 9: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/9.jpg)
Closure CompilerUglifyJS
BabiliButternut
![Page 10: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/10.jpg)
Closure CompilerUglifyJS
BabiliButternut
Says it’s a compilerin its name Implements its own
parser / AST / codegen
Built on top of BabelSimilar architectureto Buble (a lightweight ES2015 compiler)
![Page 11: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/11.jpg)
Early days: concat + minify
![Page 12: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/12.jpg)
Early days: concat + minifyProblem: global scope sucks
![Page 13: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/13.jpg)
Bundlers: let’s use modules
![Page 14: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/14.jpg)
Bundlers: let’s use modulesProblem: modules make things harder to minify
![Page 15: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/15.jpg)
registerModules([ function (module, exports) { // module 1 }, function (module, exports) { // module 2 }, // ...])
Each module is wrapped inside a separate function scope
![Page 17: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/17.jpg)
Module Scope Hoisting
main.js foo.js
bar.js
export function foo () { // ...}
export const bar = 123
import { foo } from './foo.js'import { bar } from './bar.js'
foo(bar)
![Page 18: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/18.jpg)
// foo.jsfunction foo () { // ...}
// bar.jsconst bar = 123
// main.jsfoo(bar)
Module Scope Hoisting
bundle.js
![Page 19: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/19.jpg)
// foo.jsfunction foo () { // ...}
// bar.jsconst bar = 123
// main.js// foo(bar)
Treeshaking
bundle.js
![Page 20: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/20.jpg)
// foo.jsfunction foo () { // ...}
// bar.jsconst bar = 123
// main.js// foo(bar)
Treeshaking
bundle.js
unused
unused
![Page 21: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/21.jpg)
Treeshaking
bundle.js
// nothing left!
![Page 22: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/22.jpg)
Treeshaking
Now also in webpack 3.x via webpack.optimize.ModuleConcatenationPlugin
![Page 23: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/23.jpg)
if (process.env.NODE_ENV !== 'production') { // code to drop in production build }
Conditional Block Trick
source.js
![Page 24: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/24.jpg)
if ('production' !== 'production') { // code to drop in production build }
Conditional Block Trick
source.js
Replaced during build
![Page 25: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/25.jpg)
if (false) { // unreachable }
Conditional Block Trick
source.js
![Page 26: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/26.jpg)
// nothing left!
Conditional Block Trick
source.js
![Page 27: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/27.jpg)
Make Code Faster
![Page 28: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/28.jpg)
AOT vs. JITDo more at build time
Do less at runtime
![Page 29: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/29.jpg)
Angular / Vue / GlimmerPre-compile templates to JavaScript
to avoid runtime compilation cost
![Page 30: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/30.jpg)
ReactOptimization via Babel plugins
https://github.com/thejameskyle/babel-react-optimize
![Page 31: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/31.jpg)
class MyComponent extends React.Component {
render() {
return (
<div className={this.props.className}>
<span>Hello World</span>
</div>
);
}
}
var _ref = <span>Hello World</span>;
class MyComponent extends React.Component {
render() {
return (
<div className={this.props.className}>
{_ref}
</div>
);
}
}
input output
Hoisting Static Elements
![Page 32: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/32.jpg)
SvelteCompile everything to vanilla JS with no runtime lib
![Page 33: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/33.jpg)
<h1>Hello {{name}}!</h1>
// only showing initial render code
h1 = createElement( 'h1' );
text = createText(
text_value = state.msg
);
insertNode( h1, target, anchor );
appendNode( text, h1 );
template
output
Initial Render
![Page 34: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/34.jpg)
// only showing update code
if (text_value !== (text_value =
state.msg)) {
text.data = text_value;
}
output
Updates
<h1>Hello {{name}}!</h1>
template
![Page 35: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/35.jpg)
Relay ModernPre-Compile GraphQL Queries & Schemas
![Page 36: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/36.jpg)
graphql` fragment MyComponent on Type { field }`
GraphQL QueryRuntime Artifacts & Types
Getting rid of expensive runtime query construction via static build step
![Page 38: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/38.jpg)
(function () {
function fib(x) {
return x <= 1
? x
: fib(x - 1) + fib(x - 2);
}
global.x = fib(23);
})();
(function () {
x = 28657;
})();
input output
Partial Evaluation(moving more computation to build time)
![Page 39: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/39.jpg)
RaktApplication-level optimizations via compilation
(proof of concept)
![Page 40: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/40.jpg)
Compile-time Optimizations in Vue
![Page 41: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/41.jpg)
<div>
<p class="foo">
this is static
</p>
</div>
function render() {
return this._renderStatic(0)
}
templateoutput
Hoisting Static Trees
![Page 42: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/42.jpg)
<div>
<p class="foo">
{{ msg }}
</p>
</div>
return h("div", [
h(
"p",
{ staticClass: "foo" },
[...]
)
])
templateoutput
Skipping Static Bindings
![Page 43: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/43.jpg)
<ul>
<li v-for="i in 10">
{{ i }}
</li>
</ul>
return h("ul", [
renderList(10, i => {
return h("li", i)
})
], 0) // ← optimization hint
templateoutput
Skipping Children Array Normalization
![Page 44: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/44.jpg)
SSR: optimizing Virtual DOMrender functions into string concat
<div>
<p class="foo">
{{ msg }}
</p>
<comp></comp>
</div>
function render() {
return h("div", [
this._ssrString(
"<p class=\"foo\">" +
this.msg +
"</p>"
),
h("comp") // mix w/ vdom
])
}
template
output
![Page 45: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/45.jpg)
SSR: inferring async chunks
main.js 0.js 1.js 1.js
Client Build
Manifest
Server Build
Manifest
Server Renderer
Serverbundle.js
Server build
Client build
Code-split Chunks
![Page 46: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/46.jpg)
SSR: inlining Critical CSS
Single File Vue Component
StyleInject via
Lifecycle hook
vue-server-renderer
InlinedCriticalCSS
vue-loadercompilation
![Page 47: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/47.jpg)
![Page 48: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/48.jpg)
IDEA: compile away parts of Vue that’s not used in your app
Dead code elimination
AnalyzeUnused features Feature Flags
e.g.No
<transition> used
webpack + DefinePlugin
Template
![Page 49: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/49.jpg)
IDEA: Styletron-style Atomic CSS generation at build time
![Page 50: Build-time Optimizations in Frontend Engineering · 2019-06-05 · Build-time Optimizations in Frontend Engineering Evan You JSConf China 2017](https://reader033.fdocuments.in/reader033/viewer/2022042300/5eca7b8103de2c4cd02dc2f4/html5/thumbnails/50.jpg)
The build step affordsmany more possibilities!
We’ve only scratched the surface