https://www.zhihu.com/question/346430969/answer/2308835691
为什么要做性能优化?性能优化到底有多重要?网站的性能优化对于用户的留存率、转化率有很大的影响,所以对于前端开发来说性能优化能力也是重要的考察点。

性能优化的点非常的多,有的小伙伴觉得记起来非常的麻烦,所以这里主要梳理出一条线来帮助记忆。

可以将性能优化分为两个大的分类:

加载时优化
运行时优化
加载时性能
顾名思义加载时优化 主要解决的就是让一个网站加载过程更快,比如压缩文件大小、使用CDN加速等方式可以优化加载性能。检查加载性能的指标一般看:白屏时间和首屏时间:

白屏时间:指的是从输入网址, 到页面开始显示内容的时间。
首屏时间:指从输入网址, 到首屏页面内容渲染完毕的时间。
白屏时间计算
将代码脚本放在 </head> 前面就能获取白屏时间:

<script>

new Date().getTime() - performance.timing.navigationStart

</script>
首屏时间计算
在window.onload事件中执行以下代码,可以获取首屏时间:

new Date().getTime() - performance.timing.navigationStart
运行时性能
运行时性能是指页面运行时的性能表现,而不是页面加载时的性能。可以通过chrome开发者工具中的 Performance 面板来分析页面的运行时性能。

接下来就从加载时性能和运行时性能两个方面来讨论网站优化具体应该怎么做。

加载时性能优化
我们知道浏览器如果输入的是一个网址,首先要交给DNS域名解析 -> 找到对应的IP地址 -> 然后进行TCP连接 -> 浏览器发送HTTP请求 -> 服务器接收请求 -> 服务器处理请求并返回HTTP报文 -> 以及浏览器接收并解析渲染页面。从这一过程中,其实就可以挖出优化点,缩短请求的时间,从而去加快网站的访问速度,提升性能。

这个过程中可以提升性能的优化的点:

DNS解析优化,浏览器访问DNS的时间就可以缩短
使用HTTP2
减少HTTP请求数量
减少http请求大小
服务器端渲染
静态资源使用CDN
资源缓存,不重复加载相同的资源
从上面几个优化点出发,有以下几种实现性能优化的方式。

1.DNS 预解析
DNS 作为互联网的基础协议,其解析的速度似乎容易被网站优化人员忽视。现在大多数新浏览器已经针对DNS解析进行了优化,典型的一次DNS解析耗费20-120毫秒,减少DNS解析时间和次数是个很好的优化方式。

DNS Prefetching是具有此属性的域名不需要用户点击链接就在后台解析,而域名解析和内容载入是串行的网络操作,所以这个方式能减少用户的等待时间,提升用户体验。

浏览器对网站第一次的域名DNS解析查找流程依次为:

浏览器缓存 ->系统缓存 ->路由器缓存 ->ISP DNS缓存 ->递归搜索
DNS预解析的实现:

用meta信息来告知浏览器, 当前页面要做DNS预解析:

<meta http-equiv="x-dns-prefetch-control" content="on" />
在页面header中使用link标签来强制对DNS预解析:

<link rel="dns-prefetch" href="http://bdimg.share.baidu.com"; />
注意:dns-prefetch需慎用,多页面重复DNS预解析会增加重复DNS查询次数。
2.使用HTTP2
HTTP2带来了非常大的加载优化,所以在做优化上首先就想到了用HTTP2代替HTTP1。

HTTP2相对于HTTP1有这些优点:

解析速度快

服务器解析 HTTP1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段。

多路复用

在 HTTP2 上,多个请求可以共用一个 TCP 连接,这称为多路复用。

当然HTTP1.1有一个可选的Pipelining技术,说的意思是当一个HTTP连接在等待接收响应时可以通过这个连接发送其他请求。听起来很棒,其实这里有一个坑,处理响应是按照顺序的,也就是后发的请求有可能被先发的阻塞住,也正因此很多浏览器默认是不开启Pipelining的。

HTTP1 的Pipelining技术会有阻塞的问题,HTTP/2的多路复用可以粗略的理解为非阻塞版的Pipelining。即可以同时通过一个HTTP连接发送多个请求,谁先响应就先处理谁,这样就充分的压榨了TCP这个全双工管道的性能。加载性能会是HTTP1的几倍,需要加载的资源越多越明显。当然多路复用是建立在加载的资源在同一域名下,不同域名神仙也复用不了。

首部压缩

HTTP2 提供了首部压缩功能。(这部分了解一下就行)

HTTP 1.1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,因为它们需要等待带着ACK的响应回来以后才能继续被发送。HTTP/2对消息头采用HPACK(专为http/2头部设计的压缩格式)进行压缩传输,能够节省消息头占用的网络的流量。而HTTP/1.x每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。

服务器推送

服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。

3.减少HTTP请求数量
HTTP请求建立和释放需要时间。

HTTP请求从建立到关闭一共经过以下步骤:

客户端连接到Web服务器
发送HTTP请求
服务器接受请求并返回HTTP响应
释放连接TCP链接
这些步骤都是需要花费时间的,在网络情况差的情况下,花费的时间更长。如果页面的资源非常碎片化,每个HTTP请求只带回来几K甚至不到1K的数据(比如各种小图标)那性能是非常浪费的。

4.压缩、合并文件
压缩文件 -> 减少HTTP请求大小,可以减少请求时间
文件合并 -> 减少HTTP请求数量。
我们可以对html、css、js以及图片资源进行压缩处理,现在可以很方便的使用 webpack 实现文件的压缩:

js压缩:UglifyPlugin
CSS压缩:MiniCssExtractPlugin
HTML压缩:HtmlWebpackPlugin
图片压缩:image-webpack-loader

提取公共代码

合并文件虽然能减少HTTP请求数量, 但是并不是文件合并越多越好,还可以考虑按需加载方式(后面第6点有讲到)。什么样的文件可以合并呢?可以提取项目中多次使用到的公共代码进行提取,打包成公共模块。

可以使用 webpack4 的 splitChunk 插件 cacheGroups 选项。

optimization: {

  runtimeChunk: {
    name: 'manifest' // 将 webpack 的 runtime 代码拆分为一个单独的 chunk。
},
splitChunks: {
    cacheGroups: {
        vendor: {
            name: 'chunk-vendors',
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
            chunks: 'initial'
        },
        common: {
            name: 'chunk-common',
            minChunks: 2,
            priority: -20,
            chunks: 'initial',
            reuseExistingChunk: true
        }
    },
}

},
5.采用svg图片或者字体图标
因为字体图标或者SVG是矢量图,代码编写出来的,放大不会失真,而且渲染速度快。字体图标使用时就跟字体一样,可以设置属性,例如 font-size、color 等等,非常方便,还有一个优点是生成的文件特别小。

6.按需加载代码,减少冗余代码
按需加载

在开发SPA项目时,项目中经常存在十几个甚至更多的路由页面, 如果将这些页面都打包进一个JS文件, 虽然减少了HTTP请求数量, 但是会导致文件比较大,同时加载了大量首页不需要的代码,有些得不偿失,这时候就可以使用按需加载, 将每个路由页面单独打包为一个文件,当然不仅仅是路由可以按需加载。

根据文件内容生成文件名,结合 import 动态引入组件实现按需加载:

通过配置 output 的 filename 属性可以实现这个需求。filename 属性的值选项中有一个 [contenthash],它将根据文件内容创建出唯一 hash。当文件内容发生变化时,[contenthash] 也会发生变化。

output: {

filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].js',
path: path.resolve(__dirname, '../dist'),

},
减少冗余代码

一方面避免不必要的转义:babel-loader用 include 或 exclude 来帮我们避免不必要的转译,不转译node_moudules中的js文件,其次在缓存当前转译的js文件,设置loader: 'babel-loader?cacheDirectory=true'

其次减少ES6 转为 ES5 的冗余代码:Babel 转化后的代码想要实现和原来代码一样的功能需要借助一些帮助函数,比如:

class Person {}
会被转换为:

"use strict";

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {

throw new TypeError("Cannot call a class as a function"); 

}
}

var Person = function Person() {
_classCallCheck(this, Person);
};
这里 _classCallCheck 就是一个 helper 函数,如果在很多文件里都声明了类,那么就会产生很多个这样的 helper 函数。

这里的 @babel/runtime 包就声明了所有需要用到的帮助函数,而 @babel/plugin-transform-runtime 的作用就是将所有需要 helper 函数的文件,从 @babel/runtime包 引进来:

"use strict";
var _classCallCheck2 = require("@babel/runtime/helpers/classCallCheck");
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}

var Person = function Person() {
(0, _classCallCheck3.default)(this, Person);
};
这里就没有再编译出 helper 函数 classCallCheck 了,而是直接引用了@babel/runtime 中的 helpers/classCallCheck。

安装
npm i -D @babel/plugin-transform-runtime @babel/runtime使用 在 .babelrc 文件中

"plugins": [

    "@babel/plugin-transform-runtime"

]
7.服务器端渲染
客户端渲染: 获取 HTML 文件,根据需要下载 JavaScript 文件,运行文件,生成 DOM,再渲染。

服务端渲染:服务端返回 HTML 文件,客户端只需解析 HTML。

优点:首屏渲染快,SEO 好。缺点:配置麻烦,增加了服务器的计算压力。

  1. 使用 Defer 加载JS
    尽量将 CSS 放在文件头部,JavaScript 文件放在底部

