整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Servlet:http的14个响应报头、servl

Servlet:http的14个响应报头、servlet设置响应头方法及代码实战

. Http在浏览器端的14个响应头信息

(1)响应的简介

当一个web服务器响应一个http请求时,响应通常包括一个状态行、一些响应报头、一个空行和文档。一个典型的响应如下所示:

HTTP/1.1 200 OK

Content-Type: text/html

Header2: ...

...

HeaderN: ...

(Blank Line)

<!doctype ...>

<html>

<head>...</head>

<body>

...

</body>

</html>

(2)补充:

状态行包括:http版本、一个状态码和一个对应于状态码的短消息。

(3)下表总结了从web服务器端返回到浏览器的最有用的http1.1响应报头:

2. servlet设置http响应报头的方法:

下面的方法可用于servlet程序中设置http响应报头。这些方法通过HttpServletResponse对象可用。

3. servlet设置http header响应的代码实例

(1)在webtest工程下的com.web.test包下创建类ResponseInfo

补充:通过用 setIntHeader() 方法来设置 Refresh 头,达到自动刷新的目的。

(2)启动tomcat访问,访问链接如下:

http://localhost:8080/webtest/responseinfo

(3)效果如下

此头条号每天都会分享非常实用的技术文章和笔试题讲解,欢迎大家关注此头条号!

击上方 关注订阅黑码教主获取更多精彩内容

性能之前端篇

循环优化

在多重嵌套循环的程序上,如果能分出出多个独立循环也比嵌套在一个循环体内来的更有益。

优化循环的3种方式:减少每次迭代的开销、减少迭代的次数或者重新设计应用程序。

在测试的时候仅可能模拟真实环境:如低端机器和低速网络。

?

Ajax优化

对于连续页面之间的差别很小的应用而言,使用Ajax技术能带来显著的改善。

?

减少重绘

在HTML页面完成展现之后,动态改变页面元素或调整CSS样式都会引起浏览器重绘,性能的损耗直接取决于动态改变的范围:如果只是改变一个元素的颜色之类的信息则只会重绘该元素;而如果是增删节点或调整节点位置则会引起其兄弟节点也一并重绘。

减少重绘并不是说不要重绘,而是要注意重绘范围:

  1. 改动的DOM元素越深则影响越小,所以尽量深入节点改动;
  2. 对某些DOM样式有多重变动尽量合并到一起修改;

以改变一个<a>标签的背景色、宽度和颜色为例。

<a href="javascript:void(0);" id="example">传统的代码</a> 
<script> 
 var example=document.getElementById("example"); 
 example.ondblclick=function() { 
 example.style.backgroundColor="red"; 
 example.style.width="200px"; 
 example.style.color="white"; 
 } 
</script> 

以上会执行3次重绘,而通过CSS代替javascript多次执行则只进行一次重绘。

<style> 
 .dblClick { 
 width: 200px; 
 background: red; 
 color: white; 
 } 
</style> 
<a href="javascript:;" id="example">CSS优化的代码</a> 
<script> 
 var example=document.getElementById("example"); 
 example.ondblclick=function() { 
 example.className="dblClick"; 
 } 
</script>

避免脚本阻塞加载

当浏览器在解析常规的script标签时,它需要等待script下载完毕,再解析执行,而后续的HTML代码只能等待。CSS文件引入要放在头部,因为这是HTML渲染必备元素。

?

为了避免阻塞加载,应把脚本放到文档的末尾,而CSS是需要放在头部的!

<head>
<link rel="stylesheet" href="common.css">
......
<script src="example.js"></script>
</body>

避免节点深层级嵌套

深层级嵌套的节点在初始化构建时往往需要更多的内存占用,并且在遍历节点时也会更慢些,这与浏览器构建DOM文档的机制有关。浏览器会把整个HTML文档的结构存储为DOM“树”结构。当文档节点的嵌套层次越深,构建的DOM树层次也会越深。

如下代码,完全能够去掉

或其中一个标签。<div>
 <span>
 <label>嵌套</label>
 </span>
</div>

页面缓存

通常不设置缓存的情况下,每次刷新页面都会重新读取服务器的文件,而如果设置缓存之后,所有文件都可以从本地取得,这样明显极大提高了页面效率。

我们可以通过设置页面头的expires来定义页面过期时间,将过期时间定久一点就达到了“永久”缓存。

<meta http-equiv="expires" content="Sunday 26 October 2099 01:00 GMT" />

当然,如果你的项目代码有变更,因为客户端缓存了文件就得不到最新的文件,势必造成显示错误。基于这个问题的解决方案就是给链接文件加一个时间戳,如果时间戳有变化,浏览器会认为是新文件,就会向服务器请求最新文件。

<script src="example2014-6-17.js"></script>
//如果是JSP,可以用EL表达式来取时间戳信息,这样管理更加方便
<script src="example${your time param}.js"></script>
//或者这样的写法更优秀:
<script src="example.js?time=2014-6-7"></script>
<script src="example.js?time=${your time param}"></script>

压缩合并文件

所有涉及到请求数据的文件尽量做压缩,比如Javascript文件、css文件及图片文件,特别是图片文件,如果没有高清晰要求,完全可以压缩后再使用。

数量少体积大的文件要比数量多体积小的文件加载速度快,所以有时候可以考虑将多个js文件、多个css文件合并在一起。

除此之外减少HTML文档大小还可以采取下面几种方法:

  1. 删掉HTM文档对执行结果无影响的空格空行和注释
  2. 避免Table布局
  3. 使用HTML5 ### HTML+CSS3+Javascript各司其职 让三元素各司其职才能做出高性能的网页:HTML是页面之本也是内容之源,有了它就能跟CSS和Javascript交互;CSS3可以说是展现大师,而且日渐强大的CSS能代替Javascript做很多动态的事情如渐变、移动等动态效果;Javascript是动态数据之王,旧浏览器依靠js来完成动态效果展现,但现在的CSS也能完成js的工作,所以尽量将工作交给css,这样会获得更好的性能。(这个说得有点大)

图像合并实现CSS Sprites

图像合并其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS 的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置。

一个页面要用到多个图标,完全可以将多个图标合并成一个图,然后只需要发一次图片请求,通过css定位分割图标即可。

避免使用Iframe

