1. 问题
当大屏中的内容很多时,比如50个以上,整个页面呈现速度会慢很多,影响用户体验。
通过 chrome开发者工具可以看到,默认情况下,chrome仅开启6个请求线程,用于发起ajax请求。
2. 解决方案
改进的方式有:
(1)调整加载次序。让页面前面的内容先加载,后面的内容后加载。
(2)页面的框架先加载,组件内容再加载。如果页面的框架可以在1S内加载完毕,用户体验会好很多。
(3)突破chrome 6个线程的限制。
下面重点讲解如何突破chrome6个线程的限制。
3. 步骤
3.1. 原理
chrome对同一个域的并发请求数量限制为6。只要让请求处于不同域,就可以打破这个限制。
域由三个部分构成: 协议+主机名+端口,只要一个不同,域就不同。在下面的示例中,我们使用多个不同的端口。
3.2. 后端
文件:TestController .java。它定义了一个接口,这个接口的执行时间为1秒。
文件:TomcatConfig .java。它定义3个httpConnector,分别对应8080, 8081, 8082端口。
```java
import org.apache.catalina.connector.Connector;
import org.apache.coyote.AbstractProtocol;
import org.apache.coyote.ProtocolHandler;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TomcatConfig {
/**
* @return
*/
@Bean
public ServletWebServerFactory httpServerFactory() {
// http connector
Connector connector1 = createHttpConnector(8080);
Connector connector2 = createHttpConnector(8081);
Connector connector3 = createHttpConnector(8082);
// 注册额外的connector
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(connector1, connector2, connector3);
return tomcat;
}
/**
* 创建 http connector
*
* @return
*/
private Connector createHttpConnector(int port) {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setPort(port);
// 设置最大线程数
ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractProtocol) {
AbstractProtocol protocol = (AbstractProtocol) handler;
// 运行controller代码的线程的最大数量
protocol.setMaxThreads(200);
}
return connector;
}
}
3.3. 前端
文件 index.html。使用axios模拟60个并发请求。函数axiosSwitchHost会随机地切换host。代码仅用于演示,生产中请自行封装。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script>
var urls = ['http://127.0.0.1:8080',
'http://127.0.0.1:8081',
'http://127.0.0.1:8082'
];
/**
* 切换 host
*/
function axiosSwitchHost() {
var index = Math.floor((Math.random() * urls.length));
console.log(index)
axios.defaults.baseURL = urls[index];
}
// 要ctrl + f5强制刷新
// 可以看到,chrome总共开了大约3*6个线程来发起ajax请求
for (let i = 0; i < 60; i++) {
axiosSwitchHost()
axios.get("/test1").then(function (result) {
console.log(result.data)
});
}
</script>
</html>
3.4. 效果
如上图所示,可以看到,并发的线程数多了很多,大约为16个。增加httpConnector的数量,可以进一步提升并发的数量。