所有放在 head 标签里的 CSS 和 JS 文件都会堵塞渲染。如果这些 CSS 和 JS 需要加载和解析很久的话,那么页面就空白了。所以 JS 文件要放在底部,等 HTML 解析完了再加载 JS 文件。

那为什么 CSS 文件还要放在头部呢?

因为先加载 HTML 再加载 CSS,会让用户第一时间看到的页面是没有样式的、“丑陋”的,为了避免这种情况发生,就要将 CSS 文件放在头部了。

另外,JS 文件也不是不可以放在头部,只要给 script 标签加上 defer 属性就可以了,异步下载,延迟执行。

  1. 静态资源使用 CDN
    用户与服务器的物理距离对响应时间也有影响。把内容部署在多个地理位置分散的服务器上能让用户更快地载入页面, CDN就是为了解决这一问题,在多个位置部署服务器,让用户离服务器更近,从而缩短请求时间。
  1. 图片优化
    雪碧图

图片可以合并么?当然。最为常用的图片合并场景就是雪碧图(Sprite)。

在网站上通常会有很多小的图标,不经优化的话,最直接的方式就是将这些小图标保存为一个个独立的图片文件,然后通过 CSS 将对应元素的背景图片设置为对应的图标图片。这么做的一个重要问题在于,页面加载时可能会同时请求非常多的小图标图片,这就会受到浏览器并发 HTTP 请求数的限制。

雪碧图的核心原理在于设置不同的背景偏移量,大致包含两点:

不同的图标元素都会将 background-url 设置为合并后的雪碧图的 uri;
不同的图标通过设置对应的 background-position 来展示大图中对应的图标部分。你可以用 Photoshop 这类工具自己制作雪碧图。当然比较推荐的还是将雪碧图的生成集成到前端自动化构建工具中,例如在 webpack 中使用 webpack-spritesmith,或者在 gulp 中使用 gulp.spritesmith。它们两者都是基于 spritesmith 这个库。
图片懒加载
一般来说,我们访问网站页面时,其实很多图片并不在首屏中,如果我们都加载的话,相当于是加载了用户不一定会看到图片, 这显然是一种浪费。解决的核心思路就是懒加载:实现方式就是先不给图片设置路径,当图片出现在浏览器可视区域时才设置真正的图片路径。

实现上就是先将图片路径设置给original-src,当页面不可见时,图片不会加载:


通过监听页面滚动,等页面可见时设置图片src:

const img = document.querySelector('img')
img.src = img.getAttribute("original-src")
如果想使用懒加载,还可以借助一些已有的工具库,例如 aFarkas/lazysizes、verlok/lazyload、tuupola/lazyload 等。

css中图片懒加载
除了对于 元素的图片进行来加载,在 CSS 中使用的图片一样可以懒加载,最常见的场景就是 background-url。

.login {

background-url: url(/static/img/login.png);

}
对于上面这个样式规则,如果不应用到具体的元素,浏览器不会去下载该图片。所以你可以通过切换 className 的方式,放心得进行 CSS 中图片的懒加载。

运行时性能优化

  1. 减少重绘与重排
    有前端经验的开发者对这个概念一定不会陌生,浏览器下载完页面需要的所有资源后, 就开始渲染页面,主要经历这5个过程:

解析HTML生成DOM树
解析CSS生成CSSOM规则树
将DOM树与CSSOM规则树合并生成Render(渲染)树
遍历Render(渲染)树开始布局, 计算每一个节点的位置大小信息
将渲染树每个节点绘制到屏幕上

浏览器渲染过程
重排

当改变DOM元素位置或者大小时, 会导致浏览器重新生成Render树, 这个过程叫重排

重绘

当重新生成渲染树后, 将要将渲染树每个节点绘制到屏幕, 这个过程叫重绘。

重排触发时机

重排发生后的根本原理就是元素的几何属性发生改变, 所以从能够改变几何属性的角度入手:

添加|删除可见的DOM元素
元素位置发生改变
元素本省的尺寸发生改变
内容变化
页面渲染器初始化
浏览器窗口大小发生改变
二者关系:重排会导致重绘, 但是重绘不会导致重排
了解了重排和重绘这两个概念,我们还要知道重排和重绘的开销都是非常昂贵的,如果不停的改变页面的布局,就会造成浏览器消耗大量的开销在进行页面的计算上,这样容易造成页面卡顿。那么回到我们的问题如何减少重绘与重排呢?

1.1 避免table布局
不要使用table布局,可能很小的一个改动会造成整个table重新布局
1.2 分离读写操作
DOM 的多个读操作(或多个写操作),应该放在一起。不要两个读操作之间,加入一个写操作。

// bad 强制刷新 触发四次重排+重绘
div.style.left = div.offsetLeft + 1 + 'px';
div.style.top = div.offsetTop + 1 + 'px';
div.style.right = div.offsetRight + 1 + 'px';
div.style.bottom = div.offsetBottom + 1 + 'px';

// good 缓存布局信息 相当于读写分离 触发一次重排+重绘
var curLeft = div.offsetLeft;
var curTop = div.offsetTop;
var curRight = div.offsetRight;
var curBottom = div.offsetBottom;

div.style.left = curLeft + 1 + 'px';
div.style.top = curTop + 1 + 'px';
div.style.right = curRight + 1 + 'px';
div.style.bottom = curBottom + 1 + 'px';
1.3 样式集中改变
不要频发的操作样式,虽然现在大部分浏览器有渲染队列优化,但是在一些老版本的浏览器仍然存在效率低下的问题:

// 三次重排
div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';

// 一次重排
el.style.cssText = 'left: 10px;top: 10px; width: 20px';
或者可以采用更改类名而不是修改样式的方式。

1.4 position属性为absolute或fixed
使用绝对定位会使的该元素单独成为渲染树中 body 的一个子元素,重排开销比较小,不会对其它节点造成太多影响。当你在这些节点上放置这个元素时,一些其它在这个区域内的节点可能需要重绘,但是不需要重排。

  1. 避免页面卡顿
    我们目前大多数屏幕的刷新率-60次/s,浏览器渲染更新页面的标准帧率也为60次/s --60FPS(frames/pre second), 那么每一帧的预算时间约为16.6ms ≈ 1s/60,浏览器在这个时间内要完成所有的整理工作,如果无法符合此预算, 帧率将下降,内容会在屏幕抖动, 此现象通常称为卡顿。

浏览器需要做的工作包含下面这个流程:

首先你用js做了些逻辑,还触发了样式变化,style把应用的样式规则计算好之后,把影响到的页面元素进行重新布局,叫做layout,再把它画到内存的一个画布里面,paint成了像素,最后把这个画布刷到屏幕上去,叫做composite,形成一帧。

这几项的任何一项如果执行时间太长了,就会导致渲染这一帧的时间太长,平均帧率就会掉。假设这一帧花了50ms,那么此时的帧率就为1s / 50ms = 20fps.

当然上面的过程并不一定每一步都会执行,例如:

你的js只是做一些运算,并没有增删DOM或改变CSS,那么后续几步就不会执行
style只改了颜色等不需要重新layout的属性就不用执行layout这一步
style改了transform属性,在blink和edge浏览器里面不需要layout和paint

  1. 长列表优化
    有时会有这样的需求, 需要在页面上展示包含上百个元素的列表(例如一个Feed流)。每个列表元素还有着复杂的内部结构,这显然提高了页面渲染的成本。当你使用了React时,长列表的问题就会被进一步的放大。那么怎么来优化长列表呢?

1.1 实现虚拟列表
虚拟列表是一种用来优化长列表的技术。它可以保证在列表元素不断增加,或者列表元素很多的情况下,依然拥有很好的滚动、浏览性能。它的核心思想在于:只渲染可见区域附近的列表元素。下图左边就是虚拟列表的效果,可以看到只有视口内和临近视口的上下区域内的元素会被渲染。

具体实现步骤如下所示:

首先确定长列表所在父元素的大小,父元素的大小决定了可视区的宽和高
确定长列表每一个列表元素的宽和高,同时初始的条件下计算好长列表每一个元素相对于父元素的位置,并用一个数组来保存所有列表元素的位置信息
首次渲染时,只展示相对于父元素可视区内的子列表元素,在滚动时,根据父元素的滚动的offset重新计算应该在可视区内的子列表元素。这样保证了无论如何滚动,真实渲染出的dom节点只有可视区内的列表元素。
假设可视区内能展示5个子列表元素,及时长列表总共有1000个元素,但是每时每刻,真实渲染出来的dom节点只有5个。
补充说明,这种情况下,父元素一般使用position:relative,子元素的定位一般使用:position:absolute或sticky
除了自己实现外, 常用的框架也有不错的开源实现, 例如:

基于React的 react-virtualized
基于Vue 的 vue-virtual-scroll-list
基于Angular的 ngx-virtual-scroller

  1. 滚动事件性能优化
    前端最容易碰到的性能问题的场景之一就是监听滚动事件并进行相应的操作。由于滚动事件发生非常频繁,所以频繁地执行监听回调就容易造成JavaScript执行与页面渲染之间互相阻塞的情况。

对应滚动这个场景,可以采用防抖和节流来处理。