使用iframe并不会增加同域名下的并行下载数,浏览器对同域名的连接总是共享浏览器级别的连接池,在页面加载过程中iframe元素还会阻塞父文档onload事件的触发。并且iframe是html标签中最消耗资源的标签,它的开销比DIV、SCRIPT、STYLE等DOM高1~2个数量级。

避免onload事件被阻塞,可使用JavaScript动态的加载iframe元素或动态设置iframe的src属性(但其仅在高级浏览器IE9及以上有效)。

<iframe id="if"></iframe>
document.getElementById("if").setAttribute("src","url");

多域名请求

一般来说,浏览器对于相同域名的图片,最多用2-4个线程并行下载(不同浏览器的并发下载数是不同的)。而相同域名的其他图片,则要等到其他图片下载完后才会开始下载。

有时候,图片数据太多,一些公司的解决方法是将图片数据分到多个域名的服务器上,这在一方面是将服务器的请求压力分到多个硬件服务器上,另一方面,是利用了浏览器的特性。(大家可以去新浪、腾讯门户网站查看,这些大型站点同一页面加载的图片可能由多个站点提供)

注:一个HTML请求的域名也不要太多(2~3个差不多),多了可能造成不同服务器连接时间差异,反而影响速度。

避免空链接属性

如<img src=""><a href="">这样的设置方式是非常不可取的,即使链接为空,在旧的浏览器也会以固定步骤发送请求信息。

另外<a href="#"></a>也不可取,最好的方式是在链接中加一个空的js代码<a href="javascript:void();"></a>

使用图像的BASE64编码

base64是一串字符串,他可以代表一个图片的所有信息,也就是可以通过

(S表示一串base64码)来显示图片,这种方式不需要再向服务器发送请求,完全由浏览器解析成图片。

目前高级浏览器都支持此功能,但要注意两点:

  1. 低版本浏览器(如IE7)不支持;
  2. base64字符串长度随图片的大小及复杂度成正比,base64也像URL一样,也有超出长度的情况(在IE8下很常见)。所以要根据情况来使用。

显式设置图片的宽高

如果HTML里的图片没有指定尺寸(宽和高),或者代码描述的尺寸与实际图片的尺寸不符时,浏览器则要在图片下载完成后再“回溯”该图片并重新显示,这会消耗额外时间。

<iframe id="if"></iframe>
document.getElementById("if").setAttribute("src","url");

显式指定文档字符集

如果浏览器不能获知页面的编码字符集,一般都会在执行脚本和渲染页面前,把字节流缓存,然后再搜索可进行解析的字符集,或以默认的字符集来解析页面代码,这会导致消耗不必要的时间。

<iframe id="if"></iframe>
document.getElementById("if").setAttribute("src","url");

渐进式增强设计

渐进式增强设计的通俗解释就是:首先写一段满足所有浏览器的基本样式,再在后面针对不同高级浏览器编写更漂亮的样式

如下代码,所有浏览器都支持background-color: #2067f5;满足了浏览器基本现实需求,而后面的background-image: -webkit-gradient等则为不同高级浏览器使用,只要浏览器识别就能执行这段代码(不识别,CSS也不会报错只会直接忽略)。

