如何处理过多的JavaScript 2021-10-31 默认分类 暂无评论 2049 次阅读 ![bundle-size.jpg][1] 尽量减少页面中的JavaScript数量是确保快速的用户体验的一个重要步骤。 这篇文章将解释为什么包的大小很重要,并推荐你可以遵循的工具和流程,以监测、可视化,以及最重要的是,缩小你的JS包。 **软件包的大小如何影响性能?** ----------------- 大量的JavaScript在两个不同的阶段对网站速度产生负面影响。 1. 在页面加载期间:大的包需要更长的时间来下载。 2. 在解析和编译过程中:大的包需要更长的时间才能变成机器代码,这就延迟了JS的初始化。 如果你的用户碰巧在一个缓慢的、斑点的网络上,一个电池电量不足的设备,甚至只是一个动力不足的安卓系统,大的捆绑包很可能会在加载、渲染、用户互动甚至页面滚动时造成延迟。 当然,你的用户不一定要使用老旧的设备或缓慢的网络来获得不合格的体验。通过缓存、压缩和最小化脚本资源,可以部分地缓解大数据包的影响,尽管减少数据包的大小是保证快速页面的唯一方法。 通过保持页面尽可能的轻盈,你可以确保每个访问者都有最好的机会获得良好的体验。 **哪些性能指标会受到包的大小的影响?** --------------------- 简而言之,大部分都是 含有大量脚本的页面会延迟最大内容的绘制,导致累积布局转移,增加首次输入延迟、总阻塞时间和互动时间。 这些指标的缓慢读数可以量化不良的用户体验,并可能导致SEO排名受到惩罚。 **多少JavaScript是太多了?** --------------------- 当我们谈论性能时,我们通常关注的是资源的压缩大小。然而,一旦资源被解压缩,它们将被放大2-3倍。 例如,一个有300kB压缩脚本的页面,一旦解压缩,就会产生900kB-1.3MB。 ***对于CPU受限的设备,多兆字节的有效载荷对性能的损害尤其大。*** ![cost-of-javascript.png][2] 我们建议将页面限制在最大<300kb的脚本(压缩)。在可能的情况下,使用代码分割将你的代码分割成50KB或更小的块状。这样,浏览器可以并行下载JS资源,充分利用HTTP 2复用。 **新的全局基线为电线上的HTML/CSS/字体和300-350KiB的JavaScript(压缩)留下了~100KiB(压缩)的空间。** ---------------------------------------------------------------------- **让你的代码保持快速的工具和自动程序** --------------------- **为成功设置你的编辑器** 在Sublime或VSCode中使用导入成本插件,在你编码时报告第三方库的大小。 对于import成本,你可以为小型或中型package设置 thresholds。我们建议设置比默认值更积极的目标。 ``` // Upper size limit, in KB, that will count a package as a small package "importCost.smallPackageSize": 15, // Upper size limit, in KB, that will count a package as a medium package "importCost.mediumPackageSize": 50, ``` **可视化你的package包括什么** -------------------- 使用Bundle Buddy、source-map-explorer和webpack-bundle-analyzer等工具来生成交互式bundle树状图。 在树状图中,较大的块与较大的文件尺寸相关--是快速发现大型导入文件的完美选择。 ![bundle-analyzer.png][3] 通过直观地探索捆绑,你将能够识别比预期大的模块。 **寻找较小的、可替代的第三方库** ------------------ 通常我们选择一个库的依赖,然后永远使用它。但是,可能有更多你不知道的轻量级替代品。 使用BundlePhobia.com,你可以扫描一个项目的package.json文件或搜索一个特定的npm包。 ![bundlephobia.png][4] 当一个库是 "树状摇动 "时,像webpack、rollup或esbuild这样的捆绑工具可以在构建过程中执行未使用的代码消除。如果可以的话,请选择使用树状摇动的库。 ![bundlephobia-similar-packages.png][5] 阻止选定的软件包被使用 沟通为什么要使用一个包而不是另一个包,在团队或公司之间是很困难的。为了解决这个问题,你可以使用ESLint的no-restricted-import来警告或者在包含一个受限制的包时出错。 在下面的例子中,当我们使用moment包时,ESLint会使构建失败,建议使用date-fns作为一个经过审查的替代方案。 ``` { "rules": { "no-restricted-imports": [ "error", { "paths": [ { "name": "moment", "message": "Use date-fns instead. See https://bundlephobia.com/package/moment" } ] } ] } } ``` 动态加载组件和依赖性 大多数流行的捆绑工具,如Webpack、ESBuild、Rollup或Parcel,都可以对你的代码和依赖关系进行代码分割。代码拆分允许你根据需要懒散地加载你的应用程序的一部分,从而导致更小的捆绑规模和更快的初始加载体验。 React、Next、Angular和Vue都提供了一些工具,使懒惰加载组件变得更加直接。这里有一个React的例子 ``` import React, { Fragment, Suspense } from 'react' import Skeleton from './Skeleton' // Lazy loading React import const Dashboard = React.lazy(() => import('./Dashboard')) function Page() { return ( }> ) } ``` Lazy-loading有很多好处 - 加载的初始脚本更少 - 并行加载更多的小型请求 - 不经常改变的代码可以被长期缓存。 懒加载的效果很好: - 基于路线/导航的懒惰加载:分割每个页面所需的脚本。 - 基于交互的懒惰加载:在需要时加载依赖性,例如:当浏览者打开一个面板时。 **倾向于对主要内容进行服务器端渲染** -------------------- 无论是对于终端用户还是SEO蜘蛛,我们必须尽可能快地渲染主要内容。 对于内容驱动的页面,我们推荐服务器端渲染(SSR)而不是单页应用(SPA)。单页应用适合于会话时间较长的应用或无缝过渡的界面(如购物车),但同时,我们必须快速显示内容。可以的话就在服务器端进行渲染。 **用facades懒加载第三方资源** -------------------- 业务需求经常推动第三方的使用,但这并不意味着开发者不能影响第三方的性能。 在Calibre,我们使用react-live-chat-loader将交互时间提高了30%,这是我们为Help Scout、Intercom、Facebook Messenger、Drift、Userlike和Chatwoot提供的Facade libraries。 Facade libraries的工作原理是通过临时显示一个 "假的"(非交互式)聊天小部件、视频面板或支持工具,延迟第三方的加载,直到页面最终完成关键内容的加载。 作为一个团队,你可以使用几种策略来控制第三方的性能。以下是我们最喜欢的一些策略: - 延迟第三方的加载时间,直到需要时才使用facades。 - 对第三方域名使用dns-refetching,例如。. - 倾向于自己捆绑第三方库,而不是使用他们的CDN。 - 比较有和没有第三方脚本的页面性能。与对第三方工具作出决定的人分享结果! - 在与第三方的合同协议中要求性能服务协议。 **向最新的浏览器提供ES6模块** ------------------ 支持旧的浏览器会阻碍你使用新技术(以及它们的性能优势!)。不过,我们还是需要小心,不要突然放弃对传统技术的支持,这可能会导致无法使用。 考虑将你的构建分成两个构建: - 一个ES5构建,支持浏览器、polyfills和Babel转码。 - ES2015+构建,利用async/await、Promises、箭头函数、Map和Set类型以及用于懒散加载的动态导入。 ``` ``` **持续监控JavaScript的大小** --------------------- 优化包的大小不会因为一次内务工作而结束(我们希望如此!)。随着代码库的增长和演变,我们需要保障措施来控制JavaScript的大小。前面提到的一些工具在这里会有帮助。 另一个推荐的策略是使用性能预算。通过设定目标,你可以为指标以及它们对用户体验的影响建立问责制。在Calibre,我们为整体的JavaScript大小和第三方JavaScript创建了预算,当我们超过预算时就会得到提醒。 ![performance-budgets.png][6] 你还可以使用Lighthouse来设置性能预算,并编写你自己的解决方案! 通过结合使用上述技巧和策略,你可以改善用户和开发人员的体验。如果你有其他的技巧或成功的工作流程,请告诉我们! [1]: http://guobacai.com/usr/uploads/2021/10/355688691.jpg [2]: http://guobacai.com/usr/uploads/2021/10/2012208222.png [3]: http://guobacai.com/usr/uploads/2021/10/1531288985.png [4]: http://guobacai.com/usr/uploads/2021/10/446041368.png [5]: http://guobacai.com/usr/uploads/2021/10/3056002898.png [6]: http://guobacai.com/usr/uploads/2021/10/26853222.png 标签: javascript, 编辑器, npm, 组件
评论已关闭