当一个事件频繁触发,而我们希望间隔一定的时间再触发相应的函数时, 就可以使用节流(throttle)来处理。比如判断页面是否滚动到底部,然后展示相应的内容;就可以使用节流,在滚动时每300ms进行一次计算判断是否滚动到底部的逻辑,而不用无时无刻地计算。

当一个事件频繁触发,而我们希望在事件触发结束一段时间后(此段时间内不再有触发)才实际触发响应函数时会使用防抖(debounce)。例如用户一直点击按钮,但你不希望频繁发送请求,你就可以设置当点击后 200ms 内用户不再点击时才发送请求。

  1. 使用 Web Workers
    前面提到了大量数据的渲染环节我们可以采用虚拟列表的方式实现,但是大量数据的计算环节依然会产生浏览器假死或者卡顿的情况.

通常情况下我们CPU密集型的任务都是交给后端计算的,但是有些时候我们需要处理一些离线场景或者解放后端压力,这个时候此方法就不奏效了.

还有一种方法是计算切片,使用 setTimeout 拆分密集型任务,但是有些计算无法利用此方法拆解,同时还可能产生副作用,这个方法需要视具体场景而动.

最后一种方法也是目前比较奏效的方法就是利用Web Worker 进行多线程编程.

Web Worker 是一个独立的线程(独立的执行环境),这就意味着它可以完全和 UI 线程(主线程)并行的执行 js 代码,从而不会阻塞 UI,它和主线程是通过 onmessage 和 postMessage 接口进行通信的。

Web Worker 使得网页中进行多线程编程成为可能。当主线程在处理界面事件时,worker 可以在后台运行,帮你处理大量的数据计算,当计算完成,将计算结果返回给主线程,由主线程更新 DOM 元素。

  1. 写代码时的优化点
    提升性能,有时候在我们写代码时注意一些细节也是有效果的。

6.1 使用事件委托
看一下下面这段代码:

  • 字节跳动
  • 阿里
  • 腾讯
  • 京东

// good
document.querySelector('ul').onclick = (event) => {
const target = event.target
if (target.nodeName === 'LI') {

console.log(target.innerHTML) 

}
}

// bad
document.querySelectorAll('li').forEach((e) => {
e.onclick = function() {

console.log(this.innerHTML) 

}
})
绑定的事件越多, 浏览器内存占有就越多,从而影响性能,利用事件代理的方式就可节省一些内存。

6.2 if-else 对比 switch
当判定条件越来越多时, 越倾向于使用switch,而不是if-else:

if (state ==0) {

console.log("待开通")

} else if (state == 1) {

console.log("学习中")

} else if (state == 2) {

console.log("休学中")

} else if (state == 3) {

console.log("已过期")

} esle if (state ==4){

console.log("未购买")

}

switch (state) {

case 0:

    break
case 1:

    break
case 2:

    break
case 3:

    break
case 4:

    break

}
向上面这种情况使用switch更好, 假设state为4,那么if-else语句就要进行4次判定,switch只要进行一次即可。

但是有的情况下switch也做不到if-else的事情, 例如有多个判断条件的情况下,无法使用switch

6.3 布局上使用flexbox
在早期的 CSS 布局方式中我们能对元素实行绝对定位、相对定位或浮动定位。而现在,我们有了新的布局方式 flexbox,它比起早期的布局方式来说有个优势,那就是性能比较好。

1、css sprite是什么,有什么优缺点
概念:将多个小图片拼接到⼀个图片中 。通过 background-position 和元素尺寸调节需要显示的背景图案。

优点: 缺点:
减少 HTTP 请求数,极大地提高页面加载速度
增加图片信息重复度,提高压缩比,减少图片大小
更换⻛格⽅便, 只需在⼀张或⼏张图片上修改颜色或样式即可实现 图片合并麻烦
维护麻烦,修改⼀个图片可能需要从新布局整个图片,样式
2、display: none; 与 visibility: hidden; 的区别
联系:它们都能让元素不可见

区别:

display:none ;会让元素完全从渲染树中消失, 渲染的时候不占据任何空间;
visibility: hidden ;不会让元素从渲染树消失, 渲染师元素继续占据空间, 只是内容不可⻅
display: none ;是⾮继承属性, ⼦孙节点消失由于元素从渲染树消失造成, 通过修改⼦孙节点属性⽆法显示 ;visibility: hidden; 是继承属性, ⼦孙节点消失由于继承了 hidden , 通过设置 visibility: visible; 可以让⼦孙节点显式
修改常规流中元素的 display 通常会造成⽂档重排 。修改 visibility 属性只会造成本元素的重绘。
读屏器不会读取 display: none ;元素内容;会读取 visibility: hidden; 元素内容
3、link 与 @import 的区别
link 是 HTML ⽅式, @import 是CSS⽅式
link 最大限度⽀持并⾏下载, @import 过多嵌套导致串⾏下载, 出现 FOUC (⽂档样式短暂失效)
link 可以通过 rel="alternate stylesheet" 指定候选样式
浏览器对 link ⽀持早于 @import , 可以使用 @import 对老浏览器隐藏样式
@import 必须在样式规则之前, 可以在css⽂件中引用其他⽂件
总体来说: link 优于 @import
4、什么是FOUC?如何避免
Flash Of Unstyled Content :用户定义样式表加载之前浏览器使用默认样式显示⽂档,用户样式加载渲染之后再从新显示⽂档, 造成⻚⾯闪烁。

解决方法:把样式表放到⽂档的 <head>

5、如何创建块级格式化上下文(block formatting context),BFC有什么用
创建规则:

根元素
浮动元素 ( float 不取值为 none )
绝对定位元素 ( position 取值为 absolute 或 fixed,display 取值为 inline-block 、 table-cell 、 table-caption 、 flex 、inline-flex 之⼀的元素 ,overflow 不取值为 visible 的元素 )
作用:

可以包含浮动元素
不被浮动元素覆盖
阻止父子元素的 margin 折叠
6、display 、float 、position的关系

如果 display 取值为 none ,那么 position 和 float 都不起作用, 这种情况下元素不产生框
否则, 如果 position 取值为 absolute 或者 fixed ,框就是绝对定位的, float 的计算值为 none , display 根据下面的表格进行调整。
否则, 如果 float 不是 none ,框是浮动的, display 根据下表进行调整
否则, 如果元素是根元素, display 根据下表进行调整
其他情况下 display 的值为指定值
总结起来:绝对定位、浮动、根元素都需要调整 display
7 清除浮动的几种方式,各自的优缺点
父级 div 定义 height
结尾处加空 div 标签 clear:both
父级 div 定义伪类 :after 和 zoom
父级 div 定义 overflow:hidden
父级 div 也浮动, 需要定义宽度
结尾处加 br 标签 clear:both
比较好的是第3种方式, 好多网站都这么用
8、为什么要初始化CSS样式?
因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的, 如果没对 CSS 初始化往往会出现浏览器之间的页面显示差异。
当然,初始化样式会对 SEO 有⼀定的影响,但鱼和熊掌不可兼得,但⼒求影响最⼩的情况下初始化。
9、css3有哪些新特性
新增各种 css 选择器
圆角 border-radius
多列布局
阴影和反射
文字特效 text-shadow
线性渐变
旋转 transform
10、display有哪些值?说明他们的作用
block 转换成块状元素。
inline 转换成行内元素。
none 设置元素不可见。
inline-block 象行内元素⼀样显示,但其内容象块类型元素⼀样显示。
list-item 象块类型元素⼀样显示, 并添加样式列表标记。
table 此元素会作为块级表格来显示
inherit 规定应该从父元素继承 display 属性的值
11、介绍⼀下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的?
有两种, IE 盒子模型 、 W3C 盒子模型;
盒模型: 内容(content)、填充( padding )、边界( margin )、 边框( border );
区 别: IE 的c ontent 部分把 border 和 padding 计算了进去;
12、CSS优先级算法如何计算?
优先级就近原则, 同权重情况下样式定义最近者为准
载⼊样式以最后载⼊的定位为准
优先级为: !important > id > class > tag ; !important 比 内联优先级高
13、CSS3新增伪类有那些?
p:first-of-type 选择属于其父元素的首个 <p> 元素的每个 <p> 元素。
p:last-of-type 选择属于其父元素的最后 <p> 元素的每个 <p> 元素。
p:only-of-type 选择属于其父元素唯⼀的 <p> 元素的每个 <p> 元素。
p:only-child 选择属于其父元素的唯⼀⼦元素的每个 <p> 元素。
p:nth-child(2) 选择属于其父元素的第⼆个⼦元素的每个 <p> 元素。
:after 在元素之前添加内容,也可以用来做清除浮动。
:before 在元素之后添加内容。
:enabled 已启用的表单元素。
:disabled 已禁用的表单元素。
:checked 单选框或复选框被选中。
14、谈谈浮动和清除浮动
浮动的框可以向左或向右移动, 直到他的外边缘碰到包含框或另⼀个浮动框的边框为止。

由于浮动框不在文档的普通流中,所以文档的普通流的块框表现得就像浮动框不存在⼀样 。浮动的块框会漂浮在文档普通流的块框上。

15、position的值, relative和absolute定位原点是?
absolute :生成绝对定位的元素,相对于 static 定位以外的第⼀个父元素进行定位
fixed :生成绝对定位的元素,相对于浏览器窗⼝进行定位
relative :生成相对定位的元素,相对于其正常位置进行定位
static 默认值 。没有定位,元素出现在正常的流中
inherit 规定从父元素继承 position 属性的值
16、display:inline-block 什么时候不会显示间隙? (携程)
移除空格
使用 margin 负值
使用 font-size:0 letter-spacing word-spacing
17、PNGGIFJPG的区别及如何选
GIF