<div class="someClass"></div> 
.someClass 
{ width: 100px; 
 height: 100px; 
 background-color: #2067f5; 
 background-image: -webkit-gradient(linear, left top, left bottom, from(#2067f5), 
to(#154096)); 
 background-image: -webkit-linear-gradient(top, #2067f5, #154096); 
 background-image: -moz-linear-gradient(top, #2067f5, #154096); 
 background-image: -ms-linear-gradient(top, #2067f5, #154096); 
 background-image: -o-linear-gradient(top, #2067f5, #154096); 
 background-image: linear-gradient(to bottom, #2067f5, #154096); 
}

懒加载与预加载

预加载和懒加载,是一种改善用户体验的策略,它实际上并不能提高程序性能,但是却可以明显改善用户体验或减轻服务器压力。

预加载表示当前用户在请求到需要的数据之后,页面自动预加载下一次用户可能要看的数据,这样用户下一次操作的时候就立刻呈现,依次类推。

懒加载表示用户请求什么再显示什么,如果一个请求要响应的时间非常长,就不推荐懒加载。

Flush机制

当一个页面非常大,内容非常多,可以采用flush的形式分部分返回给页面,这样能告诉用户我正在工作,显示一部分内容比白屏等很长时间要好得多。在Java Web技术中,实现Flush非常简单,只要调用 HttpServletResponse.getWriter输出流的flush方法,就可以将已经完成加载的内容写回给客户端。

这种方式只适用于返回数据特别多、请求时间特别长的情况,常规数据还是用正常的实时全部返回最佳。这种实现方式实际会增加浏览器渲染时间和用户整体等待时间,但从用户体验上会更加优秀。

性能之服务器优化

CDN机制

所谓的CDN,就是一种内容分发网络,它采用智能路由和流量管理技术,及时发现能够给访问者提供最快响应的加速节点,并将访问者的请求导向到该加速节点,由该加速节点提供内容服务。

通俗点说,你在成都(浏览器)购买了北京卖家(服务器)的产品,北京卖家通过快递(CDN服务)寄送包裹,从北京到成都可以走路、坐汽车、火车或飞机,而采用CND的快递会选择飞机直达,因为这种寄送方式最快。

当然使用CDN有两个注意事项:

  1. CDN加速服务很贵,如果你觉得你的网站值得加速,可以选择购买;
  2. CDN不适合局域性网站,比如你的网站只有某一个片区访问或者局域网访问,因为区域性网络本来就很近,无需CDN加速。

HTTP协议的合理使用

浏览器缓存带来的性能提升已经众人皆知了,而很多人却并不知道浏览器的缓存过期时间、缓存删除、什么页面可以缓存等,都可以由我们程序员来控制,只要您熟悉HTTP协议,就可以轻松的控制浏览器。

动静分离

所谓的动静分离,就是将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 { 
 @Override 
 public 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) { 
 @Override 
 public PrintWriter getWriter() throws IOException { 
 return new PrintWriter(new OutputStreamWriter(buffer, 
 getCharacterEncoding())); 
 } 
 @Override 
 public ServletOutputStream getOutputStream() throws IOException { 
 return new ServletOutputStream() { 
 @Override 
 public void write(int b) throws IOException { 
 buffer.write(b); 
 } 
 }; 
 } 
 }; 
 chain.doFilter(request, hsrw); 
 byte[] gzipData=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(); 
 } 
……
 }

如果你觉得本篇还不错,请点赞关注!

文字由黑码教主创作,配图源于网络,版权归原作者所有,如有侵权联系删除!

你有更好的网站性能优化方案吗?

欢迎留言分享。



往一些不足的地方,通过博客,好好总结一下。

1.css禁用鼠标事件

.disabled {
    pointer-events: none;
    cursor: default;
    opacity: 0.6;
}
复制代码

2.get/post的理解和他们之间的区别

http

超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信。 HTTP 的工作方式是客户机与服务器之间的请求-应答协议。 web 浏览器可能是客户端,而计算机上的网络应用程序也可能作为服务器端。

http方法:

HEAD: 与 GET 相同,但只返回 HTTP 报头,不返回文档主体 PUT: 上传指定的 URI 表示 DELETE: 删除指定资源 OPTIONS: 返回服务器支持的 HTTP 方法 CONNECT: 把请求连接转换到透明的 TCP/IP 通道 POST: 向指定的资源提交要被处理的数据

// 查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的
POST /test/demo_form.asp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2
复制代码

GET: 从指定的资源请求数据

GET和POST的区别

GET 请求可被缓存 GET 请求保留在浏览器历史记录中 GET 请求可被收藏为书签 GET 请求不应在处理敏感数据时使用 GET 请求有长度限制(2048字符),IE和Safari浏览器限制2k;Opera限制4k;Firefox,Chrome限制8k GET 请求只应当用于取回数据

POST 请求不会被缓存 POST 请求不会保留在浏览器历史记录中 POST 不能被收藏为书签 POST 请求对数据长度没有要求

3.实现条纹网格的方式

nth-child(even/odd)

// odd表示基数,此时选中基数行的样式,even表示偶数行
.row:nth-child(odd){
    background: #eee;
}
复制代码

nth-of-type(odd)

.row:nth-of-type(odd){
    background: #eee;
}
复制代码

渐变实现linear-gradient

.stripe-bg{
  padding: .5em;
  line-height: 1.5em;
  background: beige;
  background-size: auto 3em;
  background-origin: content-box;
  background-image: linear-gradient(rgba(0,0,0,.2) 50%, transparent 0);
}
复制代码

4.js求平面两点之间的距离

// 数据可以以数组方式存储,也可以是对象方式
let a={x:'6', y:10},
        b={x: 8, y: 20};
    function distant(a,b){
        let dx=Number(a.x) - Number(b.x)
        let dy=Number(a.y) - Number(b.y)
        return Math.pow(dx*dx + dy*dy, .5)
    }
复制代码

5.css禁止用户选择

body{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
复制代码

6.数组去重

// indexOf实现
var array=[1, 1, '1'];

function unique(array) {
    var res=[];
    for (var i=0, len=array.length; i < len; i++) {
        var current=array[i];
        if (res.indexOf(current)===-1) {
            res.push(current)
        }
    }
    return res;
}

console.log(unique(array));

// 排序后去重
var array=[1, 1, '1'];

function unique(array) {
    var res=[];
    var sortedArray=array.concat().sort();
    var seen;
    for (var i=0, len=sortedArray.length; i < len; i++) {
        // 如果是第一个元素或者相邻的元素不相同
        if (!i || seen !==sortedArray[i]) {
            res.push(sortedArray[i])
        }
        seen=sortedArray[i];
    }
    return res;
}

console.log(unique(array));

// filter实现
var array=[1, 2, 1, 1, '1'];
function unique(array) {
    var res=array.filter(function(item, index, array){
        return array.indexOf(item)===index;
    })
    return res;
}
console.log(unique(array));

// 排序去重
var array=[1, 2, 1, 1, '1'];
function unique(array) {
    return array.concat().sort().filter(function(item, index, array){
        return !index || item !==array[index - 1]
    })
}
console.log(unique(array));

// Object键值对
var array=[{value: 1}, {value: 1}, {value: 2}];

function unique(array) {
    var obj={};
    return array.filter(function(item, index, array){
        console.log(typeof item + JSON.stringify(item))
        return obj.hasOwnProperty(typeof item + JSON.stringify(item)) ? false : (obj[typeof item + JSON.stringify(item)]=true)
    })
}

console.log(unique(array)); // [{value: 1}, {value: 2}]

// ES6 Set实现
var unique=(a)=> [...new Set(a)]
复制代码

7.什么是CDN和CDN的好处

CDN:CDN是将源站内容分发至最接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率。解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点加速、点播、直播等场景。 好处: 1、多域名加载资源 一般情况下,浏览器都会对单个域名下的并发请求数(文件加载)进行限制,通常最多有4个,那么第5个加载项将会被阻塞,直到前面的某一个文件加载完毕。 因为CDN文件是存放在不同区域(不同IP)的,所以对浏览器来说是可以同时加载页面所需的所有文件(远不止4个),从而提高页面加载速度。

2、文件可能已经被加载过并保存有缓存 一些通用的js库或者是css样式库,如jQuery,在网络中的使用是非常普遍的。当一个用户在浏览你的某一个网页的时候,很有可能他已经通过你网站使用的CDN访问过了其他的某一个网站,恰巧这个网站同样也使用了jQuery,那么此时用户浏览器已经缓存有该jQuery文件(同IP的同名文件如果有缓存,浏览器会直接使用缓存文件,不会再进行加载),所以就不会再加载一次了,从而间接的提高了网站的访问速度

3、高效率 你的网站做的再NB也不会NB过百度NB过Google吧?一个好的CDNs会提供更高的效率,更低的网络延时和更小的丢包率。

4、分布式的数据中心 假如你的站点布置在北京,当一个香港或者更远的用户访问你的站点的时候,他的数据请求势必会很慢很慢。而CDNs则会让用户从离他最近的节点去加载所需的文件,所以加载速度提升就是理所当然的了。

5、使用情况分析 一般情况下CDNs提供商(如百度云加速)都会提供数据统计功能,可以了解更多关于用户访问自己网站的情况,可以根据统计数据对自己的站点适时适当的做出些许调整。

6、有效防止网站被攻击 一般情况下CDNs提供商也是会提供网站安全服务的

8.圣杯布局和双飞翼布局

参考连接

9.正则表达式匹配手机号

function checkPhone(){
    if(!(/^1[345678]\d{9}$/.test(phone))){
        alert("手机号码有误,请重填");
        return false;
    }
}
复制代码

10.如何提高首频加载速度

1.js外联文件放到body底部,css外联文件放到head内 2.http静态资源尽量用多个子域名 3.服务器端提供html和http静态资源时最好开启gzip 4.在js,css,img等资源响应的http headers里设置expires,last-modified 5.尽量减少http requests的数量 6.js/css/html/img资源压缩 7.使用css spirtes,可以减少img请求次数 8.大图使用lazyload懒加载 9.避免404,减少外联js 10.减少cookie大小可以提高获得响应的时间 11.减少dom elements的数量 12.使用异步脚本,动态创建脚本

11.浏览器内核(渲染引擎)

IE/360/搜狗浏览器: Trident Chrome/Safari/Opera: WebKit(KHTML的一个开源的分支) (虽然我们称WebKit为浏览器内核,但不太适合直接称渲染引擎,因为WebKit本身主要是由两个引擎构成的,一个正是渲染引擎“WebCore”,另一个则是javascript解释引擎“JSCore”,它们均是从KDE的渲染引擎KHTML及javascript解释引擎KJS衍生而来。) (在13年发布的Chrome 28.0.1469.0版本开始,Chrome放弃Chromium引擎转而使用最新的Blink引擎(基于WebKit2——苹果公司于2010年推出的新的WebKit引擎),Blink对比上一代的引擎精简了代码、改善了DOM框架,也提升了安全性。) (为了减少研发成本,Opera在2013年2月宣布放弃Presto,转而跟随Chrome使用WebKit分支的Chromium引擎作为自家浏览器核心引擎) Firefox/SeaMonkey: Gecko

12.浏览器渲染过程及优化建议

1)解析: 一个是HTML/SVG/XHTML,事实上,Webkit有三个C++的类对应这三类文档。解析这三种文件会产生一个DOM Tree。 CSS,解析CSS会产生CSS规则树。 Javascript,脚本,主要是通过DOM API和CSSOM API来操作DOM Tree和CSS Rule Tree. 2)渲染:浏览器引擎会通过DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree。注意: Rendering Tree 渲染树并不等同于DOM树,因为一些像Header或display:none的东西就没必要放在渲染树中了。 CSS 的 Rule Tree主要是为了完成匹配并把CSS Rule附加上Rendering Tree上的每个Element。也就是DOM结点。也就是所谓的Frame。 然后,计算每个Frame(也就是每个Element)的位置,这又叫layout和reflow过程。 3)绘制:最后通过调用操作系统Native GUI的API绘制。

减少reflow和repaint 1)不要一条一条地修改DOM的样式。还不如预先定义好css的class,然后修改DOM的className。

  1. 把DOM离线后修改。如: 使用documentFragment 对象在内存里操作DOM 先把DOM给display:none(有一次reflow),然后你想怎么改就怎么改。比如修改100次,然后再把他显示出来。 clone一个DOM结点到内存里,然后想怎么改就怎么改,改完后,和在线的那个的交换一下。 3)不要把DOM结点的属性值放在一个循环里当成循环里的变量。不然这会导致大量地读写这个结点的属性 4)为动画的HTML元件使用fixed或absoulte的position,尽量使用transfoem,那么修改他们的CSS是不会reflow的 5)尽量少使用table布局。因为可能很小的一个小改动会造成整个table的重新布局

