懒加载表示用户请求什么再显示什么,如果一个请求要响应的时间非常长,就不推荐懒加载 。
Flush机制当一个页面非常大,内容非常多,可以采用flush的形式分部分返回给页面,这样能告诉用户我正在工作,显示一部分内容比白屏等很长时间要好得多 。在Java Web技术中,实现Flush非常简单,只要调用 HttpServletResponse.getWriter输出流的flush方法,就可以将已经完成加载的内容写回给客户端 。
这种方式只适用于返回数据特别多、请求时间特别长的情况,常规数据还是用正常的实时全部返回最佳 。这种实现方式实际会增加浏览器渲染时间和用户整体等待时间,但从用户体验上会更加优秀 。
性能之服务器优化CDN机制所谓的CDN,就是一种内容分发网络,它采用智能路由和流量管理技术,及时发现能够给访问者提供最快响应的加速节点,并将访问者的请求导向到该加速节点,由该加速节点提供内容服务 。
通俗点说,你在成都(浏览器)购买了北京卖家(服务器)的产品,北京卖家通过快递(CDN服务)寄送包裹,从北京到成都可以走路、坐汽车、火车或飞机,而采用CND的快递会选择飞机直达,因为这种寄送方式最快 。
当然使用CDN有两个注意事项:
- CDN加速服务很贵,如果你觉得你的网站值得加速,可以选择购买;
- CDN不适合局域性网站,比如你的网站只有某一个片区访问或者局域网访问,因为区域性网络本来就很近,无需CDN加速 。
动静分离所谓的动静分离,就是将Web应用程序中静态和动态的内容分别放在不同的Web服务器上,有针对性的处理动态和静态内容,从而达到性能的提升 。我们知道如果一个HTML有多个域名请求数据文件会提高
Tomcat服务器在处理静态和并发问题上比较弱,所以事先动静分离的方式一般会用Apache+Tomcat、Nginx+Tomcat等 。
以Apache+Tomcat为例,其运行机理是:页面请求首先给Apache,然后Apache分析请求信息是静态还是动态,静态则本机处理,动态则交给Tomcat做处理 。
这其实是负载均衡的雏形,这样的实现不用让开发人员做任何特殊开发,一个
交给服务器即可,至于这个文件是从Apache还是从Tomcat取得,开发人员完全无需关注 。
HTTP持久连接持久连接(Keep-Alive)也叫做长连接,它是一种TCP的连接方式,连接会被浏览器和服务器所缓存,在下次连接同一服务器时,缓存的连接被重新使用 。HTTP无状态性表示了它不属于长连接,但HTTP/1.1提供了对长连接的支持(不过这必须依赖浏览器和服务器双方均支持长连接功能才行),最常见的HTTP长连接例子是“断点下载” 。
浏览器在请求的头部添加 Connection:Keep-Alive,以此告诉服务器“我支持长连接,你支持的话就和我建立长连接吧”,而倘若服务器的确支持长连接,那么就在响应头部添加“Connection:Keep-Alive”,从而告诉浏览器“我的确也支持,那我们建立长连接吧” 。服务器还可以通过Keep-Alive:timeout=..., max=...的头部告诉浏览器长连接失效时间 。
配置长连接通常是要服务器支持设置,有测试数据显示,使用长连接和不使用长连接的性能对比,对于Tomcat配置的maxKeepAliveRequests为50来说,效率竟然提升了将近5倍 。
GZIP压缩技术HTTP协议支持GZIP的压缩格式,当服务器返回的HTML信息报头中包含Content-Encoding:gzip,它就告诉浏览器,这个响应的返回数据已经压缩成GZIP格式,浏览器获得数据后要进行解压缩操作,一定程度上减轻了服务器传输数据的压力 。
很多服务器已经支持通过配置来自动将HTML信息压缩成GZIP,比如tomcat、又比如很火的Nginx 。如果无法配置服务器级别的GZIP压缩机制,可以改为程序压缩 。
// 监视对 gzipCategory 文件夹的请求 @WebFilter(urlPatterns = { "/gzipCategory/*" })public class GZIPFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {String parameter = request.getParameter("gzip");// 判断是否包含了 Accept-Encoding 请求头部 HttpServletRequest s = (HttpServletRequest)request;String header = s.getHeader("Accept-Encoding");//"1".equals(parameter) 只是为了控制,如果传入 gzip=1,才执行压缩,目的是测试用 if ("1".equals(parameter) && header != null && header.toLowerCase().contains("gzip")) {HttpServletResponse resp = (HttpServletResponse) response;final ByteArrayOutputStream buffer = new ByteArrayOutputStream();HttpServletResponseWrApper hsrw = new HttpServletResponseWrapper(resp) {@Overridepublic PrintWriter getWriter() throws IOException {return new PrintWriter(new OutputStreamWriter(buffer,getCharacterEncoding()));}@Overridepublic ServletOutputStream getOutputStream() throws IOException {return new ServletOutputStream() {@Overridepublic void write(int b) throws IOException {buffer.write(b);}};}};chain.doFilter(request, hsrw);byte[] gzipData = https://www.isolves.com/it/cxkf/yy/html5/2019-08-09/gzip(buffer.toByteArray());resp.addHeader("Content-Encoding", "gzip");resp.setContentLength(gzipData.length);ServletOutputStream output = response.getOutputStream();output.write(gzipData);output.flush();} else {chain.doFilter(request, response);}}// 用 GZIP 压缩字节数组 private byte[] gzip(byte[] data) {ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240);GZIPOutputStream output = null;try {output = new GZIPOutputStream(byteOutput);output.write(data);} catch (IOException e) {} finally {try {output.close();} catch (IOException e) {}}return byteOutput.toByteArray();} …… }
推荐阅读
- 网站内链的表达形式
- 吕布被张飞骂作三姓家奴说他三姓是因为什么
- 喝茶为什么会出现酸甜苦涩
- 淘宝降权订单删除会怎么样 淘宝单为什么会降权
- 李靖为什么封神了 李靖封神榜中为什么没有
- 人死后身体为什么不能触碰? 为什么不能摸死人的手
- 吸血树真的存在吗 吸血树为什么会吸血
- 人为什么会得病?早一天看到,多一份健康
- 为什么饮茶能够养生明目
- 喝海水为什么会脱水 脱水为什么不能喝海水