8 位像素, 256 色
无损压缩
支持简单动画
支持 boolean 透明
适合简单动画
JPEG

颜色限于 256
有损压缩
可控制压缩质量
不支持透明
适合照片
PNG

有 PNG8 和 truecolor PNG
PNG8 类似 GIF 颜色上限为 256 ,文件小, 支持 alpha 透明度, 无动画
适合图标 、背景 、按钮
18、行内元素float:left后是否变为块级元素?
行内元素设置成浮动之后变得更加像是 inline-block (行内块级元素,设置成这个属性的元素会同时拥有行内和块级的特性, 最明显的不同是它的默认宽度不是 100% ), 这时候给行内元素设置 padding-top 和 padding-bottom或者 width 、 height 都是有效果的。

19、在网页中的应该使用奇数还是偶数的字体?为什么呢?
偶数字号相对更容易和 web 设计的其他部分构成比例关系

20 ::before 和 :after中双冒号和单冒号 有什么区别?解释⼀下这2个伪元素的作用
单冒号( : )用于 CSS3 伪类,双冒号( :: )用于 CSS3 伪元素
用于区分伪类和伪元素
21、如果需要手动写动画,你认为最小时间间隔是多久, 为什么? ( 阿里)
多数显示器默认频率是 60Hz , 即 1 秒刷新 60 次,所以理论上最小间隔为1/60*1000ms = 16.7ms

22、CSS合并方法
避免使用 @import 引⼊多个 css 文件, 可以使用 CSS 工具将 CSS 合并为⼀个 CSS 文件,例如使用 SassCompass 等

23、CSS不同选择器的权重(CSS层叠的规则)

! important 规则最重要,大于其它规则
行内样式规则,加 1000
对于选择器中给定的各个 ID 属性值,加 100
对于选择器中给定的各个类属性 、属性选择器或者伪类选择器,加 10
对于选择其中给定的各个元素标签选择器,加1
如果权值⼀样,则按照样式规则的先后顺序来应用,顺序靠后的覆盖靠前的规则
24、列出你所知道可以改变页面布局的属性
position 、 display 、 float 、 width 、 height 、top 、 left 、 right 、、
25、CSS在性能优化方面的实践
css 压缩与合并 、 Gzip 压缩
css 文件放在 head 里 、不要用 @import
尽量用缩写 、避免用滤镜 、合理使用选择器
26、CSS3动画 ( 简单动画的实现, 如旋转等)
依靠 CSS3 中提出的三个属性: transition 、 transform 、 animation

transition :定义了元素在变化过程中是怎么样的, 包含 transition-property 、transition-duration 、 transition-timing-function 、 transition-delay 。
transform :定义元素的变化结果, 包含 rotate 、 scale 、 skew 、 translate 。
animation :动画定义了动作的每⼀帧 ( @keyframes ) 有什么效果, 包括 animation-name , animation-duration 、 animation-timing-function 、 animation-delay 、 animation-iteration-count 、 animation-direction
27、base64的原理及优缺点
优点可以加密,减少了 HTTTP 请求
缺点是需要消耗 CPU 进行编解码
28、几种常见的CSS布局
流体布局
.left {

float: left;
width: 100px;
height: 200px;
background: red;

}
.right {

float: right;
width: 200px;
height: 200px;
background: blue;

}
.main {

margin-left: 120px;
margin-right: 220px;
height: 200px;
background: green;

}

< div class= "container" >

<div class="left"></div>
<div class="right"></div>
<div class="main"></div>

</div>
圣杯布局
.container {

margin-left: 120px;
margin-right: 220px;

}
.main {

float: left;
width: 100%;
height:300px;
background: green;

}
.left {

position: relative;
left: -120px;
float: left;
height: 300px;
width: 100px;
margin-left: -100%;
background: red;

}
.right {

position: relative;
right: -220px;
float: right;
height: 300px;
width: 200px;
margin-left: -200px;
background: blue;

}
<div class="container">

<div class="main"></div>
<div class="left"></div>
<div class="right"></div>

</div>
双飞翼布局
.content {

float: left;
width: 100%;

}
.main {

height: 200px;
margin-left: 110px;
margin-right: 220px;
background: green;

}
.main::after {

content: '';
display: block;
font-size:0;
height: 0;
zoom: 1;
clear: both;

}
.left {

float:left;
height: 200px;
width: 100px;
margin-left: -100%;
background: red;

}
.right {

float: right;
height: 200px;
width: 200px;
margin-left: -200px;
background: blue;

}
<div class="content">

<div class="main"></div>