13. 页面导入样式时,使用link和@import有什么区别?

(1)link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS; (2)页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载; (3)import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题; (4)link支持使用js控制DOM去改变样式,而@import不支持;

14. 简述一下你对HTML语义化的理解?

用正确的标签做正确的事情。 html语义化让页面的内容结构化,便于对浏览器、搜索引擎解析; 即使在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的; 搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO; 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。

15. 请描述一下 cookies,sessionStorage 和 localStorage 的区别?

cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。 cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。 sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

存储大小: cookie数据大小不能超过4k。 sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

有期时间: localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据; sessionStorage 数据在当前浏览器窗口关闭后自动删除。 cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

16. iframe有那些缺点?

*iframe会阻塞主页面的Onload事件; *搜索引擎的检索程序无法解读这种页面,不利于SEO; *iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。 使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript 动态给iframe添加src属性值,这样可以绕开以上两个问题。

17. vue父子组件生命周期的顺序及作用?


(图片来自vue官网,更多vue学习推荐去官网查看详细文档)


18. 网页验证码是干嘛的,是为了解决什么安全问题?

区分用户是计算机还是人的公共全自动程序。可以防止恶意破解密码、刷票、论坛灌水; 有效防止黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试。

19. 介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的?

(1)有两种, IE 盒子模型、W3C 盒子模型; (2)盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border); (3)区 别: IE的content部分把 border 和 padding计算了进去;

20. position的值relative和absolute定位原点是?

absolute 生成绝对定位的元素,相对于值不为 static的第一个父元素进行定位。 fixed (老IE不支持) 生成绝对定位的元素,相对于浏览器窗口进行定位。 relative 生成相对定位的元素,相对于其正常位置进行定位。 static 默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right z-index 声明)。 inherit 规定从父元素继承 position 属性的值。

21. 经常遇到的浏览器的兼容性有哪些?原因,解决方法是什么,常用hack的技巧 ?

png24位的图片在iE6浏览器上出现背景,解决方案是做成PNG8.

  • 浏览器默认的margin和padding不同。解决方案是加一个全局的*{margin:0;padding:0;}来统一。
  • IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。 浮动ie产生的双倍距离 #box{ float:left; width:10px; margin:0 0 0 100px;} 这种情况之下IE会产生20px的距离,解决方案是在float的标签样式控制中加入 ——_display:inline;将其转化为行内属性。(_这个符号只有ie6会识别) 渐进识别的方式,从总体中逐渐排除局部。 首先,巧妙的使用“”这一标记,将IE游览器从所有情况中分离出来。 接着,再次使用“+”将IE8和IE7、IE6分离开来,这样IE8已经独立识别。 css .bb{ background-color:red;/所有识别/ background-color:#00deff; /IE6、7、8识别/ +background-color:#a200ff;/IE6、7识别/ _background-color:#1e0bd1;/IE6识别/ }
  • IE下,可以使用获取常规属性的方法来获取自定义属性, 也可以使用getAttribute()获取自定义属性; Firefox下,只能使用getAttribute()获取自定义属性。 解决方法:统一通过getAttribute()获取自定义属性。
  • IE下,even对象有x,y属性,但是没有pageX,pageY属性; Firefox下,event对象有pageX,pageY属性,但是没有x,y属性。
  • 解决方法:(条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。
  • Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示, 可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决。

超链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了解决方法是改变CSS属性的排列顺序: L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}

