前端性能优化

 页面的性能指标

  • DCL(DOMContentLoaded),DOM解析完毕。
  • FP(First Paint),表示渲染出第一个像素点。FP一般在HTML解析完成或者解析一部分时候触发。
  • FCP(First Contentful Paint),表示渲染出第一个内容,这里的“内容”可以是文本、图片、canvas。
  • FMP(First Meaningful Paint),首次渲染有意义的内容的时间,“有意义”没有一个标准的定义,FMP的计算方法也很复杂。
  • LCP(largest contentful Paint),最大内容渲染时间。

白屏时间(FP) = 地址栏输入网址后回车 - 浏览器出现第一个元素

首屏时间(FCP) = 地址栏输入网址后回车 - 浏览器第一屏渲染完成

如何了解当前页面的性能状况

  • 通过Chrome浏览器的Lighthouse和performance功能面板查看资源数据 【performance面板的操作流程
  • 引入Google Chrome官方的 web-vitals 包进行数据搜集
const reportWebVitals = onPerfEntry => {
  if (onPerfEntry && onPerfEntry instanceof Function) {
    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
      getCLS(onPerfEntry);
      getFID(onPerfEntry);
      getFCP(onPerfEntry);
      getLCP(onPerfEntry);
      getTTFB(onPerfEntry);
    });
  }
};
export default reportWebVitals;

  • 为了更准确的收集性能数据,可以通过performance API获取到响应的指标值。

白屏

一般是认为DOM Tree构建时,解析到的时候,我们认为是白屏结束的时间点。
我们可以在这个时候使用performace.mark进行打点标记,最后可以通过performance的
entry.startTime来获取白屏时间,其中entry.startTime是相对于performance.timing.navigationStart的时间。

<head>
...
<script>
    // 通常在head标签尾部时,打个标记,这个通常会视为白屏时间
    performance.mark("first paint time");
</script>
</head>
<body>
...
<script>
    // get the first paint time
    const fp = Math.ceil(performance.getEntriesByName('first paint time')[0].startTime);
</script>
</body>

首屏

一般是首屏中的图片加载完毕的时候,我们认为是首屏结束的时间点。我们可以对首屏中的image做onload事件绑定,
performace.mark进行打点标记,不过打点前先进行performance.clearMarks清除操作,以获取到多张图片最后加载完毕的时间。

<body>
<div class="app-container">
    <img src="a.png" onload="heroImageLoaded()">
    <img src="b.png" onload="heroImageLoaded()">
    <img src="c.png" onload="heroImageLoaded()">
</div>
<script>
    // 根据首屏中的核心元素确定首屏时间
    performance.clearMarks("hero img displayed");
    performance.mark("hero img displayed");
    function heroImageLoaded() {
        performance.clearMarks("hero img displayed");
        performance.mark("hero img displayed");
    }
</script>
...
...
<script>
    // get the first screen loaded time
    const fmp = Math.ceil(performance.getEntriesByName('hero img displayed')[0].startTime);
</script>
</body>

此外,Google也提供了一些新的API——PerformanceObserver ,来获取相应的指标值。

首次绘制 (FP)/首次内容绘制 (FCP)

PerformanceObserver 为我们提供的新功能是,能够在性能事件发生时订阅这些事件,并以异步方式响应事件。

let perfomanceMetrics = {};
const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        // `entry` is a PerformanceEntry instance.
        // `name` will be either 'first-paint' or 'first-contentful-paint'.
        const metricName = entry.name;
        const time = Math.round(entry.startTime + entry.duration);
        if (metricName === 'first-paint') {
            perfomanceMetrics.fp = time;
        }
        if (metricName === 'first-contentful-paint') {
            perfomanceMetrics.fcp = time;
        }
    }
});

页面的性能优化 

渲染层面

  • 优化文件资源的异步加载及处理顺序,不要阻塞页面的渲染
  • 通过服务端渲染同构直出

        (路由同构,数据同构,渲染同构)

          省去了客户端二次请求数据的网络传输开销,服务端的网络环境要优于客户端,内部服务器之间通信路径也更短。首屏加载时间(FCP)更快,同时也有更好的 seo。