</div>
<div class="left"></div>
<div class="right"></div>
29、stylus/sass/less区别
均具有“变量”、“混合”、“嵌套”、“继承”、“颜色混合”五大基本特性
Scss 和 LESS 语法较为严谨, LESS 要求⼀定要使用大括号“{}”, Scss 和 Stylus 可 以通过缩进表示层次与嵌套关系
Scss 无全局变量的概念, LESS 和 Stylus 有类似于其它语⾔的作用域概念
Sass 是基于 Ruby 语⾔的, 而 LESS 和 Stylus 可以基于 NodeJS NPM 下载相应库后进⾏编译;
30、postcss的作用
可以直观的理解为:它就是⼀个平台 。为什么说它是⼀个平台呢? 因为我们直接用它, 感觉不能⼲什么事情,但是如果让⼀些插件在它上面跑,那么将会很强大
PostCSS 提供了⼀个解析器, 它能够将 CSS 解析成抽象语法树
通过在 PostCSS 这个平台上, 我们能够开发⼀些插件,来处理我们的 CSS , 比如热门的: autoprefixer
postcss 可以对sass处理过后的 css 再处理 最常⻅的就是 autoprefixer
31、css样式 ( 选择器) 的优先级
计算权重确定
!important
内联样式
后写的优先级高
32、自定义字体的使用场景
宣传/品牌/ banner 等固定文案
字体图标
33、如何美化CheckBox
<label> 属性 for 和 id
隐藏原生的 <input>
:checked + <label>
34、伪类和伪元素的区别
伪类表状态
伪元素是真的有元素
前者单冒号,后者双冒号
35、base64 的使用
用于减少 HTTP 请求
适用于小图片
base64 的体积约为原图的 4/3
36、自适应布局
左侧浮动或者绝对定位,然后右侧 margin 撑开
使用 <div> 包含,然后靠负 margin 形成 bfc
使用 flex
37、请用CSS写⼀个简单的幻灯片效果页面
/css/ .ani{

width:480px;
height:320px;
margin:50px auto;
overflow: hidden;
box-shadow:0 0 5px rgba(0,0,0,1);
background-size: cover;
background-position: center;
-webkit-animation-name: "loops";
-webkit-animation-duration: 20s;
-webkit-animation-iteration-count: infinite;

}
@-webkit-keyframes "loops" {
0% {

  background:url(http://d.hiphotos.baidu.com/image/w%3D400/sign=c01e6

}
25% {

  background:url(http://b.hiphotos.baidu.com/image/w%3D400/sign=edee1

}
50% {

  background:url(http://b.hiphotos.baidu.com/image/w%3D400/sign=937da

}
75% {

  background:url(http://g.hiphotos.baidu.com/image/w%3D400/sign=7d375

}
100% {

  background:url(http://c.hiphotos.baidu.com/image/w%3D400/sign=cfb23

}
}
38、什么是外边距重叠?重叠的结果是什么?
外边距重叠就是margin-collapse

在CSS当中,相邻的两个盒子 ( 可能是兄弟关系也可能是祖先关系) 的外边距可以结合成⼀个单独的外边距 。这种合并外边距的方式被称为折叠, 并且因而所结合成的外边距称为折叠外边距。

折叠结果遵循下列计算规则:

两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
两个外边距⼀正⼀负时,折叠结果是两者的相加的和。
39、rgba()和opacity的透明效果有什么不同?
rgba() 和 opacity 都能实现透明效果,但最大的不同是 opacity 作用于元素, 以及元素内的所有内容的透明度,

而 rgba() 只作用于元素的颜色或其背景色 。 ( 设置 rgba 透明的元素的子元素不会继承透明效果!)

40、css中可以让文字在垂直和水平方向上重叠的两个属性是什么?
垂直方向: line-height
水平方向: letter-spacing
41、如何垂直居中⼀个浮动元素?
/方法⼀: 已知元素的高宽/

div1{

background-color:#6699FF;
width:200px;
height:200px;
position: absolute; //父元素需要相对定位
top: 50%;
left: 50%;
margin-top:-100px ; //二分之⼀的height,width
margin-left: -100px;

}
/方法二:/

div1{

width: 200px;
height: 200px;
background-color: #6699FF;
margin:auto;
position: absolute; //父元素需要相对定位
left: 0;
top: 0;
right: 0;
bottom: 0;

}
如何垂直居中⼀个 ? (用更简便的方法。)

container /的容器设置如下/

{

display:table-cell;
text-align:center;
vertical-align:middle;

}
42、px和em的区别
px 和 em 都是长度单位, 区别是, px 的值是固定的,指定是多少就是多少,计算比较容易 。 em 得值不是固定的, 并且 em 会继承父级元素的字体大小 。
浏览器的默认字体高都是 16px 。所以未经调整的浏览器都符合: 1em=16px 。那么12px=0.75em,10px=0.625em 。
43、Sass 、LESS是什么?大家为什么要使用他们?
他们是 CSS 预处理器 。他是 CSS 上的⼀种抽象层 。他们是⼀种特殊的语法/语⾔编译成CSS 。

例如Less是⼀种动态样式语⾔ . 将CSS赋予了动态语⾔的特性, 如变量, 继承, 运算, 函数. LESS 既可以在客户端上运⾏ (支持 IE 6+ , Webkit , Firefox ),也可⼀在服务端运⾏ (借助 Node.js )
为什么要使用它们?

结构清晰,便于扩展。可以方便地屏蔽浏览器私有语法差异 。这个不用多说, 封装对- 浏览器语法差异的重复处理,减少无意义的机械劳动。可以轻松实现多重继承。完全兼容 CSS 代码, 可以方便地应用到老项目中 。LESS 只- 是在 CSS 语法上做了扩展,所以老的 CSS 代码也可以与 LESS 代码⼀同编译。
44、知道css有个content属性吗?有什么作用?有什么应用?

css的 content 属性专门应用在 before/after 伪元素上, 用于来插⼊生成内容 。最常⻅的应用是利用伪类清除浮动。

/⼀种常⻅利用伪类清除浮动的代码/
.clearfix:after {

content:"."; //这里利用到了content属性
display:block;
height:0;
visibility:hidden;
clear:both;

}
.clearfix {

*zoom:1;

}
45、水平居中的方法
元素为行内元素,设置父元素 text-align:center
如果元素宽度固定, 可以设置左右 margin 为 auto ;
如果元素为绝对定位,设置父元素 position 为 relative ,元素设left:0;right:0;margin:auto;
使用 flex-box 布局,指定 justify-content 属性为center
display 设置为 tabel-ceil
46、垂直居中的方法
将显示方式设置为表格, display:table-cell ,同时设置 vertial-align:middle使用 flex 布局,设置为 align-item: center
绝对定位中设置 bottom:0,top:0 ,并设置 margin:auto
绝对定位中固定高度时设置 top:50%,margin-top 值为高度⼀半的负值
文本垂直居中设置 line-height 为 height 值
47、如何使用CSS实现硬件加速?
硬件加速是指通过创建独立的复合图层,让GPU来渲染这个图层,从而提高性能,

⼀般触发硬件加速的 CSS 属性有 transform 、 opacity 、 filter , 为了避免2D动画在开始和结束的时候的 repaint 操作,⼀ 般使用 tranform:translateZ(0)。

48、重绘和回流 ( 重排) 是什么, 如何避免?
DOM的变化影响到了元素的⼏何属性 ( 宽高) ,浏览器重新计算元素的⼏何属性, 其他元素的⼏何属性和位置也会受到影响, 浏览器需要重新构造渲染树, 这个过程称为重排, 浏览器将受到影响的部分重新绘制到屏幕上的过程称为重绘 。引起重排的原因有:

添加或者删除可见的DOM元素,
元素位置 、尺⼨ 、内容改变,
浏览器页面初始化
浏览器窗⼝尺⼨改变, 重排⼀定重绘, 重绘不⼀定重排
减少重绘和重排的方法:

不在布局信息改变时做 DOM 查询
使用 cssText 或者 className ⼀次性改变属性
使用 fragment
对于多次重排的元素, 如动画,使用绝对定位脱离文档流,让他的改变不影响到其他元素
49、说⼀说css3的animation
css3的 animation 是css3新增的动画属性, 这个css3动画的每⼀帧是通过 @keyframes来声明的, keyframes 声明了动画的名称, 通过 from 、 to 或者是百分比来定义。

每⼀帧动画元素的状态, 通过 animation-name 来引用这个动画, 同时css3动画也可以定义动画运行的时长 、动画开始时间 、动画播放方向 、动画循环次数 、动画播放的方式。

这些相关的动画⼦属性有: animation-name 定义动画名 、 animation-duration 定义动画播放的时长 、 animation-delay 定义动画延迟播放的时间 、 animation-direction 定义 动画的播放方向 、 animation-iteration-count 定义播放次数 、animation-fill-mode 定义动画播放之后的状态 、 animation-play-state 定义播放状态, 如暂停运行等 、 animation-timing-function

定义播放的方式, 如恒速播放 、艰涩播放等。

50、左边宽度固定,右边自适应
左侧固定宽度,右侧自适应宽度的两列布局实现

html结构

< div class= " outer" >

<div class="left">固定宽度</div>
<div class="right">自适应宽度</div>

</div>
在外层 div ( 类名为 outer ) 的 div 中,有两个⼦ div , 类名分别为left 和 right , 其中 left 为固定宽度, 而 right 为自适应宽度。

方法1:左侧div设置成浮动:float: left,右侧div宽度会自拉升适应

.outer {

width: 100%;
height: 500px;
background-color:yellow;

}
.left {

width: 200px;
height: 200px;

background-color: red;

float: left;

}
.right {
height: 200px;
background-color: blue;
}
方法2:对右侧:div进行绝对定位,然后再设置right=0,即可以实现宽度自适应

绝对定位元素的第⼀个高级特性就是其具有自动伸缩的功能, 当我们将width 设置为 auto 的时候 ( 或者不设置, 默认为 auto ), 绝对定位元素会根据其 left 和 right 自动伸缩其大小。
.outer {
width: 100%;
height: 500px;
background-color: yellow;
position: relative;
}
.left {
width: 200px;
height: 200px;
background-color: red;
}
.right {
height: 200px;
background-color: blue;
position: absolute;
left: 200px;
top:0;
right: 0;
}
方法3:将左侧div进行绝对定位,然后右侧div设置margin-left: 200px

.outer {
width: 100%;
height: 500px;
background-color: yellow;
position: relative;
}
.left {
width: 200px;
height: 200px;
background-color: red;
position: absolute;
}
.right {
height: 200px;
background-color: blue;
margin-left: 200px;
}
方法4:使用flex布局

.outer {
width: 100%;
height: 500px;
background-color: yellow;
display: flex;
flex-direction: row;
}
.left {
width: 200px;
height: 200px;
background-color: red;
}
.right {
height: 200px;
background-color: blue;
flex: 1;
}
51、两种以上方式实现已知或者未知宽度的垂直水平居中
/ 1 /
.wraper {
position: relative;
.box {

  position: absolute;
  top: 50%;
  left: 50%;
  width: 100px;
  height: 100px;
  margin: -50px 0 0 -50px;

}
}
/ 2 /
.wraper {
position: relative;
.box {

  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);

}
}
/ 3 /
.wraper {
.box {

  display: flex;
  justify-content:center;
  align-items: center;
  height: 100px;

}
}
/ 4 /
.wraper {
display: table;
.box {

  display: table-cell;
  vertical-align: middle;

}
}
52、如何实现小于12px的字体效果
transform:scale() 这个属性只可以缩放可以定义宽高的元素, 而⾏内元素是没有宽高的, 我们可以加上⼀个 display:inline-block ;

transform: scale(0.7);
css 的属性, 可以缩放大小。

1、前端需要注意哪些SEO
(1)合理的 title 、description 、keywords :搜索对着三项的权重逐个减小,title 值强调重点即可,重要关键词出现不要超过2次, 而且要靠前,不同页面 title 要有所不同; description 把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面description 有所不同; keywords 列举出重要关键词即可。
(2)语义化的 HTML 代码,符合W3C规范:语义化代码让搜索引擎容易理解网页。
(3)重要内容 HTML 代码放在最前:搜索引擎抓取 HTML 顺序是从上到下, 有的搜索引擎对抓取长度有限制,保证重要内容⼀定会被抓取 。
(4)重要内容不要用 js 输出:爬虫不会执行js获取内容。
(5)少用 iframe :搜索引擎不会抓取 iframe 中的内容 。
(6)非装饰性图片必须加 alt 。
(7)提高网站速度: 网站速度是搜索引擎排序的⼀个重要指标。

2、img标签的 title 和 alt 有什么区别
(1)通常当鼠标滑动到元素上的时候显示 。
(2)alt 是 的特有属性,是图片内容的等价描述,用于图片五法加载时显示、读屏器阅读图片 。可提图片高可访问性, 除了纯装饰图片外都必须设置有意义的值, 搜索引擎会重点分析。

3、HTTP的几种请求方法用途
(1)GET 方法
发送⼀个请求来取得服务器上的某⼀资源 。

(2)POST 方法
向 URL 指定的资源提交数据或附加新的数据 。

(3)PUT 方法
跟 POST 方法很像,也是想服务器提交数据 。但是, 它们之间有不同 。 PUT 指定了资源在服务器上的位置, 而 POST 没有。

(4)HEAD 方法
只请求页面的首部 。

(5)DELETE 方法
删除服务器上的某资源 。

(6)OPTIONS 方法
它用于获取当前 URL 所⽀持的方法 。如果请求成功,会有⼀个 Allow 的头包含类似 “GET,POST” 这样的信息。

(7)TRACE 方法
TRACE ⽅法被用于激发⼀个远程的,应用层的请求消息回路 。

(8)CONNECT 方法
把请求连接转换到透明的 TCP/IP 通道。

4、从浏览器地址栏输入url到显示页面的步骤
基础版:

(1)浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP , 向服务器发起请求;
(2)服务器交给后台处理完成后返回数据, 浏览器接收⽂件 ( HTML、JS、CSS 、图象等);
(3)浏览器对加载到的资源 ( HTML、JS、CSS 等) 进行语法解析, 建立相应的内部数据结构 ( 如 HTML 的 DOM );
(4)载入解析到的资源⽂件,渲染页面,完成。

详细版

  1. 在浏览器地址栏输⼊URL
  2. 浏览器查看缓存, 如果请求资源在缓存中并且新鲜,跳转到转码步骤:
    (1)如果资源未缓存,发起新请求 ;

(2)如果已缓存,检验是否足够新鲜, 足够新鲜直接提供给客户端, 否则与服务器进行验证。
(3)检验新鲜通常有两个HTTP头进行控制 Expires 和 Cache-Control :
1)HTTP1.0提供Expires,值为⼀个绝对时间表示缓存新鲜⽇期 ;
2)HTTP1.1增加了Cache-Control: max-age=,值为以秒为单位的最大新鲜时间;

  1. 浏览器解析URL获取协议, 主机,端口 , path
  2. 浏览器组装⼀个HTTP ( GET) 请求报文
  3. 浏览器获取主机ip地址, 过程如下:
    (1) 浏览器缓存

(2)本机缓存
(3)hosts文件
(4)路由器缓存
(5)ISP DNS缓存
(6)DNS递归查询 ( 可能存在负载均衡导致每次IP不⼀样)

  1. 打开⼀个socket与目标IP地址,端口建立TCP链接,三次握手如下:
    (1)客户端发送⼀个TCP的SYN=1,Seq=X的包到服务器端口。

(2)服务器发回SYN=1, ACK=X+1, Seq=Y的响应包。
(3)客户端发送ACK=Y+1, Seq=Z

  1. TCP链接建立后发送HTTP请求
  2. 服务器接受请求并解析,将请求转发到服务程序, 如虚拟主机使用工TTP 工ost头部判断请求的服务程序
  3. 服务器检查HTTP请求头是否包含缓存验证信息如果验证缓存新鲜, 返回304等对应状态码
  4. 处理程序读取完整请求并准备工TTP响应, 可能需要查询数据库等操作
  5. 服务器将响应报文通过TCP连接发送回浏览器
  6. 浏览器接收工TTP响应,然后根据情况选择关闭TCP连接或者保留重用,关闭TCP连接的四次握手如下:
    (1)主动方发送Fin=1, Ack=Z, Seq= X报文

(2)被动方发送ACK=X+1, Seq=Z报文
(3)被动方发送Fin=1, ACK=X, Seq=Y报文
(4)主动方发送ACK=Y, Seq=X报文

  1. 浏览器检查响应状态吗:是否为1XX, 3XX, 4XX, 5XX, 这些情况处理与2XX不同
  2. 如果资源可缓存, 进行缓存
  3. 对响应进行解码 (例如gzip压缩)
  4. 根据资源类型决定如何处理 (假设资源为工TML文档)
  5. 解析HTML文档,构件DOM树,下载资源,构造CSSOM树,执行js脚本, 这些操作没有严格的先后顺序, 以下分别解释。
  6. 构建DOM树:
    (1) Tokenizing:根据工TML规范将字符流解析为标记。

(2) Lexing:词法分析将标记转换为对象并定义属性和规则。
(3) DOM construction:根据工TML标记关系将对象组成DOM树

  1. 解析过程中遇到图片 、样式表 、js文件,启动下载
  2. 构建CSSOM树:
    (1) Tokenizing:字符流转换为标记流

(2) Node:根据标记创建节点
(3) CSSOM:节点创建CSSOM树

  1. 根据DOM树和CSSOM树构建渲染树 :
    (1) 从DOM树的根节点遍历所有可见节点,不可见节点包括:

1) script , meta 这样本身不可见的标签 。
2) 被css隐藏的节点, 如 display: none
(2)对每⼀个可⻅节点,找到恰当的CSSOM规则并应用
(3)发布可视节点的内容和计算样式

  1. js解析如下:
    (1)浏览器创建Document对象并解析HTML,将解析到的元素和文本节点添加到文档中,此时document.readystate为loading。

