前端性能优化实战
关注“前端学苑” ,坚持每天进步一点点
「~前端性能优化~」
对于前端的性能话题,从来都没有断绝过。因为这个东西没有最好,只有更好。而且往往也是业务的繁杂程度去决定优化程度的。作为一个前端开发者,性能是我们关注的指标。它直接影响着我们的用户,同时也影响着产品本身。
作为一个优秀的前端开发人员,性能优化是必备技能。本篇对于常用的优化方式进行总结。
简短的概括:
1、图片优化篇
2、合理利用缓存
3、webpack优化
4、优化网络链接
5、体验优化
正文从这里开始~~~
一、图片优化篇
1)webp图片优化
WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都相当优秀、稳定和统一。无损webp相比png减少26%大小。
比如有这么一张图片用于学生的头像 https://img.zuoyebang.cc/zyb_d5302679abe24c3a8aa1a11e8862fd5b.jpg 我们不进行任何操作的时候,这张图片的大小是46kb
但是如果使用在这个地址后加上表示将其转换为webp(我们使用的是百度云) https://img.zuoyebang.cc/zyb_d5302679abe24c3a8aa1a11e8862fd5b.jpg@f_webp 这里表示将这张图片转换为webp格式,然后在看图片大小:
从46kb减少到了31kb,减少了32%。使用这项技术能够大大的提高页面的加载速度,为公司节省带宽。在相关业务上,可能需要其他的手段,例如头像是不需要这个高的的图片质量的,后端返回的图片可能是400*400的,但是头像可能只需要100*100,例如上面给出的这个地址可以转换为: https://img.zuoyebang.cc/zyb_d5302679abe24c3a8aa1a11e8862fd5b.jpg@f_webp,q_75,w_100
q: 代表图片质量
w: 表示图片最大宽度
可以图片从46kb降到了2kb,图片大小得到了惊人的改善,并且不会产生肉眼可见的视觉影响,所以使用webp是非常有必要的。
WebP兼容性
WebP优势
下面我们以一张图片为例,分别用不同质量进行压缩。
2)延迟加载(懒加载)
进入页面的时候,只请求可视区域的图片资源,需要延迟加载 --- 也叫懒加载。
(1) 原生的实现方式
延迟加载的方式大概可以总结成以下几点:
1)设置图片 src 属性为同一张图片(一般放置加载图片,也就是所谓的菊花图),同时自定义一个 data-src 属性来存储图片的真实地址。
2)页面初始化显示的时候或者浏览器发生滚动的时候判断图片是否在视野中。
3)当图片在视野中时,通过 js 自动改变该区域的图片的 src 属性为 data-src 中的真实地址。
代码如下:
<img src="./src/assets/loading.svg" class="lazy" data-src="a.png">
<img src="./src/assets/loading.svg" class="lazy" data-src="b.png">
var imgs = document.querySelectorAll('img'); // 获取页面所有的 img 标签
// offsetTop 是元素与 offsetParent 的距离,循环获取直到页面顶部
function getTop(e) {
var T = e.offsetTop; // 距离上方的距离
while(e = e.offsetParent) { // 循环到父元素 div 的顶部
T += e.offsetTop;
}
return T;
}
// offsetTop - scrollTop < clientHeight 距离父元素顶部的高度 - 滑动距离高度(不可见) < 可视区域高度
// 实现懒加载
function lazyLoad(imgs) {
// 获取浏览器窗口可视区域高度,肉眼可见的那部分高度
var clientHeight = document.documentElement.clientHeight;
// 浏览器向上滚动的高度
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
for (let i = 0; i < imgs.length; i++) {
// 整个页面高度 + 向上滚动距离 > 取出来显示的图片的高度
if (clientHeight + scrollTop > getTop(imgs[i])) {
// 滑出了页面范围
imgs[i].src = imgs[i].getAttribute('data-src');
// 把图片的地址换成 data-src 中的真实地址
}
}
}
// 要加上 window.onload() --- 在页面首次加载完成的时候要先执行一次把一定的图片显示出来
window.onload = window.onscroll = function () {
// onscroll() 在滚动条滚动的时候触发
lazyLoad(imgs);
}
(2) vue的实现方式
<template>
<div id="app">
<div v-for="(img, index) in images" :key="index">
<img v-lazy="img">
</div>
</div>
</template>
在页面初始化后,只会加载页面视口内的图片,当我们滚动相应的位置才会加载对应的图片。
二、合理利用缓存
使用service worker
PWA全称Progressive Web App,即渐进式WEB应用。
PWA 主要功能:
1) web App Manifest 实现添加至主屏幕,
2) Service Worker 实现离线缓存, (主要功能)
3) push Notification 实现消息推送。
pwa中其他的功能感觉用不上,这里只介绍service worker。一般都有成熟的插件可以使用pwa,主要用它来缓存文件,如分析一个网站
在第一次访问的时候,需要下载整个文件大小约97kb,但是当我们第二次进入该文件的时候,这个chunk-vendor不需要重新下载,直接从缓存中获取
大大的提高了性能。
PWA项目实践:
vue cli 3.0中pwa使用了第三方库workbox,Web App 静态资源和请求结果的本地存储的解决方案。
workbox 是由谷歌浏览器团队发布,用来协助创建 PWA 应用的 JavaScript 库。
此时项目中关于PWA的文件如下:
1、package.json中引用了register-service-worker插件;
2、根目录下有registerServiceWorker.js;
3、public文件夹下有manifest.json,可以根据需要修改其中的内容。
三、webpack优化
1、打包公共代码
将公共的模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存到缓存中供后续使用,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。在webpack的splitChunks就能够把多次引入的包,都打包到一个文件中。这部分的的代码不会频繁更改,下次请求会从缓存中获取,而不是通过网络请求获取。注:CommonsChunkPlugin已经被移除了。
2、按需加载
1) 路由按需加载(使用import)。
const Home = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/home')
2)webpack提供的require.ensure()
vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。
{
path: '/home',
name: 'home',
component: r => require.ensure([], () => r(require('@/components/home')), 'demo')
}
四、优化网络链接
1、使用CDN
CDN即内容分发网络,它能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
2、使用DNS预解析
当浏览器访问一个域名的时候,需要解析一次DNS,获得对应域名的ip地址。
DNS Prefetch,即DNS预解析就是根据浏览器定义的规则,提前解析之后可能会用到的域名,使解析结果缓存到系统缓存中,缩短DNS解析时间,来提高网站的访问速度 ,方法是在head标签里面写上几个link标签
<link rel="dns-prefetch" href="yy-s.zuoyebang.cc">
<link rel="dns-prefetch" href="img.zuoyebang.cc">
3、preload/prefetch
preload主要目的都是为了提前加载浏览器之后需要的资源,一般用于加载css文件引用的字体。
prefetch的作用是告诉浏览器加载下一页面会用到的资源,这种方式的作用是加速下一个页面的加载速度。
4、defer/async
1) defer 是在HTML解析完之后才会执行,如果是多个,按照加载的顺序依次执行。
2) async是在加载完之后立即执行,如果是多个,执行顺序和加载顺序无关。(不保证按前后顺序执行)
五、体验优化
使用骨架屏
骨架屏可以理解为是当数据还未加载进来前,页面的一个空白版本,一个简单的关键渲染路径。
一些项目,可能大部分数据都是从后端获取,网络请求是需要占用一定的时间的,所以用户一进来发现是空页面,所以这个时候可以使用骨架屏先加载一个轮廓,而不是让用户觉得这个页面挂了。
可以看一下上面的示例图,第一个为骨架屏,第二个为菊花图,第三个为无优化,可以看到相比于传统的菊花图会在感官上觉得内容出现的流畅而不突兀,体验更加优良。
觉得本文对你有帮助?请分享给更多人
关注「前端学苑」加星标,提升前端技能