22. CSS优化、提高性能的方法有哪些?

关键选择器(key selector)。选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分); 如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签。过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了); 提取项目的通用公有样式,增强可复用性,按模块编写组件;增强项目的协同开发性、可维护性和可扩展性; 使用预处理工具或构建工具(gulp对css进行语法检查、自动补前缀、打包压缩、自动优雅降级);

23. 如何修改chrome记住密码后自动填充表单的黄色背景 ?

 input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
    background-color: rgb(250, 255, 189); /* #FAFFBD; */
    background-image: none;
    color: rgb(0, 0, 0);
  }
复制代码

24. 让页面里的字体变清晰,变细用CSS怎么做?

-webkit-font-smoothing: antialiased;
复制代码

25. 让overflow:scroll平滑滚动?

-webkit-overflow-scrolling: touch;
复制代码

26. 如何将浮点数点左边的数每三位添加一个逗号,如12000000.11转化为『12,000,000.11』?

function commafy(num){
  	return num && num
  		.toString()
  		.replace(/(\d)(?=(\d{3})+\.)/g, function($1, $2){
  			return $2 + ',';
  		});
  }
复制代码

27. Javascript作用链域?

全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。 当需要从局部函数查找某一属性或方法时,如果当前作用域没有找到,就会上溯到上层作用域查找, 直至全局函数,这种组织形式就是作用域链。

28. 谈谈This对象的理解。

this总是指向函数的直接调用者(而非间接调用者); 如果有new关键字,this指向new出来的那个对象; 在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window;

29. eval是做什么的?

它的功能是把对应的字符串解析成JS代码并运行; 应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。 由JSON字符串转换为JSON对象的时候可以用eval,var obj=eval('('+ str +')');

30. 什么是window对象? 什么是document对象?

window对象是指浏览器打开的窗口。 document对象是Documentd对象(HTML 文档对象)的一个只读引用,window对象的一个属性。

31. ["1", "2", "3"].map(parseInt) 答案是多少?

["1", "2", "3"].map(parseInt) 答案也就是:[1, NaN, NaN]

32. 什么是闭包(closure),为什么要用它?

闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。

33. javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么?

使JS编码更加规范化的模式,消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为。 默认支持的糟糕特性都会被禁用,比如不能用with,也不能在意外的情况下给全局变量赋值; 全局变量的显示声明,函数必须声明在顶层,不允许在非函数代码块内声明函数,arguments.callee也不允许使用; 保证代码运行的安全,限制函数中的arguments修改; 提高编译器效率,增加运行速度;

34. 如何判断一个对象是否属于某个类?

if(a instanceof Person){
   alert('yes');
}
// 判断对象类型最好的方式
// 对于 Object 对象,直接调用 toString()  就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
Object.prototype.toString.call('') ;   // [object String]
Object.prototype.toString.call(1) ;    // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window 是全局对象 global 的引用
复制代码

35. new一个对象的过程

1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。
复制代码

36. Ajax 解决浏览器缓存问题

1、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")。

2、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")。 3、在URL后面加上一个随机数: "fresh=" + Math.random();。 4、在URL后面加上时间戳:"nowtime=" + new Date().getTime();。 5、如果是使用jQuery,直接这样就可以了 $.ajaxSetup({cache:false})。这样页面的所有ajax都会执行这条语句就是不需要保存缓存记录。

37. 如何解决跨域问题?

jsonp、 iframe、window.name、window.postMessage、服务器上设置代理页面

38. 模块化开发怎么做

立即执行函数,不暴露私有成员

var module1=(function(){
     ????var _count=0;
     ????var m1=function(){
     ??????//...
     ????};
     ????var m2=function(){
     ??????//...
     ????};
     ????return {
     ??????m1 : m1,
     ??????m2 : m2
     ????};
     ??})();
复制代码

39. AMD(Modules/Asynchronous-Definition)、CMD(Common Module Definition)规范区别?

对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。 2. CMD 推崇依赖就近,AMD 推崇依赖前置。

// CMD
 define(function(require, exports, module) {
     var a=require('./a')
     a.doSomething()
     // 此处略去 100 行
     var b=require('./b') // 依赖可以就近书写
     b.doSomething()
     // ...
 })

 // AMD 默认推荐
 define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
     a.doSomething()
     // 此处略去 100 行
     b.doSomething()
     // ...
 })
复制代码

40. requireJS的核心原理是什么?(如何动态加载的?如何避免多次加载的?如何 缓存的?)

参考链接

41. 如何实现一个模块加载器

参考连接

42. 列举几条 JavaScript 的基本代码规范

(1)不要在同一行声明多个变量 (2)如果你不知道数组的长度,使用 push (3)请使用===/!==来比较 true/false 或者数值 (4)对字符串使用单引号 ''(因为大多时候我们的字符串。特别html会出现") (5)使用对象字面量替代 new Array 这种形式 (6)绝对不要在一个非函数块里声明一个函数,把那个函数赋给一个变量。浏览器允许你这么做,但是它们解析不同 (7)不要使用全局函数 (8)总是使用 var 来声明变量,如果不这么做将导致产生全局变量,我们要避免污染全局命名空间 (9)Switch 语句必须带有 default 分支 (10)使用 /**...*/ 进行多行注释,包括描述,指定类型以及参数值和返回值 (11)函数不应该有时候有返回值,有时候没有返回值 (12)语句结束一定要加分号 (13)for 循环必须使用大括号 (14)if 语句必须使用大括号 (15)for-in 循环中的变量应该使用 var 关键字明确限定作用域,从而避免作用域污染 (16)避免单个字符名,让你的变量名有描述意义 (17)当命名对象、函数和实例时使用驼峰命名规则 (18)给对象原型分配方法,而不是用一个新的对象覆盖原型,覆盖原型会使继承出现问题

43. DOM操作——怎样添加、移除、移动、复制、创建和查找节点?

1)创建新节点 createDocumentFragment() //创建一个DOM片段 createElement() //创建一个具体的元素 createTextNode() //创建一个文本节点 (2)添加、移除、替换、插入 appendChild() removeChild() replaceChild() insertBefore() //在已有的子节点前插入一个新的子节点 (3)查找 getElementsByTagName() //通过标签名称 getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的) getElementById() //通过元素Id,唯一性

