做者:Jogis
原文连接:https://github.com/yesvods/Bl...
转载请注明原文连接以及做者信息html
前端框架时代,为开发体验、效率与页面性能带来,很是大的革命。你们纷纷拿起一系列打包工具(webpack/parcel etc.),配合一系列加载器快速搭建起一个 SPA 页面。前端
SPA 应用带来的好处很是明显;react
可是也带来一系列性能问题:webpack
这些问题是使用 SPA 模式不可避免的,经过了解 SPA 加载运行过程,能够逐渐看清楚引发性能问题的根本缘由,经过精细化应用加载,来解决这些问题。git
比起通常的简单页面,SPA 最大的问题,就是在初始化之时引入大量框架方案脚本,这致使脚本体积随着项目发展体积愈发增大。github
不少人会关注脚本的加载体积,经过一系列方案来提高缓存命中率,减小脚本请求次数。在网络环境较差的移动端,尽可能减小请求时间意义很大。web
但这不是银弹,移动设备对脚本的解析、编译、执行性能较差(脚本加载参考《图说舌尖上的脚本》),即使能够彻底利用缓存,执行时间也是性能一大瓶颈。后端
性能优化原则:贫则独善其身,富则兼济天下。缓存
随着项目不断发展,页面不断增长,源源不断的第三方组件&工具库加入到Bundle
里面,良好的 SPA 架构能够保证大型 SPA 项目依旧保持极致的性能与体验。下面介绍一个优秀性能&体验 SPA 具有的特性:性能优化
快速启动应用,并行发起 Bundle 加载&拉取初始数据。相信你们已经发现了,SPA 初始化时候,不得不等待 bundle 返回并执行后,才会发起数据加载。
因为在移动设备上(即使有缓存)bundle 加载极为耗时,咱们能够充分利用这段时间将数据进行预加载。这项特性,使得后面的优化起到更加明显的效果。
以下示例代码:
// app.js Promise.all([load('bundle'), load('data')])
利用异步加载方式,在路由注册时提供异步拉取组件的方法,仅在须要进入对应路由时,对应组件才会被加载进来。
route({ Home: () => import('@/coms/home'), About: () => import('@/coms/about') })
在Home
和About
等路由里面,可能公用一套 UI 组件,若不将异步加载公用组件统一打包,每次加载 路由时,都会额外加载一套 UI 组件。经过将公用组件提取打包成Vendor
,能够减小下次进入路由加载体积与时间。
BTW:在webpack < 4
时,依旧须要手动维护异步加载组件公用组件。webpack4
提供更丰富的异步组件抽离方案。
当首屏加载完毕后,设备&网络处于空闲状态,能够对其余路由组件进行预加载,以便提高页面切换性能。
预加载是一个很是繁琐的过程,咱们能够设计一个极小启动器,在页面渲染后快速预加载后续组件:
// 全部包含Page的路由组件均会被预加载 boostraper.loadMatch('Page')
webpack4
在 ESM tree shaking
上作了极大优化,使得在引用工具库时候真正作到"按需打包",这要求不管是本身开发的工具库,抑或使用第三方工具库,打包&使用 ESM 版本很是必要。
根据 PWA 缓存策略,能够将访问的页面index.html
缓存起来,下次打开时候优先利用缓存,再发起请求更新缓存。这使得 SPA 应用几乎不须要额外时间即可加载应用首屏文档流。
Skeleton Page
SPA 首屏加载面临较长时间白屏,骨架图是一个完美的"缓兵之计"。在谷歌研究员的文章 中有提到,骨架图对用户体验有极大的提高:
快速展现
稳定加载
须要注意的是,骨架图应尽可能保持足够小巧与简单,以确保不会严重影响页面后续加载。
不管如何优化性能加载,在页面切换时候依旧须要获取页面数据,若处理很差,可能会在数据返回前有短暂的不友好"空白"。经过如下方式能够很好处理这个问题:
友好的切换前 Loading
转场动画
除了上述提到的 SPA 优化方案,Web 性能基础也是必备的基石(如域名收敛、合理文档结构)。性能优化本质是一个页面精细化监控运营的过程,也要求咱们对 Web 加载的过程与逻辑有更多的思考与理解。