关于前端:6s到1s-双端应用的秒开优化之路

39次阅读

共计 2894 个字符,预计需要花费 8 分钟才能阅读完成。

背景

近来,咱们团队开始尝试用新的解决方案(双端开发,同时投放 PC 端和挪动端)解决前端资源短缺问题。但提测后,测试提出咱们挪动端页面首屏太慢(6s+),体验极差。

我尝试在 PC 端关上这个页面,耗时 4s+,加载瀑布流长上面这样:

粗略一剖析,存在上面三个问题:

  • 利用页面采纳了懒加载策略,详见红色圈注区域;
  • 入口 js,包体积太大,gzip 之后还有 1.3M, 原始大小 4M+
  • 日常动态资源未开启 cdn

优化三部曲

一、利用架构优化

在利用架构中,懒加载是一个常见的优化技巧,它能够在须要时才加载资源,缩小利用的启动工夫和流量耗费。然而,懒加载并不是万能的,有时候过多的懒加载反而会升高利用性能。因而,在进行利用架构优化时,应该依据具体情况衡量是否采纳懒加载。

依据瀑布流联合上图的剖析,资源的加载用时 4s+,index.html 的工夫对于前端来说是不可控的,这齐全取决于域名的解析和服务器的响应。但 js 和 css 这一段是齐全可控的,咱们能够把前面 500ms 的资源加载用时提前,也就是去除懒加载的架构计划。

二、包体积优化

包体积优化是优化利用性能的重要一环。包体积的大小间接影响利用的加载工夫和用户体验。

当看到 1.3M 的 gzip 包大小后,咱们第一反馈就是去开启 webpack 的 analyse 查看包体积散布,后果齐全超出设想(这是 development 模式,正文了其余页面入口,仅保留了时段菜单一个页面):

下面这张图也很直观的暴露出几个问题:

  • 同一个 chunk 同一个依赖被屡次打入(以图中的 cook-design 为首,见下图)
  • 包的大小散布极不平均
  • 不同 chunk 打入同一版本依赖(懒加载策略造成)

我的项目依赖治理,避免多版本

在我的项目依赖治理中,应该尽可能防止多版本的依赖关系。多版本的依赖关系会导致包体积变大,甚至会产生抵触和谬误。在日常业务组件开发中,对根底组件(比方 antd)的依赖,能够设置为 peerDependencies。

咱们的解决思路是通过标准业务的依赖引入形式 和 通过 resolution 强制指定版本。

组件库反对 treeShaking

在应用第三方组件库时,通过 treeShaking,能够只加载利用中所需的组件和函数,缩小包体积和加载工夫。以往咱们引入 antd3 时,为了避免包体积过大,就会引入 babel-plugin-import 帮忙咱们去除无用代码。但 antd4 听从 es-module 标准,并配置了 sideEffect, 使得人造反对 treeShaking。

咱们的我的项目大量依赖了本地生存的 cook-design 与 cook-design/icons,这两个因为短少 treeShaking 配置,导致组件被残缺打了进来,其冗余组件与冗余组件带来的依赖,体积在 5M 左右。

所以咱们在和相干的维护者交换了相干想法后,其批准加配置降级反对 treeShaking,咱们团队本人的双端组件库 cook-design-mixin 也反对了这个配置。

在优化利用架构、优化依赖的版本、组件反对 treeshaking、以及采纳分包策略后,咱们的构建后果(production 模式)长上面这样:

去除无用代码

将利用中的无用代码去除是包体积优化的重要伎俩之一,我在文章结尾提到,咱们这个我的项目是一个双端架构的我的项目, 它是一个编译时计划,这就是意味着 pc 端和挪动端投放是两套不同的资源。但因为咱们是在一个利用中开发,所以 pc 端的代码和挪动端的代码是混着写的,咱们通过标准和构建插件来解决代码混写的问题。

// 上面是一个示例
import {Decorator} from '@alife/wa-mixin-core';
import DMobile from './wa-mobile';
import DDesktop from './wa-desktop';

export default (props: {
  isShowTipStatus: boolean;
  showMode?: boolean;
}) => {
  return Decorator({Mobile: <DMobile {...props} />,
    Desktop: <DDesktop />,
  });
};

但通过代码剖析,咱们发现上面两个问题:

  • 双端组件库晚期编写的组件存在大量的编写不标准,导致构建插件无奈 shaking 掉另一端的代码,从而导致挪动端打入了 pc 端的代码(涉及面太广,后续做专项优化)
  • 业务代码因为是存量业务 (这里指菜品下发) 转双端(后期 pc 端代码已开发上线,挪动端采纳双端计划开发),所以导出的不标准,导致包体积剧增

当咱们把菜品下发入口退出时,构建后果长上面这样,比下面单入口的减少 2.3M(压缩后的):

而只留下发一个入口,构建后果长上面这样:

上面页面的引入,导致大量的 cook-design 与 cook-design/icons 被引入,以致于我过后在思考要不要为 icon 独自拆一个包或者通过 cdn 引入。

包入口被治理后,构建包大小显著达到了改善:

gzip 之后,大小根本在 1M 以类(还有改善的空间):

三、网络申请优化

网络申请优化是优化利用性能的另一个重要环节。在进行网络申请优化时,能够思考以下几个方面:

利用 combo 升高申请数量

在前端利用中,通常须要加载多个 JS、CSS、图片等资源文件,这会产生大量的网络申请,影响利用性能。能够应用 combo 技术,将多个文件合并成一个文件申请,缩小网络申请的数量, 不过这也须要服务器的反对。咱们的利用模版将 react、moment、babel-polyfill 等应用 cdn 作为内部依赖引入,但为了缩小申请数,应用了 combo 服务。

利用 http2 的多路复用提供申请效率

http2 反对多路复用,能够在一个连贯上同时传输多个申请和响应,进步申请效率和传输速度。因而,在应用 http2 协定时,能够利用多路复用优化网络申请。所以才有了下面分多个包的策略,为了能最大化利用古代网络的带宽。

期待队列优化

在分包依赖实现后,咱们发现 js 资源包的加载存在显著的期待状况(如上图),而且是稳固复现的,通过剖析,咱们发现脚手架提供的利用 html 模版,存在同步 script 引入 vconsole, 从而阻塞了 js 资源的下载。

缩小 DNS 解析 与 TCP 的握手工夫

在排查期待队列问题时,咱们还发现,html 模版中利用局部内部依赖应用了非团体的 cdn 域名问题。在 http1 时代,这个做法是被提倡的,因为浏览器对单个域名同时的 http 连贯有限度,所以为了减少并行申请数,在同一个网页中,会采纳几个 cdn 域名。但 http2,这个就成了解放,而且采纳内部 cdn,会带来平安危险。

在下面的策略全副施行后,日常环境,利用首屏稳固在 1.5s 左右。待双端组件库按标准调整后,这个数据能再快 10%。

开启 cdn 减速

什么是 cdn,置信大家都应该很理解了。在咱们利用上线后,动态资源终于失去了 cdn 魔法的加持。页面在咱们的投放 app 掌客端也顺利实现了秒开,体验极好:

总结

首屏优化是前端经久不衰的话题,其伎俩丰盛、细节繁多。利用架构优化、包体积优化和网络申请优化是优化前端利用性能和进步用户体验的关键所在。

本文由 ChatGPT 拟初稿,打工人加工而成。

正文完
 0