44. jquery实现原理

参考链接

45. jquery中如何将数组转化为json字符串,然后再转化回来?

jQuery中没有提供这个功能,所以你需要先编写两个jQuery的扩展: 
 $.fn.stringifyArray=function(array) {
        return JSON.stringify(array)
    }

    $.fn.parseArray=function(array) {
        return JSON.parse(array)
    }

    然后调用:
    $.fn.stringifyArray(array)
复制代码

46. jquery的$.extend深复制和浅复制原理

// 浅复制
$={ 

     extend : function(target, options) { 

        for (name in options) { 

            target[name]=options[name]; 

        } 

        return target; 

    } 

}; 
// 深复制
$={ 
   extend : function(deep, target, options) { 
       for (name in options) { 
           copy=options[name]; 
           if (deep && copy instanceof Array) { 
               target[name]=$.extend(deep, [], copy); 
           } else if (deep && copy instanceof Object) { 

              target[name]=$.extend(deep, {}, copy); 
           } else { 
              target[name]=options[name]; 
          } 
      } 

     return target; 
  }
};
复制代码

47. jquery.extend 与 jquery.fn.extend的区别?

jquery.extend 为jquery类添加类方法,可以理解为添加静态方法

  • jquery.fn.extend: 源码中jquery.fn=jquery.prototype,所以对jquery.fn的扩展,就是为jquery类添加成员函数 使用: jquery.extend扩展,需要通过jquery类来调用,而jquery.fn.extend扩展,所有jquery实例都可以直接调用。

48. 如何判断当前脚本运行在浏览器还是node环境中?(阿里)

this===window ? 'browser' : 'node';
复制代码

49. 实现一个页面操作不会整页刷新的网站,并且能在浏览器前进、后退时正确响应。给出你的技术实现方案?

参考链接

50. 把 Script 标签 放在页面的最底部的body封闭之前 和封闭之后有什么区别?浏览器会如何解析它们?

之前推荐的方法(已过时):之前解决这个问题的方法是把script标签放到body标签之后 ,这确保了解析到</body>之前都不会被script终端。这个方法是有问题的: 浏览器在整个文档解析完成之前都不能下载script文件,如果文档很大的话,解析完HTML,用户依然要等待script文件下载并执行完成之后,才能操作这个网站。

现在推荐的解决方案: 现在浏览器script标签支持 async 和 defer 属性. 应用这些属性当script被下载时,浏览器更安全而且可以并行下载(下载script并不阻断HTML解析)。 1.async标记的Script异步执行下载,并执行。这意味着script下载时并不阻塞HTML的解析,并且下载结束script马上执行。 2.defer标签的script顺序执行。这种方式也不会阻断浏览器解析HTML。 跟 async不同, defer scripts在整个文档里的script都被下载完才顺序执行。

51. JQuery一个对象可以同时绑定多个事件,这是如何实现的?

 //多个事件同一个函数:
 	$("div").on("click mouseover", function(){});
 //多个事件不同函数
 	$("div").on({
 		click: function(){},
 		mouseover: function(){}
 	});
复制代码

52. 什么是前端路由?前端路由的 实现原理

参考链接

53. 检测浏览器版本版本有哪些方式?

  功能检测、userAgent特征检测

  比如:navigator.userAgent
  //"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36
    (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
复制代码

54. 什么是Polyfill?

polyfill 是“在旧版浏览器上复制标准 API 的 JavaScript 补充”,可以动态地加载 JavaScript 代码或库,在不支持这些标准 API 的浏览器中模拟它们。 例如,geolocation(地理位置)polyfill 可以在 navigator 对象上添加全局的 geolocation 对象,还能添加 getCurrentPosition 函数以及“坐标”回调对象, 所有这些都是 W3C 地理位置 API 定义的对象和函数。因为 polyfill 模拟标准 API,所以能够以一种面向所有浏览器未来的方式针对这些 API 进行开发, 一旦对这些 API 的支持变成绝对大多数,则可以方便地去掉 polyfill,无需做任何额外工作。

55. 做的项目中,有没有用过或自己实现一些 polyfill 方案(兼容性处理方案)?

html5shiv、Geolocation、Placeholder

56. 我们给一个dom同时绑定两个点击事件,一个用捕获,一个用冒泡。会执行几次事件,会先执行冒泡还是捕获?

按照W3C的标准,先发生捕获事件,后发生冒泡事件。所有事件的顺序是:其他元素捕获阶段事件 -> 本元素代码顺序事件 -> 其他元素冒泡阶段事件

// div-capture > btn-bubble > btn-capture > div-bubble
var btn=document.querySelector('button');
var div=document.querySelector('div');

btn.addEventListener('click', function(){
    console.log('bubble','btn');
},false);
btn.addEventListener('click', function(){
    console.log('capture','btn');
},true);

div.addEventListener('click', function(){
    console.log('bubble','div');
},false);
div.addEventListener('click', function(){
    console.log('capture','div');
},true);
复制代码

57. Webpack热更新实现原理?

Webpack编译期,为需要热更新的 entry 注入热更新代码(EventSource通信)

  1. 页面首次打开后,服务端与客户端通过 EventSource 建立通信渠道,把下一次的 hash 返回前端
  2. 客户端获取到hash,这个hash将作为下一次请求服务端 hot-update.js 和 hot-update.json的hash
  3. 修改页面代码后,Webpack 监听到文件修改后,开始编译,编译完成后,发送 build 消息给客户端
  4. 客户端获取到hash,成功后客户端构造hot-update.js script链接,然后插入主文档
  5. hot-update.js 插入成功后,执行hotAPI 的 createRecord 和 reload方法,获取到 Vue 组件的 render方法,重新 render 组件, 继而实现 UI 无刷新更新。

58. 函数节流和防抖

参考链接

59. 页面重构怎么操作?

网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。 也就是说是在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。

对于传统的网站来说重构通常是:

表格(table)布局改为DIV+CSS 使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对IE6有效的) 对于移动平台的优化 针对于SEO进行优化 深层次的网站重构应该考虑的方面

