前端性能优化:常用方法
本文首发于 前端性能优化:常用方法
方法一:压缩打包体积(开启 GZIP)
-
安装插件
npm i compression-webpack-plugin -D
-
在 Webpack 中引入插件
// webpack.config.js const CompressionPlugin = require('compression-webpack-plugin') module.exports = { plugins: [ new CompressionPlugin({ algorithm: 'gzip', }), ], }
-
服务器配置
-
以 nginx 为例:
server { gzip on; gzip_static on; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_proxied any; gzip_vary on; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; }
-
以 nodejs 为例:
npm i compression
const compression = require('compression') app.use(compression())
-
方法二:压缩代码
-
安装插件
npm i uglifyjs-webpack-plugin -D
-
在 Webpack 中引入
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') module.exports = { mode: 'production', plugins: [ new UglifyJsPlugin({ uglifyOptions: { compress: { drop_console: true, // 压缩时删除 `console` 语句 drop_debugger: true, // 压缩时删除 `debugger` 语句 }, }, }), ], }
方法三:压缩图片
-
安装 loader
npm i image-webpack-loader -D
-
在 webpack.config.js 中配置 loader
module.exports = { module: { rules: [ { test: /\.(gif|png|jpe?g|svg)$/i, use: ['file-loader', 'image-webpack-loader'], }, ], }, }
方法四:减少 HTTP 请求
大量的 HTTP 请求会给服务器造成一定压力,导致服务器响应时间增加,从而造成页面加载时间过长。因此,减少 HTTP 请求是非常重要的。
减少 HTTP 请求可以从以下几个方面入手:
-
使用 CDN
服务器的位置是固定的,负载也是有限的。通常访客区域距离服务器越远,打开网站速度越慢。如果在高峰时间段,网站访问量很大,服务器无法负载,也会导致访问速度下降。
因此,我们可以将我们的资源放到 CDN 上,这样就可以减少对服务器的 HTTP 请求。从而提高页面加载速度。
-
图片使用懒加载
如果一个页面上图片过多,全部加载就会相应发起很多请求,但是此时可视区域以外的图片即使已经加载,用户也无法看到,所以这其中就有很多不必要的请求。因此可以使用懒加载的方式,也就是只加载当前窗口可见的图片。
具体可以使用
Element.getBoundingClientRect()
方法,该方法会返回元素的大小及其相对于视口的位置。然后判断图片是否出现在页面上。 -
尽量使用 CSS3 代替图片
可以利用 CSS3 代替一些简单的图片,这样就可以减少一些图片请求,提高页面加载速度。
方法五:使用 HTTP 2.0
我们目前使用的 HTTP 1.1 的 Headers 采用的是文本格式,每一个请求都会带上一些完全相同的数据,而且没有进行压缩,而 HTTP 2.0 采用的是二进制编码,并且对 Headers 进行了 HPack 压缩,进而提升了传输效率。
关于 HTTP 版本之间的区别,可以参考 前端基础:HTTP。
方法六:减少重绘(Repaint)和重排(Reflow)
重绘和重排都会导致页面或部分页面重新渲染,所以我们应当尽量避免触发这两个浏览器事件。
重绘(Repaint) 就是浏览器使用新的样式重新渲染一个元素。改变元素的风格通常会触发重绘,比如:
-
background
-
border
-
border-radius
-
box-shadow
-
color
-
visibility
-
outline
如果需要改变元素的某些 CSS 属性,尽量一次性改变,减少触发重绘的次数。
重排(Reflow) 就是浏览器重新渲染部分或全部页面,通常是当元素的尺寸发生改变或者浏览器的一些行为影响到页面布局而触发的,比如
-
clientWidth
、clientHeight
等窗口属性改变 -
box-sizing
、width
、height
、border
、padding
等元素尺寸改变 -
font-size
、line-height
等元素字体大小改变 -
margin
、float
、flex-direction
等元素位置改变
如果需要改变元素位置或尺寸,可以使用以下属性避免重排:
-
position: fixed | absolute
使元素脱离文档流。 -
transform
属性不会触发避免重排。
方法七:使用节流防抖
在用户浏览网页或者在网页上进行一些操作时,我们常常需要监听一些事件去完成相应的功能。比如鼠标点击、键盘输入、滚轮滚动等一些其它事件。
在处理这些事件时,我们常常会发现,如果一个事件发生的频率过高,相应的代码执行的频率也会越高。
所以,我们并不需要代码如此高频率的执行,这在一定程度上对系统资源造成了浪费,程序的性能也会因此变得很差。因此,我们需要使用节流防抖,对代码的执行频率进行一些限制。
/**
* @description 节流函数
* @param {Function} func 需要节流的函数
* @param {Number} wait 节流的时间
* @returns {Function} 返回节流后的函数
*/
function throttle(func, wait) {
let timer = null
return function () {
if (timer) return
timer = setTimeout(() => {
func.apply(this, arguments)
timer = null
}, wait)
}
}
/**
* @description 防抖函数
* @param {Function} func 需要防抖的函数
* @param {Number} wait 防抖的时间
* @returns {Function} 返回防抖后的函数
*/
function debounce(func, wait) {
let timeout
return function () {
timeout && clearTimeout(timeout)
timeout = setTimeout(() => {
func.apply(this, arguments)
}, wait)
}
}
// 节流
input.addEventListener('input', throttle(printInputText, 500))
// 防抖
input.addEventListener('input', debounce(printInputText, 500))
更多有关节流防抖的使用,可以参考 前端性能优化:手写实现节流防抖
方法八:使用服务端渲染(SSR)
使用服务端渲染有以下优点:
-
首屏加载快。
-
利于 SEO。
有关 SSR 的更多介绍,可以参考 五分钟了解 SPA 与 SSR
参考资料: