..
❝要说面试的时候问到最多的问题,那性能优化绝对是躲不开的话题,基本每个公司面试我都遇到了相关问题,其中,首页加载速度优化又是其中最常问的问题,网上的文章比较零零散散,没有一个总结到十分满意的,于是自己便来总结一下❞点击关注公众号,“技术干货...
A股板块轮动加剧,跨年大妖来袭,这几只票主力已明显介入!微信搜索关注【研讯小组】公众号(可长按复制),回复666,领取代码!
❝要说面试的时候问到最多的问题,那性能优化绝对是躲不开的话题,基本每个公司面试我都遇到了相关问题,其中,首页加载速度优化又是其中最常问的问题,网上的文章比较零零散散,没有一个总结到十分满意的,于是自己便来总结一下
❞
点击关注公众号,“技术干货”及时达!
这张图是我发现的比较宝藏,比较全面的一张首页加载优化图,便以此图来进行相关总结
一. 资源加载优化
压缩资源
启用Gzip压缩
使用缓存
使用内容分发网络 (CDN)
使用HTTP/2
优化DNS解析
减少HTTP请求数
预加载和预获取
使用更高效的图片格式
图片懒加载和路由懒加载
二. 页面渲染优化
优化CSS
使用CSS3动画代替JavaScript动画
将JavaScript放在页面底部
使用async和defer属性
减少和优化DOM操作
使用Virtual DOM
避免布局抖动
使用will-change提示浏览器优化
使用服务端渲染 (SSR)
延迟加载资源
通过 Webpack 配置,可以自动压缩 HTML、CSS 和 JavaScript 文件。
//webpack.config.js
constHtmlWebpackPlugin=require('html-webpack-plugin');
constMiniCssExtractPlugin=require('mini-css-extract-plugin');
constTerserPlugin=require('terser-webpack-plugin');
constCssMinimizerPlugin=require('css-minimizer-webpack-plugin');
module.exports={
mode:'production',
entry:'./src/index.js',
output:{
filename:'bundle.js',
path:__dirname+'/dist'
},
module:{
rules:[
{
test:/\.css$/,
use:[MiniCssExtractPlugin.loader,'css-loader']
}
]
},
optimization:{
minimize:true,
minimizer:[
newTerserPlugin(),
newCssMinimizerPlugin()
]
},
plugins:[
newHtmlWebpackPlugin({
template:'./src/index.html',
minify:{
collapseWhitespace:true,
removeComments:true,
removeRedundantAttributes:true,
useShortDoctype:true
}
}),
newMiniCssExtractPlugin({
filename:'styles.css'
})
]
};
通过 Webpack 配置,可以生成 Gzip 压缩文件。
//在请求时会带上该请求头,声明它支持的压缩算法
Accept-Encoding:gzip,deflate,br
//webpack.config.js
constCompressionPlugin=require('compression-webpack-plugin');
module.exports={
//其他配置...
plugins:[
newCompressionPlugin({
filename:'[path][base].gz',
algorithm:'gzip',
test:/\.(js|css|html|svg)$/,
threshold:10240,
minRatio:0.8
})
]
};
服务端通过配置协商缓存和强缓存,来实现请求的缓存,这里以强缓存为例
//设置强缓存
constexpress=require('express');
constpath=require('path');
constapp=express();
//强缓存中间件
app.use((req,res,next)=>{
constoptions={
maxAge:'1y',//缓存一年
immutable:true
};
//设置Cache-Control头
res.set('Cache-Control',`public,max-age=${options.maxAge},immutable`);
next();
});
//将静态文件托管到public目录
app.use(express.static(path.join(__dirname,'public'),{
maxAge:'1y'//缓存一年
}));
constPORT=process.env.PORT||3000;
app.listen(PORT,()=>{
console.log(`Serverisrunningonport${PORT}`);
});
通过 Webpack 配置,将静态资源路径指向 CDN。
output:{
filename:'[name].[contenthash].js',
path:__dirname+'/dist',
publicPath:'https://cdn.example.com/'//指向你的CDN地址
},
启用 HTTP/2 需要在服务器配置中完成,Webpack 本身不直接支持 HTTP/2 配置。
# Nginx 配置
server {
listen 443 ssl http2;
server_name example.com;
# SSL 配置
}
在 HTML 中添加 DNS 预获取。
<linkrel="dns-prefetch"href="//example.com">
通过 Webpack 配置,合并文件和使用图片精灵,同时我们可以将一些小图片转为base64格式(虽然会减少请求,但是转为base64资源体积会变大一点,所有不推荐进行大图片base64处理)
//webpack.config.js
constSpriteLoaderPlugin=require('svg-sprite-loader/plugin');
module.exports={
//其他配置...
module:{
rules:[
{
test:/\.svg$/,
use:['svg-sprite-loader']
}
]
},
plugins:[
newSpriteLoaderPlugin()
]
};
使用 Webpack 插件进行预加载和预获取。
//webpack.config.js
constPreloadWebpackPlugin=require('preload-webpack-plugin');
module.exports={
//其他配置...
plugins:[
newPreloadWebpackPlugin({
rel:'preload',
as:'script',
include:'allChunks'
})
]
};
通过 Webpack 配置,使用现代图片格式,如 WebP(但是得注意浏览器兼容性)。
//webpack.config.js
constImageMinimizerPlugin=require('image-minimizer-webpack-plugin');
module.exports={
//其他配置...
module:{
rules:[
{
test:/\.(jpe?g|png|gif|svg)$/i,
type:'asset',
use:[
{
loader:ImageMinimizerPlugin.loader,
options:{
minimizerOptions:{
plugins:[
['imagemin-webp',{quality:75}]
]
}
}
}
]
}
]
}
};
通过InterpObserver API和自定义指令来实现图片懒加载,路由懒加载即用vue的动态路由@import引入即可
exportdefault{
inserted(el){
constloadImage=()=>{
constimageElement=el.tagName==='IMG'?el:el.querySelector('img');
if(imageElement){
imageElement.src=imageElement.dataset.src;
imageElement.onload=()=>el.classList.add('loaded');
}
};
consthandleIntersect=(entries,observer)=>{
entries.forEach(entry=>{
if(entry.isIntersecting){
loadImage();
observer.unobserve(el);
}
});
};
constoptions={
root:null,
threshold:0.1
};
constobserver=newInterpObserver(handleIntersect,options);
observer.observe(el);
}
};
将 CSS 外链放在页面顶部,因为这样可以确保页面在加载时尽快应用样式,从而避免样式闪烁(FOUC,Flash of Unstyled Content)并提升用户体验。
html>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metaname="viewport"content="width=device-width,initial-scale=1.0">
<title>ExamplePagetitle>
<linkrel="stylesheet"href="styles/main.css">
<linkrel="stylesheet"href="styles/theme.css">
head>
html>
使用 CSS3 动画而不是 JavaScript 动画(原理:transform等css3属于是独立的图层,不会影响其他图层,而且使用GPU加速),以减少重排和重绘。
.box{
transition:transform0.5s,opacity0.5s;
}
.box:hover{
transform:translateX(100px);
opacity:0.5;
}
将 JavaScript 文件放在 标签的底部(现代浏览器支持async和defer后就不需要了)
<body>
<scriptsrc="bundle.js">script>
body>
使用 async
或 defer
属性加载外部 JavaScript 文件。
<scriptsrc="bundle.js"async>script>
<scriptsrc="bundle.js"defer>script>
减少不必要的 DOM 操作,合并多次操作为一次。
//Before
element.style.width='100px';
element.style.height='100px';
//After
element.style.cssText='width:100px;height:100px;';
使用虚拟 DOM 技术(如 React)减少直接操作 DOM 带来的开销。
//使用React示例
importReact,{useState}from'react';
functionApp(){
const[count,setCount]=useState(0);
return(
<div>
<p>{count}p>
<buttononClick={()=>setCount(count+1)}>Incrementbutton>
div>
);
}
在操作 DOM 和样式时,避免可能导致重排的操作,对样式进行统一处理
//Before
element.style.margin='10px';
element.style.padding='20px';
element.style.border='1pxsolid#000';
//After
element.style.cssText='margin:10px;padding:20px;border:1pxsolid#000;';
使用 will-change
属性可以提示浏览器即将发生的变化,使浏览器提前进行优化。
.box{
will-change:transform,opacity;
}
使用服务端渲染技术提前生成 HTML 内容,减少客户端渲染的负担。
//使用Next.js进行SSR示例
importReactfrom'react';
import{renderToString}from'react-dom/server';
importAppfrom'./App';
consthtml=renderToString(<App/>);
延迟加载图片和非关键 CSS、JavaScript 文件。
<imgsrc="image.jpg"loading="lazy"alt="Lazyloadedimage">
<script>
varlink=document.createElement('link');
link.rel='stylesheet';
link.href='non-critical-styles.css';
document.head.appendChild(link);
script>
点击关注公众号,“技术干货”及时达!
A股板块轮动加剧,跨年大妖来袭,这几只票主力已明显介入!微信搜索关注【研讯小组】公众号(可长按复制),回复666,领取代码!
本站内容转载请注明来源并提供链接,数据来自互联网,仅供参考。如发现侵权行为,请联系我们删除涉嫌侵权内容。
【封装axios】前端架构让你一次封装终身受益!!!(稀土掘金技术社区2024年11月07日文章)
axios中的那些天才代码!看完我实力大涨!(稀土掘金技术社区2024年10月07日文章)
前端部署后自动提醒用户更新(稀土掘金技术社区2024年11月09日文章)
用iframe必定遇到过这六种“坑”之一(以vue为示例)(稀土掘金技术社区2024年11月05日文章)
vue3+gasp实现【星之卡比输入框】(稀土掘金技术社区2024年10月23日文章)
flex 布局中更巧妙的布局方案!比 justify-content 和 align-items 好用多了!(稀土掘金技术社区2024年10月29日文章)
2024年了,前端人是时候给予页面一点 Hero Section 魔法了!!! (Three.js)(稀土掘金技术社区2024年10月05日文章)
发现一个程序员最强外设,助你高效开发早日摸鱼!(稀土掘金技术社区2024年09月24日文章)
源码视角,Vue3为什么推荐使用ref而不是reactive(稀土掘金技术社区2024年07月31日文章)
前端开发,vue3实现excel文件预览和打印(稀土掘金技术社区2024年08月05日文章)
版权投诉请发邮件到1191009458#qq.com(把#改成@),我们会尽快处理
Copyright©2023-2024众股360(www.zgu360.com).AllReserved|备案号:湘ICP备2023009521号-3
本站资源均收集整理于互联网,其著作权归原作者所有,如有侵犯你的版权,请来信告知,我们将及时下架删除相应资源
Copyright © 2024-2024 EYOUCMS. 易优CMS 版权所有 Powered by EyouCms