减少代码间的耦合 让代码保持弹性 严格按规范编写代码 设计可扩展的API 代替旧有的框架、语言(如VB) 增强用户体验 通常来说对于速度的优化也包含在重构中

压缩JS、CSS、image等前端资源(通常是由服务器来解决) 程序的性能优化(如数据读写) 采用CDN来加速资源加载 对于JS DOM的优化 HTTP服务器的文件缓存

60. 列举IE与其他浏览器不一样的特性

事件不同之处:

 	触发事件的元素被认为是目标(target)。而在 IE 中,目标包含在 event 对象的 srcElement 属性;

获取字符代码、如果按键代表一个字符(shift、ctrl、alt除外),IE 的 keyCode 会返回字符代码(Unicode),DOM 中按键的代码和字符是分离的,要获取字符代码,需要使用 charCode 属性;

阻止某个事件的默认行为,IE 中阻止某个事件的默认行为,必须将 returnValue 属性设置为 false,Mozilla 中,需要调用 preventDefault() 方法;

停止事件冒泡,IE 中阻止事件进一步冒泡,需要设置 cancelBubble 为 true,Mozzilla 中,需要调用 stopPropagation();
复制代码

61. 对Node的优点和缺点提出了自己的看法?

*(优点)因为Node是基于事件驱动和无阻塞的,所以非常适合处理并发请求, 因此构建在Node上的代理服务器相比其他技术实现(如Ruby)的服务器表现要好得多。 此外,与Node代理服务器交互的客户端代码是由javascript语言编写的, 因此客户端和服务器端都用同一种语言编写,这是非常美妙的事情。

*(缺点)Node是一个相对新的开源项目,所以不太稳定,它总是一直在变, 而且缺少足够多的第三方库支持。看起来,就像是Ruby/Rails当年的样子。

62. 你有用过哪些前端性能优化的方法?