(2)HTML解析器遇到没有async和defer的script时,将他们添加到文档中,然后执行行内或外部脚本 。这些脚本会同步执行, 并且在脚本下载和执⾏时解析器会暂停 。这样就可以用document.write()把文本插⼊到输⼊流中 。同步脚本经常简单定义函数和注册事件处理程序,他们可以遍历和操作script和他们之前的文档内容。
(3)当解析器遇到设置了async属性的script时, 开始下载脚本并继续解析文档 。脚本会在它下载完成后尽快执行,但是解析器不会停下来等它下载 。异步脚本禁止使用document.write(), 它们可以访问自⼰script和之前的文档元素。
(4)当文档完成解析,document.readState变成interactive。
(5)所有defer脚本会按照在文档出现的顺序执行,延迟脚本能访问完整文档树, 禁止使用document.write。
(6)浏览器在Document对象上触发DOMContentLoaded事件。
(7) 此时文档完全解析完成, 浏览器可能还在等待如图片等内容加载, 等这些内容完成载入并且所有异步脚本完成载入和执行,document.readState变为complete,window触发load事件。

  1. 显示页面 ( HTML解析过程中会逐步显示页面)

详细简版

  1. 从浏览器接收 url 到开启⽹络请求线程 ( 这⼀部分可以展开浏览器的机制以及进程与线程之间的关系) 。
  2. 开启⽹络线程到发出⼀个完整的 HTTP 请求 ( 这⼀部分涉及到dns查询, TCP/IP 请求,五层因特⽹协议栈等知识) 。
  3. 从服务器接收到请求到对应后台接收到请求 ( 这⼀部分可能涉及到负载均衡, 安全拦截以及后台内部的处理等等) 。
  4. 后台和前台的 HTTP 交互 ( 这⼀部分包括 HTTP 头部 、响应码 、报文结构 、cookie 等知识, 可以提下静态资源的 cookie 优化,以及编码解码,如 gzip压缩等)。
    5.单独拎出来的缓存问题,HTTP 的缓存 ( 这部分包括http缓存头部,ETag ,catch control等) 。
  5. 浏览器接收到 HTTP 数据包后的解析流程 ( 解析 html -词法分析然后解析成 dom 树 、解析 css 生成 css 规则树、合并成 render 树,然后layout、painting渲染、复合图层的合成、GPU 绘制、外链资源的处理 、 loaded 和 DOMContentLoaded等) 。
  6. CSS 的可视化格式模型 ( 元素的渲染规则, 如包含块,控制框, BFC , IFC 等概念) 。
  7. JS 引擎解析过程 ( JS 的解释阶段,预处理阶段,执⾏阶段生成执⾏上下文, VO ,作用域链 、回收机制等等)。
  8. 其它 ( 可以拓展不同的知识模块, 如跨域,web安全, hybrid 模式等等内容)

5、如何进行网站性能优化
(1)content 方面
减少 HTTP 请求:合并文件 、 CSS 精灵 、 inline Image。减少 DNS 查询: DNS 缓存 、将资源分布到恰当数量的主机名;减少 DOM 元素数量。

(2)Server 方面
使用 CDN ;配置 ETag;对组件使用 Gzip 压缩。

(3)Cookie 方面
减⼩ cookie 大⼩

(4)css 方面
将样式表放到页面顶部;不使用 CSS 表达式;使用 <link> ;不使用 @import。

(5)Javascript 方面
将脚本放到页面底部;将 javascript 和 css 从外部引⼊;压缩 javascript 和 css;删除不需要的脚本;减少 DOM 访问。

(6)图片⽅面
优化图片:根据实际颜色需要选择色深 、压缩 ;优化 css 精灵;不要在 HTML 中拉伸图片。

6、HTTP状态码及其含义
1XX :信息状态码

100 Continue 继续,⼀ 般在发送 post 请求时, 已发送了 http header 之后服务端将返回此信息,表示确认, 之后发送具体参数信息。

2XX :成功状态码

200 OK 正常返回信息
201 Created 请求成功并且服务器创建了新的资源
202 Accepted 服务器已接受请求,但尚未处理

3XX :重定向

301 Moved Permanently 请求的网页已永久移动到新位置。
302 Found 临时性重定向。
303 See Other 临时性重定向,且总是使用 GET 请求新的 URI 。
304 Not Modified 自从上次请求后,请求的网页未修改过。

4XX :客户端错误

400 Bad Request 服务器⽆法理解请求的格式,客户端不应当尝试再次使用相同的内
容发起请求。
401 Unauthorized 请求未授权。
403 Forbidden 禁止访问。
404 Not Found 找不到如何与 URI 相匹配的资源。

5XX: 服务器错误

500 Internal Server Error 最常⻅的服务器端错误。
503 Service Unavailable 服务器端暂时⽆法处理请求 ( 可能是过载或维护) 。

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

8、介绍⼀下你对浏览器内核的理解?
主要分成两部分:渲染引擎( layout engineer 或 Rendering Engine )和 JS 引擎。

渲染引擎:负责取得网页的内容 ( HTML 、 XML 、图像等等) 、整理讯息 (例如加⼊CSS 等), 以及计算网页的显示⽅式,然后会输出至显示器或打印机 。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑 、显示网络内容的应用程序都需要内核。

