web-performance-with-webpack
Web Performance
Top Performance Issues
- Top three causes of web performance issues
- Amount of JavaScript for initial download
- Amount of CSS for initial download
- Amount of network request on initial download
Performance Goals
- Goals
- <=200kb(uncompressed) initial JavaScript [total].
- <=100kb(uncompressed) initial CSS [total].
- HTTP: <=6 initial network calls
- HTTP/2: <=20 initial network calls
- 90% code coverage(only 10% code unused)
Code Coverage
在Chrome开发者工具中按下shift + CMD + p,输入coverage,即可查看代码加载时的使用率。
Code Splitting
- Code splitting
- Process of splitting pieces of your code into async chunks at build time.
Types of Code Splitting
Why should care about code splitting
- The future of web is mobile
- The average mobile website takes 14 seconds to get interactive
- Load less code => interactive faster
Two types of code splitting
- Static
- “Dynamic”
Static code splitting
- When to use:
- “Heavy” JavaScript
- 例如之后才会用到的一些第三方包(three.js之类)
- Anything temporal
- 像弹框等只有满足条件才可见的
- Routes
- 只加载用户可见的路由页面
- “Heavy” JavaScript
- When to use:
Code Splitting Demonstration
1 | import Listener from "./listener.js"; |
例如我们要实现一个点击加载footer模块的功能,简单实现就是先引入,在点击之后插入DOM。或者我们也可以使用Dynamic import,代码类似如下:
1 | button.addEventListener('click', e => { |
Webpack Code Splitting Under the Hood
当我们使用动态引入之后,分析打包后生成的文件可见不止一个js文件,而是额外生成了动态引入的js文件。
分析打包后的代码可见,webpack会将依赖以数组的形式进行缓存,在使用动态引入时,会在数组加载完毕新的包后进行异步操作。
Load a Heavy Module Asynchronously
加入我们需要引入GSAP,引入后分析打包文件体积可见增加了几百kb。
我们可以使用如下语法来异步引入
1 | const getGSAP = () => import('gsap') |
此时再进行打包可见整个GSAP库以被单独放入一个打包文件内。
Code Splitting in Vue, React & Frameworks
使用Vue时,我们只需在引入组件时将组件引入形式更改为异步引入,而无需更改其他代码即可。
使用React,我们可以使用React Loadable库。
Code Splitting Named Exports
截止到此workshop时,webpack只能异步引入使用export default导出的模块,所以无法tree shaking。
加入我们要引入lodash其中一个方法,我们只能使用如下语法
1 | const getUnique = () => import('lodash-es/unique') |
Vendor Bundlers are an Anti Pattern
有时我们会使用缓存来缓存所有文件并希望能提高加载速度。但是用网络缓存只能减少网络请求时间,js的解析执行仍需要一段时间。作者认为提升性能的主要措施还是减少首次加载时的文件体积。
Dynamic Code Splitting
此处的”动态“代码分离并不是真的”动态“,而是一个技巧。
1 | const getTheme = themeName => import(`./src/themes/${themeName}`); |
上面的代码中基于运行时的状态引入了异步模块。但是webpack在打包时仍会将src下的themes中所有文件进行打包,只是在引入时”动态“引入。
- When to use:
- A/B testing
- Theme
- Condition
Module Methods & Magic Comments
Introducing Magic Comments
当我们将文件打包之后debug并不方便,所以增加了magic comments的功能。
1 | ) |
在webpack.config.js的output中可以添加配置如下
1 | output: { |
Webpack Modes
动态导入的模块的模式,目前共四种
- lazy
- lazy-once
- eager
- weak