(1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。

(2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数

(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。

(4) 当需要设置的样式很多时设置className而不是直接操作style。

(5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。

(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。

(7) 图片预加载,将样式表放在顶部,将脚本放在底部  加上时间戳。

(8) 避免在页面的主体布局中使用table,table要等其中的内容完全下载之后才会显示出来,显示比div+css布局慢。
对普通的网站有一个统一的思路,就是尽量向前端优化、减少数据库操作、减少磁盘IO。向前端优化指的是,在不影响功能和体验的情况下,能在浏览器执行的不要在服务端执行,能在缓存服务器上直接返回的不要到应用服务器,程序能直接取得的结果不要到外部取得,本机内能取得的数据不要到远程取,内存能取到的不要到磁盘取,缓存中有的不要去数据库查询。减少数据库操作指减少更新次数、缓存结果减少查询次数、将数据库执行的操作尽可能的让你的程序完成(例如join查询),减少磁盘IO指尽量不使用文件系统作为缓存、减少读写文件次数等。程序优化永远要优化慢的部分,换语言是无法“优化”的。
复制代码

63. http

1**(信息类):表示接收到请求并且继续处理 100——客户必须继续发出请求 101——客户要求服务器根据请求转换HTTP协议版本

2**(响应成功):表示动作被成功接收、理解和接受
200——表明该请求被成功地完成,所请求的资源发送回客户端
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求

3**(重定向类):为了完成指定的动作,必须接受进一步处理
300——请求的资源可在多处得到
301——本网页被永久性转移到另一个URL
302——请求的网页被转移到一个新的地址,但客户访问仍继续通过原始URL地址,重定向,新的URL会在response中的Location中返回,浏览器将会使用新的URL发出新的Request。
303——建议客户访问其他URL或访问方式
304——自从上次请求后,请求的网页未修改过,服务器返回此响应时,不会返回网页内容,代表上次的文档已经被缓存了,还可以继续使用
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除

4**(客户端错误类):请求包含错误语法或不能正确执行
400——客户端请求有语法错误,不能被服务器所理解
401——请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
HTTP 401.1 - 未授权:登录失败
??HTTP 401.2 - 未授权:服务器配置问题导致登录失败
??HTTP 401.3 - ACL 禁止访问资源
??HTTP 401.4 - 未授权:授权被筛选器拒绝
HTTP 401.5 - 未授权:ISAPI 或 CGI 授权失败
402——保留有效ChargeTo头响应
403——禁止访问,服务器收到请求,但是拒绝提供服务
HTTP 403.1 禁止访问:禁止可执行访问
??HTTP 403.2 - 禁止访问:禁止读访问
??HTTP 403.3 - 禁止访问:禁止写访问
??HTTP 403.4 - 禁止访问:要求 SSL
??HTTP 403.5 - 禁止访问:要求 SSL 128
??HTTP 403.6 - 禁止访问:IP 地址被拒绝
??HTTP 403.7 - 禁止访问:要求客户证书
??HTTP 403.8 - 禁止访问:禁止站点访问
??HTTP 403.9 - 禁止访问:连接的用户过多
??HTTP 403.10 - 禁止访问:配置无效
??HTTP 403.11 - 禁止访问:密码更改
??HTTP 403.12 - 禁止访问:映射器拒绝访问
??HTTP 403.13 - 禁止访问:客户证书已被吊销
??HTTP 403.15 - 禁止访问:客户访问许可过多
??HTTP 403.16 - 禁止访问:客户证书不可信或者无效
HTTP 403.17 - 禁止访问:客户证书已经到期或者尚未生效
404——一个404错误表明可连接服务器,但服务器无法取得所请求的网页,请求资源不存在。eg:输入了错误的URL
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求长。

5**(服务端错误类):服务器不能正确执行一个正确的请求
HTTP 500 - 服务器遇到错误,无法完成请求
??HTTP 500.100 - 内部服务器错误 - ASP 错误
??HTTP 500-11 服务器关闭
??HTTP 500-12 应用程序重新启动
??HTTP 500-13 - 服务器太忙
??HTTP 500-14 - 应用程序无效
??HTTP 500-15 - 不允许请求 global.asa
??Error 501 - 未实现
HTTP 502 - 网关错误
HTTP 503:由于超载或停机维护,服务器目前无法使用,一段时间后可能恢复正常
复制代码

64. 一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?(流程说的越详细越好)

而高手可以根据自己擅长的领域自由发挥,从URL规范、HTTP协议、DNS、CDN、数据库查询、 到浏览器流式解析、CSS规则构建、layout、paint、onload/domready、JS执行、JS API绑定等等;

详细版:
1、浏览器会开启一个线程来处理这个请求,对 URL 分析判断如果是 http 协议就按照 Web 方式来处理;
2、调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法;
  3、通过DNS解析获取网址的IP地址,设置 UA 等信息发出第二个GET请求;
4、进行HTTP协议会话,客户端发送报头(请求报头);
  5、进入到web服务器上的 Web Server,如 Apache、Tomcat、Node.JS 等服务器;
  6、进入部署好的后端应用,如 PHP、Java、JavaScript、Python 等,找到对应的请求处理;
7、处理结束回馈报头,此处如果浏览器访问过,缓存上有对应资源,会与服务器最后修改时间对比,一致则返回304;
  8、浏览器开始下载html文档(响应报头,状态码200),同时使用缓存;
  9、文档树建立,根据标记请求所需指定MIME类型的文件(比如css、js),同时设置了cookie;
  10、页面开始渲染DOM,JS根据DOM API操作DOM,执行事件绑定等,页面显示完成。
复制代码

65. 前端学习资源

js秘密花园 jquery原理解析 css3 js标准

66. 邮箱验证

var pattern=/^([A-Za-z0-9_\-\.\u4e00-\u9fa5])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,8})$/;
复制代码

参考链接

67. ajax实现原理及方法使用

readyState属性有五个状态值。

0:是uninitialized,未初始化。已经创建了XMLHttpRequest对象但是未初始化。
1:是loading.已经开始准备好要发送了。
2:已经发送,但是还没有收到响应。
3:正在接受响应,但是还不完整。
4:接受响应完毕。
responseText:服务器返回的响应文本。只有当readyState>=3的时候才有值,根据readyState的状态值,可以知道,当readyState=3,返回的响应文本不完整,只有readyState=4,完全返回,才能接受全部的响应文本。

responseXML:response  as Dom Document object。响应信息是xml,可以解析为Dom对象。
status:服务器的Http状态码,若是200,则表示OK,404,表示为未找到。
statusText:服务器http状态码的文本。比如OK,Not Found。
复制代码

参考链接

68. js实现继承

参考链接

69. 用generator实现es7的async


复制代码

70. 闭包使用的优缺点

优点:1.保护函数内部变量的安全,加强了封装性 2.在内存中维持一个变量 3.设计私有方法和变量 4.可以读取函数内部的变量 缺点:1.导致内存泄漏,使用不当会造成额外的内存占用 2.可以改变父函数的变量,所以使用时要谨慎

71. canvas和svg区别

1.从图像类别区分,Canvas是基于像素的位图,而SVG却是基于矢量图形。可以简单的把两者的区别看成photoshop与illustrator的区别。 2.从结构上说,Canvas没有图层的概念,所有的修改整个画布都要重新渲染,而SVG则可以对单独的标签进行修改。 3.从操作对象上说,Canvas是基于HTML canvas标签,通过宿主提供的Javascript API对整个画布进行操作的,而SVG则是基于XML元素的。 4.从功能上讲,SVG发布日期较早,所以功能相对Canvas比较完善。 5.关于动画,Canvas更适合做基于位图的动画,而SVG则适合图表的展示。 6.从搜索引擎角度分析,由于svg是有大量标签组成,所以可以通过给标签添加属性,便于爬虫搜索

72. 开启硬件加速

//目前,像Chrome/Filefox/Safari/IE9+以及最新版本Opera都支持硬件加速,当检测到某个DOM元素应用了某些CSS规则时就会自动开启,从而解决页面闪白,保证动画流畅。
.css {
    -webkit-transform: translate3d(0,0,0);
    -moz-transform: translate3d(0,0,0);
    -ms-transform: translate3d(0,0,0);
    transform: translate3d(0,0,0);
}
复制代码

73. button注意事项

<button></button>元素一定要写上type属性不然会默认提交表单,出现想不到的bug
复制代码

74. 移动端html标签几个体验优化

html,body{

overflow: hidden;/*手机上写overflow-x:hidden;会有兼容性问题,如果子级如果是绝对定位有运动到屏幕外的话ios7系统会出现留白*/

-webkit-overflow-scrolling:touch;/*流畅滚动,ios7下会有滑一下滑不动的情况,所以需要写上*/

position:realtive;/*直接子级如果是绝对定位有运动到屏幕外的话,会出现留白*/
}
复制代码

75.手机上的多行省略

.overflow-hidden{
    display: box !important;
    display: -webkit-box !important;
    overflow: hidden;
    text-overflow: ellipsis;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;/*第几行出现省略号*/
    /*text-align:justify;不能和溢出隐藏的代码一起写,会有bug*/
}
复制代码

76. 长时间按住页面闪退

.element {
    -webkit-touch-callout: none;
}
复制代码

77. 改变输入框内提示文字颜色

::-webkit-input-placeholder { /* WebKit browsers */
    color: #999; }
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
    color: #999; }
::-moz-placeholder { /* Mozilla Firefox 19+ */
    color: #999; }
:-ms-input-placeholder { /* Internet Explorer 10+ */
    color: #999; }
input:focus::-webkit-input-placeholder{ color:#999; }
复制代码

78. 自动播放音乐

//JS绑定自动播放(操作window时,播放音乐)
$(window).one('touchstart', function(){
    music.play();
})

//微信下兼容处理
document.addEventListener("WeixinJSBridgeReady", function () {
    music.play();
}, false);
复制代码

79.消除transtration闪屏

消除transition闪屏
.css {
    -webkit-transform-style: preserve-3d;
    -webkit-backface-visibility: hidden;
    -webkit-perspective: 1000;
}
复制代码

最后

文中如有一些不足,欢迎指正。笔者1天后将推出开源的CMS系统,技术架构:

  • 后台Node+Koa+redis+JsonSchema
  • 管理后台界面 vue-cli3 + vue + ts + vuex + antd-vue + axios
  • 客户端前台 react + antd + react-hooks + axios

后面将推出该系统的设计思想,架构和实现过程,欢迎在公众号《趣谈前端》里查看更详细的介绍。


原链接:https://juejin.im/post/5d8989296fb9a06b1f147070