JS 引擎:解析和执⾏ javascript 来实现网页的动态效果。最开始渲染引擎和 JS 引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。

9、html5有哪些新特性、移除了那些元素
HTML5 现在已经不是 SGML 的子集, 主要是关于图像,位置,存储, 多任务等功能的增加;
绘画 canvas,用于媒介回放的 video 和 audio 元素;
本地离线存储 localStorage 长期存储数据, 浏览器关闭后数据不丢失 ;
sessionStorage 的数据在浏览器关闭后自动删除 ;
语意化更好的内容元素, 比如 article 、 footer 、 header 、 nav 、 section ;
表单控件, calendar 、 date 、 time 、 email 、 url 、 search ;
新的技术 webworker 、 websocket 、 Geolocation ;
移除的元素:

纯表现的元素: basefont 、 big 、 center 、 font 、 s 、 strike 、 tt 。
对可用性产生负面影响的元素: frame 、 frameset 、 noframes
⽀持 HTML5 新标签:

IE8/IE7/IE6 ⽀持通过 document.createElement ⽅法产生的标签;
可以利用这⼀特性让这些浏览器⽀持 HTML5 新标签;
浏览器⽀持新标签后, 还需要添加标签默认的样式;
当然也可以直接使用成熟的框架 、比如 html5shim。
10、HTML5 的离线储存怎么使用,工作原理能不能解释⼀下?
在用户没有与因特网连接时, 可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件

原理: HTML5 的离线存储是基于⼀个新建的 .appcache 文件的缓存机制(不是存储技术), 通过这个文件上的解析清单离线存储资源, 这些资源就会像 cookie ⼀样被存储了下来 。之后当网络在处于离线状态下时, 浏览器会通过被离线存储的数据进行页面展示。

如何使用:

页面头部像下面⼀样加入⼀个 manifest 的属性;
在 cache.manifest 文件的编写离线存储的资源;
在离线状态时, 操作 window.applicationCache 进行需求实现。

11、浏览器是怎么对 HTML5 的离线储存资源进行管理和加载的呢?
在线的情况下, 浏览器发现 html 头部有 manifest 属性, 它会请求 manifest 文件, 如果是第⼀次访问 app ,那么浏览器就会根据manifest文件的内容下载相应的资源并且进行离线存储 。如果已经访问过 app 并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的 manifest 文件与旧的 manifest 文件, 如果文件没有发生改变,就不做任何操作, 如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。

离线的情况下, 浏览器就直接使用离线存储的资源。

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

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

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

13、iframe有那些缺点?
iframe 会阻塞主⻚⾯的 Onload 事件
搜索引擎的检索程序无法解读这种⻚⾯,不利于 SEO
iframe 和主⻚⾯共享连接池, 而浏览器对相同域的连接有限制,所以会影响⻚⾯的并⾏加载
使用 iframe 之前需要考虑这两个缺点 。如果需要使用 iframe , 最好是通过javascript 动态给 iframe 添加 src 属性值, 这样可以绕开以上两个问题。
14、WEB标准以及W3C标准是什么?
标签闭合 、标签小写 、不乱嵌套 、使用外链 css 和 js 、结构⾏为表现的分离。

15、xhtml和html有什么区别?
⼀个是功能上的差别:
主要是 XHTML 可兼容各⼤浏览器 、手机以及 PDA , 并且浏览器也能快速正确地编译网页。

另外是书写习惯的差别:
XHTML 元素必须被正确地嵌套, 闭合, 区分大⼩写,文档必须拥有根元素。

16、Doctype作用? 严格模式与混杂模式如何区分? 它们有何意义?
页面被加载的时, link 会同时被加载, 而 @imort 页面被加载的时, link 会同时被加载, 而 @import 引用的 CSS 会等到页面被加载完再加载 import 只在 IE5 以上才能识别, 而 link 是 XHTML 标签, 无兼容问题 link 方式的样式的权重 高于 @import 的权重。

<!DOCTYPE> 声明位于文档中的最前面, 处于 <html> 标签之前 。告知浏览器的解析器, 用什么文档类型 规范来解析这个文档 。
严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运⾏在混杂模式中, 页面以宽松的向后兼容的方式显示 。模拟老式浏览器的⾏为以防止站点无法⼯作 。 DOCTYPE 不存在或格式不正确会导致文档以混杂模式呈现。
17 行内元素有哪些?块级元素有哪些? 空(void)元素有那些?行内元素和块级元素有什么区别?
⾏内元素有: a b span img input select strong
块级元素有: div ul ol li dl dt dd h1 h2 h3 h4… p
空元素:


<input> <link> <meta>
⾏内元素不可以设置宽高,不独占⼀⾏
块级元素可以设置宽高, 独占⼀⾏
18、HTML全局属性(global attribute)有哪些
class :为元素设置类标识
data-* : 为元素增加自定义属性
draggable : 设置元素是否可拖拽
id : 元素 id ,文档内唯⼀
lang : 元素内容的的语⾔
style : ⾏内 css 样式
title : 元素相关的建议信息
19、Canvas和SVG有什么区别?
svg 绘制出来的每⼀个图形的元素都是独立的 DOM 节点, 能够方便的绑定事件或用来修改 。 canvas 输出的是⼀整幅画布。
svg 输出的图形是矢量图形,后期可以修改参数来自由放大缩⼩,不会失真和锯齿 。而canvas 输出标量画布,就像⼀张图片⼀样,放大会失真或者锯齿。
20、HTML5 为什么只需要写 <!DOCTYPE HTML>
HTML5 不基于 SGML , 因此不需要对 DTD 进⾏引用,但是需要 doctype 来规范浏览器的⾏为
而 HTML4.01 基于 SGML ,所以需要对类型DTD 进⾏引用, 才能告知浏览器文档所使用的文档
21、如何在页面上实现⼀个圆形的可点击区域?
svg
border-radius
纯 js 实现 需要求⼀个点在不在圆上简单算法 、获取鼠标坐标等等
22 网页验证码是干嘛的, 是为了解决什么安全问题?
区分用户是计算机还是⼈的公共全自动程序 。可以防止恶意破解密码 、刷票 、论坛灌水
有效防止黑客对某⼀个特定注册用户用特定程序暴⼒破解方式进⾏不断的登陆尝试
23 viewport
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimu......
// width 设置viewport宽度,为⼀个正整数,或字符串‘device-width’
// device-width 设备宽度
// height 设置viewport高度,⼀ 般设置了宽度,会自动解析出高度,可以不用设置
// initial-scale 默认缩放比例 (初始缩放比例), 为⼀个数字,可以带⼩数
// minimum-scale 允许用户最⼩缩放比例,为⼀个数字,可以带⼩数
// maximum-scale 允许用户最大缩放比例,为⼀个数字,可以带⼩数
// user-scalable 是否允许手动缩放
24、渲染优化
1、禁止使用 iframe ( 阻塞父⽂档 onload 事件)

2、iframe 会阻塞主页面的 Onload 事件

搜索引擎的检索程序⽆法解读这种页面,不利于SEO
iframe 和主页面共享连接池, 而浏览器对相同域的连接有限制,所以会影响页面的并行加载
使用 iframe 之前需要考虑这两个缺点 。如果需要使用 iframe , 最好是通过javascript
动态给 iframe 添加 src 属性值, 这样可以绕开以上两个问题
3、禁止使用 gif 图片实现 loading 效果 ( 降低 CPU 消耗,提升渲染性能)

4、使用 CSS3 代码代替 JS 动画 (尽可能避免重绘重排以及回流)

5、对于⼀些⼩图标, 可以使用base64位编码, 以减少⽹络请求 。但不建议大图使用, 比较耗费 CPU。小图标优势在于 (1. 减少 HTTP 请求 2.避免⽂件跨域 3.修改及时生效)

6、页面头部的 <style></style> <script></script> 会阻塞页面;( 因为 Renderer进程中 JS 线程和渲染线程是互斥的)

7、页面中空的 href 和 src 会阻塞页面其他资源的加载 (阻塞下载进程)

8、⽹页 gzip , CDN 托管, data 缓存 , 图片服务器

9、前端模板 1S+数据,减少由于 HTML 标签导致的带宽浪费, 前端用变量保存A1AX请求结果,每次操作本地变量,不用请求,减少请求次数

10、用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能

11、当需要设置的样式很多时设置 className 而不是直接操作 style

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

13、图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳

14、对普通的网站有⼀个统⼀的思路,就是尽量向前端优化 、减少数据库操作 、减少磁盘 IO