缓存层面

  • 离线数据可以缓存到localStorage
  • webpack配置chunkhash/contenthash实现资源依赖长期缓存(强缓存/协商缓存)

chunkhash根据两个chunk自身的内容,通过某种算法来生成各自的hash,不会相互影响。

contenthash的意思是hash的生成,是基于自身内容来创建的。css chunk和app chunk的hash因为是基于各自内容的生成的,现在他们hash是不一样的。修改任何一方都不会影响另外一方。

webpack4配置实现浏览器长期缓存 - 知乎

请求层面

  • 降低请求资源大小

        (1)gzip可以有效压缩文件资源的体积

        (2)雪碧图合并图片资源

        (3)对于图片的处理,可以按支持情况使用webp/avif格式,且进行图片懒加载

        (4)webpack打包时利用插件优化资源大小

                        url-loader(将小图片转成base64打包进 html 中,减小图片数量);

                        terser-webpack-plugin、uglifyjs-webpack-plugin(压缩 js 文件);

                        webpack SplitChunksPlugin (更合理的拆包策略)【查看更多

  • 加快请求速度

        (1)升级HTTP2.0,利用多路复用让请求可以并行

        (2)图片等静态资源上传到CDN服务【CDN加速原理

        (3)配置DNS预解析【DNS预解析详解

                        ①用meta信息来告知浏览器, 当前页面要做DNS预解析 <meta http-equiv="x-dns-prefetch-control" content="on">

                        ②在页面header中使用link标签来强制对DNS预解析: <link rel="dns-prefetch" href="//www.zhix.net">

 

内嵌的webview网页优化

  • 离线压缩包

                服务端渲染直出html后仍然需要加载一个html文件,离线包基本思路通过通过webview统一拦截url, 将资源映射到本地离线包【事先打包好的文件资源】, 更新的时候对版本资源检测, 下载和维护本地缓存目录中的资源

  • 预加载webView
  • webView复用

打包构建的性能优化

  1. 使用 webpack-bundle-analyzer 查看打包出来文件的体积大小,看看是哪个包太大了。
  2. 在排除了包大小的问题之后,再使用 speed-measure-webpack-plugin 插件来查询是哪个插件或者是 loader 整慢了。
  3. 发现有些插件的运行确实慢了,但是我们也没精力去改人家的代码,所以还是牺牲自己电脑的内存吧,比较常见的方案就是使用 happypack / thread-loader来进行多进程构建。(原理类似,每次 webpack 解析一个模块,happypack thread- loader 会将它及它的依赖分配给 worker 线程中,从而达到多进程打包的目的。)
  4. 生产环境开启 tree shaking 去掉没有引用的代码。
  5. 引入 dllplugin+dllReferencePlugin 动态链接库方案,将第三方库单独打包,再链入我们的webpack项目中。(对于现代化前端,我们总是会应用各种库,这些库我们并不会频繁去变动他们,为了避免每次都是构建这些不常变动的代码,可以把这些代码抽离出来,webpack中,我们可以结合DllPlugin 和 DllReferencePlugin插件来实现,在实操中还是用 polyfill 来进行引入对应库的静态资源,连打包都省掉了,只用使用 externals 来引入这些我们埋在 html 的 js 资源。)
  6. 其实在构建过程主要是 js 的编译这块可能会占用很多的时间来构建,所以 babel-loader 的 cache 属性来配置缓存或者直接使用 cache-loader 来进行缓存来提升二次构建速度。
  7. 通过 rule 的 include 属性来缩小构建目标,resolve 的具体配置来减少文件搜索范围。

其他体验优化

参考文章

离线包方案

APP 内嵌 h5 性能优化

前端优化之DNS预解析

前端性能检测工具 --- Web Vitals

Web前端最新性能优化

前端页面性能指标与采集方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值