对 基于webpack的单页应用 进行性能优化的几种方式
ZhenHe17 opened this issue · comments
GeShengming commented
场景一
面临问题:
小部分页面依赖体积较大的js库,影响了首屏加载时间
解决方案:
可以对依赖库进行按需加载,
- 对于支持import的js库,webpack4支持使用
import('path/to/module') -> Promise
按需加载; - 对于不支持import的js库,可以通过创建script标签并监听load事件进行按需加载,例如:
var paypalScript = document.createElement('script');
paypalScript.type = "text/javascript";
paypalScript.src = 'https://www.paypalobjects.com/api/checkout.js';
paypalScript.id = 'paypalScript';
document.body.appendChild(paypalScript);
paypalScript.addEventListener('load', function () {
// do something...
});
解决痛点:
当首屏是不需要依赖此库的页面,则不会加载此库。对于需要此依赖的页面,最终加载大小不变。
缺点:
按需加载的库不论是被webpack打包成单独的chunk或是通过script标签加载,都会成为一个单独的文件,且在对应加载代码执行时开始才加载。整体加载速度会慢于正常将库引入。
从不需要依赖库的页面跳转至需要依赖库的页面,将会有较长一段加载此库的加载时间。
使用建议:
满足以下条件则建议使用按需加载:
- 依赖库较大,影响了所有页面的加载时间
- 只有少部分依赖此库的页面
- 页面不会被跳转进入,或是不考虑跳转进入的加载时间带来的影响
场景二
本解决方案主要摘录于 Web 前端构建预渲染技术-孙凤鸣-美团
面临问题:
首屏加载时,加载至FCP(first contentful paint)的时间过长,页面加载过程有撕裂感
解决方案:
- 方案一:使用服务端渲染(server side rendering)
- 依赖服务
- 维护成本高
- 数据、结构一同输出
- 方案二:使用构建时预渲染(prerender),对应webpack配置:prerender-spa-plugin
- 不依赖服务
- 只输出结构
解决痛点:
将FCP时间节点提前,改善页面加载时的用户体验
使用建议:
- 方案一建议对服务器资源及维护资源有所考量后酌情使用
- 方案二建议对应用入口路由页面配置
场景三
面临问题:
一些结构、逻辑极其简单,几乎不依赖其他js库的页面如广告页、展示页,在首屏加载时也一样加载了单页应用的所有依赖。
解决方案:
通过webpack的配置(主要是entry和html webpack plugin),将单页应用拆解为多个单页应用
参考文章:
解决痛点:
大大加快了依赖少的页面的加载时间,使对应页面只加载自己需要的依赖库。
缺点:
由于拆解成了多个单页应用,跳转至另一个单页应用时将需要重新加载。服务器也需要对路由进行额外的配置。
使用建议:
将逻辑简单的广告页,展示页、或者依赖库差距大的几部分页面剥离成新的单页应用,重新配置依赖和路由,加快他们的加载速度。此时它们在同一个工程中,方便依赖的共用和维护管理