25、meta viewport相关
<!DOCTYPE html> <!--H5标准声明,使用 HTML5 doctype,不区分大⼩写-->
<head lang=”en”> <!--标准的 lang 属性写法-->
<meta charset= ’utf-8′> <!--声明文档使用的字符编码-->
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> <!--优先使
<meta name= ”description” content=”不超过150个字符”/> <!--页面描述-->
<meta name= ”keywords” content=””/> <!-- 页面关键词-->
<meta name= ”author” content= ”name, email@gmail .com”/> <!--网页作者-->
<meta name= ”robots” content= ”index,follow”/> <!--搜索引擎抓取-->
<meta name=”viewport” content=”initial-scale=1, maximum- scale=3, minimum-sc
<meta name= ”apple-mobile-web-app-title” content=”标题”> <!--iOS 设备 begin-- <meta name= ”apple-mobile-web-app-capable” content= ”yes”/> <!--添加到主屏后的标
是否启用 WebApp 全屏模式,删除苹果默认的⼯具栏和菜单栏-->
< meta name=”apple- itunes- app” content=” app- id=myAppStoreID, affiliate-data=
<!--添加智能 App ⼴告条 Smart App Banner ( iOS 6+ Safari) -->
<meta name= ”apple-mobile-web-app-status-bar-style” content= ”black”/>
<meta name=”format-detection” content=”telphone=no, email=no”/> <!--设置苹果
<meta name= ”renderer” content= ”webkit”> <!-- 启用360浏览器的极速模式(webkit)-- <meta http-equiv=”X-UA-Compatible” content=”IE=edge”> <!--避免IE使用兼容模
<meta http-equiv= ”Cache-Control” content=”no-siteapp” /> <!--不让百度转码- <meta name= ”HandheldFriendly” content= ”true”> <!--针对手持设备优化,主要是针
<meta name= ”MobileOptimized” content= ”320″> <!--微软的老式浏览器-->
<meta name= ”screen-orientation” content= ”portrait”> <!--uc强制竖屏-->
<meta name=”x5-orientation” content= ”portrait”> <!--QQ强制竖屏-->
<meta name= ”full-screen” content=”yes”> <!--UC强制全屏-->
<meta name=”x5-fullscreen” content= ”true”> <!--QQ强制全屏-->
<meta name= ”browsermode” content= ”application”> <!--UC应用模式-->
<meta name=”x5-page-mode” content=”app”> <!-- QQ应用模式-->
<meta name= ”msapplication-tap-highlight” content=”no”> <!--windows phone
设置页面不缓存-->
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv= ”cache-control” content=”no-cache”>
<meta http-equiv= ”expires” content=”0″>
26、你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么?
IE : trident 内核
Firefox : gecko 内核
Safari : webkit 内核
Opera :以前是 presto 内核, Opera 现已改用Google - Chrome 的 Blink 内核
Chrome:Blink (基于 webkit , Google与Opera Software共同开发)
27、div+css的布局较table布局有什么优点?
改版的时候更⽅便 只要改 css ⽂件。
页面加载速度更快 、结构化清晰 、页面显示简洁。
表现与结构相分离。
易于优化 ( seo ) 搜索引擎更友好, 排名更容易靠前。
28、 img的alt与title有何异同?b:strong与em的异同?
alt(alt text) :为不能显示图像 、窗体或 applets 的用户代理 ( UA ), alt 属性用来指定替换⽂字 。替换⽂字的语⾔由 lang 属性指定 。(在IE浏览器下会在没有 title 时把 alt 当成 tool tip 显示)
title(tool tip) :该属性为设置该属性的元素提供建议性的信息
strong :粗体强调标签, 强调,表示内容的重要性
em :斜体强调标签,更强烈强调,表示内容的强调点
29、你能描述⼀下渐进增强和优雅降级之间的不同吗?
渐进增强:针对低版本浏览器进⾏构建页面,保证最基本的功能,然后再针对高级浏览器
进⾏效果 、交互等改进和追加功能达到更好的用户体验。
优雅降级:⼀开始就构建完整的功能,然后再针对低版本浏览器进⾏兼容。
区别:优雅降级是从复杂的现状开始, 并试图减少用户体验的供给, 而渐进增强则是从⼀个非常基础的, 能够起作用的版本开始, 并不断扩充, 以适应未来环境的需要 。降级 (功能衰减) 意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。

30、为什么利用多个域名来存储网站资源会更有效?
CDN 缓存更⽅便
突破浏览器并发限制
节约 cookie 带宽
节约主域名的连接数,优化页面响应速度
防止不必要的安全问题
31、简述⼀下src与href的区别
src 用于替换当前元素, href用于在当前⽂档和引用资源之间确立联系。
src 是 source 的缩写,指向外部资源的位置,指向的内容将会嵌⼊到⽂档中当前标签所在位置;在请求 src 资源时会将其指向的资源下载并应用到⽂档内,例如 js 脚本,img 图片和 frame 等元素
<script src ="js.js"></script> 当浏览器解析到该元素时,会暂停其他资源的下载和处理, 直到将该资源加载 、编译 、执⾏完毕, 图片和框架等元素也如此, 类似于将所指向资源嵌⼊当前标签内 。这也是为什么将js脚本放在底部而不是头部。

href 是 Hypertext Reference 的缩写,指向⽹络资源所在位置, 建立和当前元素 ( 锚点) 或当前⽂档 (链接) 之间的链接, 如果我们在⽂档中添加 。
<link href="common.css" rel="stylesheet"/> 那么浏览器会识别该⽂档为 css ⽂件,就会并⾏下载资源并且不会停止对当前⽂档的处理 。这也是为什么建议使用 link ⽅式来加载 css , 而不是使用 @import ⽅式。
32、知道的网页制作会用到的图片格式有哪些?
png-8 、 png-24 、 jpeg 、 gif 、 svg

但是上面的那些都不是面试官想要的最后答案 。面试官希望听到是Webp , Apng 。 ( 是否有关注新技术,新鲜事物)。

Webp: WebP 格式,谷歌 ( google) 开发的⼀种旨在加快图片加载速度的图片格式 。图片压缩体积大约只有 JPEG 的 2/3 , 并能节省大量的服务器带宽资源和数据空间。Facebook Ebay 等知名⽹站已经开始测试并使用 WebP 格式。在质量相同的情况下, WebP格式图像的体积要比JPEG格式图像⼩ 40% 。

Apng:全称是 “Animated Portable Network Graphics” , 是PNG的位图动画扩展, 可以实现png格式的动态图片效果 。04年诞生,但⼀直得不到各大浏览器⼚商的⽀持, 直到⽇前得到 iOS safari 8 的⽀持,有望代替 GIF 成为下⼀代动态图标准。

33、⼀个页面上有大量的图片 (大型电商网站) ,加载很慢,你有哪些方法优化这些图片的加载,给用户更好的体验。
图片懒加载,在页面上的未可视区域可以添加⼀个滚动事件, 判断图片位置与浏览器顶端的距离与页面的距离, 如果前者小于后者,优先加载。
如果为幻灯片 、相册等, 可以使用图片预加载技术,将当前展示图片的前⼀张和后⼀张优先下载。
如果图片为css图片, 可以使用 CSSsprite , SVGsprite , Iconfont 、 Base64 等技术。
如果图片过大, 可以使用特殊编码的图片,加载时会先加载⼀张压缩的特别厉害的缩略图, 以提高用户体验。
如果图片展示区域小于图片的真实大小,则因在服务器端根据业务需要先行进行图片压缩, 图片压缩后大小与展示⼀致。
34、常见排序算法的时间复杂度,空间复杂度

35、web开发中会话跟踪的方法有哪些
cookie
session
url 重写
隐藏 input
ip 地址
36、HTTP request报文结构是怎样的
首行是Request-Line包括:请求方法,请求URI,协议版本, CRLF
首行之后是若干行请求头, 包括general-header, request-header或者entity-header,每个⼀行以CRLF结束
请求头和消息实体之间有⼀个CRLF分隔
根据实际请求需要可能包含⼀个消息实体 ⼀个请求报文例子如下:
GET /Protocols/rfc2616/rfc2616-sec5.html HTTP/1.1
Host: www.w3.org
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,
Referer: https://www.google.com.hk/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: authorstyle=yes
If-None-Match: "2cc8-3e3073913b100"
If-Modified-Since: Wed, 01 Sep 2004 13:24:52 GMT
name=qiu&age=25
37、 HTTP response报文结构是怎样的
首行是状态行包括:HTTP版本,状态码,状态描述,后面跟⼀个CRLF
首行之后是若干行响应头, 包括:通用头部,响应头部,实体头部
响应头部和响应实体之间用⼀个CRLF空行分隔
最后是⼀个可能的消息实体 响应报文例子如下:
HTTP/1.1 200 OK
Date: Tue, 08 Jul 2014 05:28:43 GMT
Server: Apache/2
Last-Modified: Wed, 01 Sep 2004 13:24:52 GMT
ETag: "40d7-3e3073913b100"
Accept-Ranges: bytes
Content-Length: 16599
Cache-Control: max-age=21600
Expires: Tue, 08 Jul 2014 11:28:43 GMT
P3P: policyref="http://www.w3.org/2001/05/P3P/p3p.xml"
Content-Type: text/html; charset=iso-8859-1
{"name": "qiu", "age": 25}

css属性white-space定义如何处理文本中多余的空白和换行

css3对white-space增加了两个值,pre-line和pre-wrap,如下

normal ---- 忽略空白、换行(默认值)
pre ---- 保留空白,忽略换行
pre-line ---- 保留换行,忽略空白
pre-wrap ---- 保留空白、换行
nowrap ---- 强制不换行,忽略空白
inherit ---- 继承父元素

当项目不在vscode打开的根目录时,eslint可能会报这个错误: Cannot read file 'tsconfig.json' .eslint
因为eslint默认在根目录寻找 tsconfig.json
可配置 .eslint.js 解决问题

module.exports = {
  parserOptions: {
    project: 'tsconfig.json',
    sourceType: 'module',
    tsconfigRootDir: __dirname,
    createDefaultProgram: true,
  },
};