对于浏览器来说,加载网页的过程可以分为两部分,下载文档并响应(5%左右),下载各种组件(95%左右)。
而对比大部分优秀网页来说下载文档(10%~ 20%),下载组件(80%~90%)。
优化就是要减少下载组件这部分。
1.压缩HTTP
对于请求,试着想一想,传输一个文件夹轻松还是一个压缩包轻松,毫无疑问当然是压缩包,对于请求,我们同样也是如此,我们可以压缩请求,减少网络传输的数据量,这样就会减少请求的时间,提高用户体验。
HTTP压缩,浏览器可以使用Accept-Encoding头来声明压缩,而服务端可以使用content-Encoding 来确认压缩。
//简单使用vue的请求来演示accept-Encoding
const axios = require('axios');
axios.get('/', {
baseURL: window.location.origin,
headers: {
'Accept-Encoding': 'gzip, deflate'//压缩方式
}
})
.then(response => {
const acceptEncoding = response.headers['accept-encoding'];
console.log(acceptEncoding);
})
.catch(error => {
console.error(error);
});
//用java来表示context-Ecoding
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class HTTPServer {
public static void main(String[] args) {
try {
// 创建服务器套接字
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
// 等待客户端连接
``````
// 创建输出流
``````
// 构建HTTP响应
``````
// 获取请求头中的Accept-Encoding字段的值
String acceptEncoding = clientSocket.getHeaderField("Accept-Encoding");
// 根据Accept-Encoding字段的值设置Content-Encoding字段的值
String contentEncoding;
if (acceptEncoding != null && acceptEncoding.contains("gzip")) {
response.append("Content-Encoding: gzip\r\n");
contentEncoding = "gzip";
// 添加使用gzip压缩的内容
// ...
} else {
response.append("Content-Encoding: identity\r\n");
contentEncoding = "identity";
// 添加未压缩的内容
// ...
}
// 输出响应内容
``````
// 关闭连接
``````
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
同时,web服务器通过gzip对response进行编码,当浏览器接收到response时,对其解码。
gzip压缩:压缩比率3~10倍,通常压缩静态文件。
2.减少HTTP请求
对于网站来说,大部分时间都花费在响应组件上面,而组件大部分都是图片或者其他文件,要优化的话,减少对这部分的请求是一个好方法。
2.1图片地图
图片地图就是允许在一个图片上关联多个URL,目标URL的取决于用户点击的位置。而图片地图有两种,服务端图片地图和客户端图片地图。
服务端图片地图就是将所有的点击提交到同一个目标URL中,然后向其传递用户点击的x,y坐标。然后进行操作,这种方式可能很少使用,而经常使用的是客户端图片地图,它可以将用户的点击映射成一个操作,无需向后端应用程序发送请求。映射可以通过HTML的map标签实现,或者使用绝对定位和相对定位实现。
<img usemap="#map1" src="xxx">
<map name="map1">
<!--shape是区域形状,但好像只有矩形;coords是坐标 -->
<area shape="rect" coords="0,0,31,31" href="xxxx.html" title="xxx">
<area shape="rect" coords="0,0,90,30" href="xxxx.html" title="xxx">
``````
</map>
2.2内联图片
这种图片可以不用向后端发送请求,可以减少HTTP请求,它通过data:URL实现,它将图片作为一种内嵌资源。
<img src="data:image/png;base64,base64码">
<style>
.home{
//其中png可以更换成其他不同类型,最后的是图片转换成base64的编码。
background-image:url(data:image/png;base64,base64码)
}
</style>
2.3合并脚本和样式表
对于一个前端项目,肯定会有许多的js和css,而我们是否对这些进行内联(嵌在html页面),或者还是放在外部文件中,而外部文件确实可以提高性能,但是太多了会造成,请求的过多。一个js文件就会发送一次请求。根据一些大型网站来说,平均6~ 7个脚本和1~ 2css表,也就是说可以将多个脚本文件合并到一个文件中,多个样式表合成一个文件。
1.手动合并:将所有的脚本和样式表文件的内容复制到一个新的文件中,并确保按照原来的顺序进行合并。这种方法适用于项目规模较小或需要手动维护的情况。
2.构建工具:使用构建工具(如Webpack、Grunt、Gulp等)来自动化合并脚本和样式表文件。这些构建工具通常提供了合并、压缩和优化代码的功能,可以根据配置文件和规则进行合并操作。你可以定义合并文件的顺序,并设置其他的编译和转换规则。
3.服务器端合并:在服务器上使用服务器端脚本(如PHP、Node.js等)将多个脚本和样式表文件合并成一个文件,并将合并后的文件返回给客户端。这种方法可以减少HTTP请求的数量,提高页面加载性能。你可以通过编写服务器端代码,将需要合并的脚本和样式表文件动态地合并在一起。
2.使用内容发布网络
内容发布网络(CDN):是一组分布在多个不同地理位置的web服务器。用户找最近的位置web服务器或者网络延迟最低的服务器发送请求。
1.优点:
提高网站性能:CDN将内容缓存在全球各地的边缘服务器上,并将内容部署到离用户最近的服务器上。这可以大大减少用户访问网站时的延迟,提高加载速度和性能。
提供可扩展性:CDN使用多个服务器节点分担请求负载,提供更好的可扩展性和更高的容量,使网站能够更好地处理大量的并发请求。
减少网络拥塞:通过将内容缓存在离用户更近的位置,CDN可以减少互联网主干网络上的流量,减轻网络拥塞,并提高整体网络性能。
提供高可用性和容错能力:CDN会自动将内容从一个服务器节点复制到另一个节点,以提供高可用性和容错能力。如果一个服务器节点不可用,CDN会自动将请求路由到其他可用节点。
降低成本:通过使用CDN,网站可以减少自己的服务器和网络带宽需求,从而降低成本。
2.缺点:
成本:使用CDN服务会增加额外的成本,特别是对于小型或低流量的网站来说,可能超出其预算。CDN的具体价格因服务提供商和使用情况而异。
数据一致性:由于CDN的分布式性质,内容更新可能需要一些时间才能在全球所有节点上生效,这可能导致数据的一致性问题。对于需要实时更新和同步的应用程序来说,这可能是一个挑战。
安全性:CDN可以缓存和传输网站的内容,但这也意味着它需要访问和处理网站的数据。因此,确保CDN提供商有适当的安全措施来保护数据安全和隐私是重要的。
控制性:使用CDN服务可能会带来一定的控制权妥协。网站可能无法完全控制缓存策略、内容更新和数据传输方面的细节,因此需要仔细考虑使用CDN时的控制权和灵活性。
3.添加Expries头
浏览器(和代理)使用缓存来减少HTTP请求的数量,并减少HTTP响应的大小。web服务器使用Expries头来告诉web客户端它可以使用一个组件的当前副本直到指定的时间为止,在HTTP响应中发送。,就算说页面的图片返回这个头,浏览器就在之后就会使用缓存的这张图片而不发送请求了。
还有一种更加方便的头,Cache-control,它可以解决Expries头需要指定一个确切的日期,这样很不方便。而Cache-control可以使用max-age指令去指定组件缓存多久。秒为单位。
//但是不支持HTTP1.1的浏览器,那就同时使用就行了
Cache-Control:max-age=2222222222
//这个请求和响应都可以使用
在符合缓存策略时,服务器不会发送新的资源,但不代表客户端与服务端的会话中断。