Comment on page
09 知识点梳理:HTML和浏览器
共同点
都是保存在浏览器端,并且是同源的
区别
Cookie 和 session 都可用来存储用户信息,cookie 存放于客户端,session 存放于服务器端, 因为 cookie 存放于客户端有可能被窃取,所以 cookie 一般用来存放不敏感的信息,比如 用户设置的网站主题,敏感的信息用 session 存储,比如用户的登陆信息,session 可以 存放于文件,数据库,内存中都可以,cookie 可以服务器端响应的时候设置,也可以客 户端通过 JS 设置 cookie 会在请求时在 http 首部发送给客户端,cookie 一般在客户端有 大小限制,一般为 4K,
下面从几个方向区分一下 cookie,localstorage,sessionstorage 的区别
- 生命周期:
- Cookie:可设置失效时间,否则默认为关闭浏览器后失效 Localstorage:除非被手动清除,否则永久保存
- Sessionstorage:仅在当前网页会话下有效,关闭页面或浏览器后就会被清除 2、存放数据:
- Cookie:4k 左右
- Localstorage 和 sessionstorage:可以保存 5M 的信息
- http 请求:
- Cookie:每次都会携带在 http 头中,如果使用 cookie 保存过多数据会带来性能问题
- 其他两个:仅在客户端即浏览器中保存,不参与和服务器的通信
- 易用性:
- Cookie:需要程序员自己封装,原生的 cookie 接口不友好
- 其他两个:即可采用原生接口,亦可再次封装
- 应用场景:
- 从安全性来说,因为每次 http 请求都回携带 cookie 信息,这样子浪费了带宽,所以 cookie 应该尽可能的少用
- 此外 cookie 还需要指定作用域,不可以跨域调用,限制很多
- 但是 用户识别用户登陆来说,cookie 还是比 storage 好用,其他情况下可以用 storage
- localstorage 可以用来在页面传递参数
- sessionstorage 可以用来保存一些临时的数据,防止用户刷新 页面后丢失了一些参数。
在 HTML 页面中,如果在执行脚本时,页面的状态是不可响应的,直到脚本执行完成后,页面才变成可响应。
web worker 是运行在后台的 js,独立于其他脚本,不会影响页面的性能。并且通过 postMessage 将结果回传到主线程。这样在进行复杂操作的时候,就不会阻塞主线程了。
概念
Web Worker (工作线程) 是 HTML5 中提出的概念,分为两种类型,
专用线程(Dedicated Web Worker)
和共享线程(Shared Web Worker)
。专用线程
仅能被创建它的脚本所使用(一个专用线程对应一个主线程),而共享线程
能够在不同的脚本中使用(一个共享线程对应多个主线程)。专用线程可以看做是默认情况的 Web Worker,其加上修饰词的目的是为了与共享线程进行区分。
用途
Web Worker 的意义在于可以将一些耗时的数据处理操作从主线程中剥离,使主线程更加专注于页面渲染和交互。
- 懒加载
- 文本分析
- 流媒体数据处理
- canvas 图形绘制
- 图像处理
- ...
需要注意的点
- 有同源限制
- 无法访问 DOM 节点
- 运行在另一个上下文中,无法使用Window对象
- Web Worker 的运行不会影响主线程,但与主线程交互时仍受到主线程单线程的瓶颈制约。换言之,如果 Worker 线程频繁与主线程进行交互,主线程由于需要处理交互,仍有可能使页面发生阻塞
- 共享线程可以被多个浏览上下文(Browsing context)调用,但所有这些浏览上下文必须同源(相同的协议,主机和端口号)
Doctype 声明于文档最前面,告诉浏览器以何种方式来渲染页面,这里有两种模式,严格模式和混杂模式。
严格模式与混杂模式如何区分? 它们有何意义?
- 严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行
- 混杂模式,向后兼容,模拟老式浏览器,防止浏览器无法兼容页面
XSS(跨站脚本攻击)
是指攻击者在返回的 HTML 中嵌入 javascript 脚本。为了减轻这些 攻击,需要在 HTTP 头部配上,set-cookie:
- httponly
- 这个属性可以防止 XSS,它会禁止 javascript 脚本来访问 cookie。
- secure
- 这个属性告诉浏览器仅在请求为 https 的时候发送 cookie。
- 结果应该是这样的:Set-Cookie=
<cookie-value>
.....
XSS 防御的总体思路是:对输入(和 URL 参数)进行过滤,对输出进行编码。也就是对提 交的所有内容进行过滤,对 url 中的参数进行过滤,过滤掉会导致脚本执行的相关内容; 然后对动态输出到页面的内容进行 html 编码,使脚本无法在浏览器中执行。虽然对输 入过滤可以被绕过,但是也还是会拦截很大一部分的 XSS 攻击。
- 1.cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
- 2.cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗 考虑到安全应当使用 session。
- 3.session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用 COOKIE。
- 4.单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。
原因
safari,为了能把PC端大屏幕的页面以较好的效果展示在小屏幕手机端上,采用了双击缩放(double tap to zoom)的方案。而这就是click在移动端ios会有300ms的缘由。
解决方案一:
禁止缩放,那么就没有了双击产生缩放的操作,那么就不需要等待300ms
<meta name="viewport" content="user-scalable=no" />
解决方案二: FastClcik
- fast click 原理
- 监听touchend事件(touchstart touchend会先于click触发)
- 使用自定义DOM事件 模拟一个click事件
- 把默认的click事件(300ms之后触发)禁止掉
很久不维护了,坑多
浏览器缓存是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档。
所以根据上面的特点,浏览器缓存有下面的优点:
- 1.减少冗余的数据传输
- 2.减少服务器负担
- 3.加快客户端加载网页的速度
第一次请求时

在第一次请求时,服务器会将页面最后修改时间通过Last-Modified标识由服务器发送给客户端,客户端记录修改时间;服务器还会生成一个Etag,并发送给客户端。
浏览器后续再次进行请求时:

浏览器缓存主要分为强强缓存(也称本地缓存)和协商缓存(也称弱缓存)。根据上图,浏览器在第一次请求发生后,再次发送请求时:
- 浏览器请求某一资源时,会先获取该资源缓存的header信息,
- 然后根据header中的Cache-Control和Expires来判断是否过期。
- 若没过期则直接从缓存中获取资源信息,包括缓存的header的信息,所以此次请求不会与服务器进行通信。
这里判断是否过期,则是强缓存相关。后面会讲Cache-Control和Expires相关。
- 如果显示已过期,浏览器会向服务器端发送请求
- 这个请求会携带第一次请求返回的有关缓存的header字段信息
- 比如客户端会通过If-None-Match头将先前服务器端发送过来的Etag发送给服务器,服务会对比这个客户端发过来的Etag是否与服务器的相同
- 若相同,就将If-None-Match的值设为false,
- 返回状态
304
- 客户端继续使用本地缓存,不解析服务器端发回来的数据
- 若不相同就将If-None-Match的值设为true
- 返回状态为200
- 客户端重新机械服务器端返回的数据
- 客户端还会通过If-Modified-Since头将先前服务器端发过来的最后修改时间戳发送给服务器,服务器端通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回最新的内容,如果是最新的,则返回
304
,客户端继续使用本地缓存。
两种缓存
缓存分为两种:强缓存和协商缓存,根据响应的 header 内容来决定。
强缓存、协商缓存什么时候用哪个
- 强缓存是利用http头中的Expires和Cache-Control两个字段来控制的,用来表示资源的缓存时间。强缓存中,普通刷新会忽略它,但不会清除它,需要强制刷新。浏览器强制刷新,请求会带上Cache-Control:no-cache和Pragma:no-cache
- 协商缓存就是由服务器来确定缓存资源是否可用,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问。
- 普通刷新会启用弱缓存,忽略强缓存。只有在地址栏或收藏夹输入网址、通过链接引用资源等情况下,浏览器才会启用强缓存,这也是为什么有时候我们更新一张图片、一个js文件,页面内容依然是旧的,但是直接浏览器访问那个图片或文件,看到的内容却是新的。
为什么要有Etag
你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
- 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
- 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
- 某些服务器不能精确的得到文件的最后修改时间。
Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
具体有哪些请求头是跟缓存相关的
强缓存相关字段有 expires,cache-control。如果 cache-control 与 expires 同时存在的话, cache-control 的优先级高于 expires。
协商缓存相关字段有 Last-Modified/If-Modified-Since,Etag/If-None-Match
- DNS 解析
- TCP 连接
- 发送 HTTP 请求 服务器处理请求并返回 HTTP 报文 浏览器解析渲染页面
- 连接结束

- CSRF
- 跨站请求伪造
- 可以理解为攻击者盗用了用户的身份,以用户的名义发送了恶意请求,比如用户登录了一个网站后,立刻在另一个tab页面访问量攻击者用来制造攻击的网站,这个网站要求访问刚刚登陆的网站,并发送了一个恶意请求,这时候 CSRF 就产生了,比如这个制造攻击的网站使用一张图片,但是这种图片的链接却是可以修改 数据库的,这时候攻击者就可以以用户的名义操作这个数据库
- 防御方式的话
- 验证 HTTPReferer 字段
- 在请求地址中添加 token 并 验证
- 在 HTTP 头中自定义属性并验证。
- XSS
- 跨站脚本攻击
- 是说攻击者通过注入恶意的脚本,在用户浏览网页的时候进行攻 击,比如获取 cookie,或者其他用户身份信息,可以分为存储型和反射型,存储型是攻 击者输入一些数据并且存储到了数据库中,其他浏览者看到的时候进行攻击,反射型的 话不存储在数据库中,往往表现为将攻击代码放在 url 地址的请求参数中
- 防御的话为 cookie 设置 httpOnly 属性,对用户的输入进行检查,进行特殊字符过滤。
encodeURI()
- 301 Moved Permanently 永久移动。
- 请求的资源已被永久的移动到新 URI,返回信息会 包括新的 URI,浏览器会自动定向到新 URI。今后任何新的请求都应使用新的 URI 代替
- 302 Found 临时移动。
- 与 301 类似。但资源只是临时被移动。客户端应继续使用原有 URI
- 304 Not Modified 未修改。
- 所请求的资源未修改,服务器返回此状态码时,不会返回 任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希 望只返 回在指定日期之后修改的资源
HTML5 语义化标签是指正确的标签包含了正确的内容,结构良好,便于阅读,比如 nav 表示导航条,类似的还有 article、header、footer 等等标签。
- 定义
- iframe 元素会创建包含另一个文档的内联框架
- 提示:可以将提示文字放在
<iframe></iframe>
之间,来提示某些不支持 iframe 的浏览器
- 缺点:
- 会阻塞主页面的 onload 事件
- 搜索引擎无法解读这种页面,不利于 SEO
- iframe 和主页面共享连接池,而浏览器对相同区域有限制所以会影响性能。
- event 指定事件名
- function 指定要事件触发时执行的函数
- useCapture 指定事 件 是否在捕获或冒泡阶段执行。
- 首先 html5 为了更好的实践 web 语义化,增加了 header,footer,nav,aside,section 等语义 化标签
- 在表单方面,为了增强表单,为 input 增加了 color,emial,data ,range 等类型,
- 在存储方面,提供了 sessionStorage,localStorage,和离线存储,通过这些存储方式方便数 据在客户端的存储和获取
- 在多媒体方面规定了音频和视频元素 audio 和 vedio
- 另外还 有地理定位,canvas 画布,拖放,多线程编程的 web worker 和 websocket 协议。
直接设置0.5px,在不同的浏览器会有不同的表现
transform 缩放
.scale-half {
height: 1px;
transform: scaleY(0.5);
transform-origin: 50% 100%; /*为了防止线模糊*/
}
meta viewport
这样子就能缩放到原来的0.5倍,如果是1px那么就会变成0.5px。
<meta name="viewport" content="initial-scale=0.5, maximum-scale=1.0, user-scalable=no" />
注意:移动端适用,字体也会变小,原理是css的1px在手机上并不是物理上的1像素,可能是2像素,initial-scale的值改为0.5之后就只代表1像素
也可以直 接用图片
- 区别1:
- link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;
- @import属于CSS范畴,只能加载CSS。
- 区别2:
- link引用CSS时,在页面载入时同时加载;
- @import需要页面网页完全载入以后加载。所以会出现一开始没有css样式,闪烁一下出现样式后的页面(网速慢的情况下)
- 区别3:
- link是XHTML标签,无兼容问题;
- @import是在CSS2.1提出的,低版本的浏览器不支持。
- 区别4:
- link支持使用Javascript控制DOM去改变样式;
- 而@import不支持。在html设计制作中,css有四种引入方式。
方式一: 内联样式
<div style="display: none;background:red"></div>
方式二: 嵌入样式
<head>
<style>
.content {
background: red;
}
</style>
</head>
方式三:链接样式
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
方式四:导入样式
导入方式指的是使用 CSS 规则引入外部 CSS 文件
<style>
@import url(style.css);
</style>
或者写在css样式中
@charset "utf-8";
@import url(style.css);
*{ margin:0; padding:0;}
.notice-link a{ color:#999;}
总结
我们应尽量使用
<link>
标签导入外部 CSS 文件,避免或者少用使用其他三种方式。animation属性类似于transition,他们都是随着时间改变元素的属性值,那么区别是什么?
其主要区别在于:transition需要触发一个事件才会随着时间改变其CSS属性;animation在不需要触发任何事件的情况下,也可以显式的随时间变化来改变元素CSS属性,达到一种动画的效果。
1)CSS的transition需要借助别的方式来触发,比如CSS的状态选择器(如:hover)或 借助JavaScript来触发;animation可以自动触发
2)过渡只有一组(两个:开始-结束) 关键帧,动画可以设置多个。
官方文档比较晦涩,建议搭配阅读
- 设定行高(line-height)
- 行内元素
- 添加伪元素(::before、::after)
- calc动态计算
- 使用表格或假装表格
- transform
- 绝对定位
- 使用Flexbox
JS动画
- 缺点:
- (1)JavaScript在浏览器的主线程中运行,而主线程中还有其它需要运行的JavaScript脚本、样式 计算、布局、绘制任务等,对其干扰导致线程可能出现阻塞,从而造成丢帧的情况。
- (2)代码的复杂度高于CSS动画
- 优点:
- (1)JavaScript动画控制能力很强, 可以在动画播放过程中对动画进行控制:开始、暂停、回放、终止、取消都是可以做到的。
- (2)动画效果比css3动画丰富,有些动画效果,比如曲线运动,冲击闪烁,视差滚动效果,只有JavaScript动画才能完成
- (3)CSS3有兼容性问题,而JS大多时候没有兼容性问题
CSS动画
- 缺点:
- (1)运行过程控制较弱,无法附加事件绑定回调函数。CSS动画只能暂停,不能在动画中寻找一个特定的时间点,不能在半路反转动画,不能变换时间尺度,不能在特定的位置添加回调函数或是绑定回放事件,无进度报告
- (2)代码冗长。想用 CSS 实现稍微复杂一点动画,最后CSS代码都会变得非常笨重。
- 优点:
- (1)浏览器可以对动画进行优化。
- (2)代码相对简单,性能调优方向固定
- (3)对于帧速表现不好的低版本浏览器,CSS3可以做到自然降级,而JS则需要撰写额外代码
渲染线程分为main thread(主线程)和compositor thread(合成器线程)。 如果CSS动画只是改变transform和opacity,这时整个CSS动画得以在compositor thread完成(而JS动画则会在main thread执行,然后触发compositor进行下一步操作)。
在JS执行一些昂贵的任务时,main thread繁忙,CSS动画由于使用了compositor thread可以保持流畅。
CSS动画比JS流畅的前提:
- 1.JS在执行一些昂贵的任务
- 2.同时CSS动画不触发layout或paint,在CSS动画或JS动画触发了paint或layout时,需要main thread进行Layer树的重计算,这时CSS动画或JS动画都会阻塞后续操作。
- 只有如下属性的修改才符合“仅触发Composite,不触发layout或paint”:
- backface-visibility
- opacity
- *erspective
- perspective-origin
- transfrom
所以只有用上了3D加速或修改opacity时,css3动画的优势才会体现出来。
如果动画只是简单的状态切换,不需要中间过程控制,在这种情况下,css动画是优选方案。它可以让你将动画逻辑放在样式文件里面,而不会让你的页面充斥 Javascript 库。
然而如果你在设计很复杂的富客户端界面或者在开发一个有着复杂UI状态的 APP。那么你应该使用js动画,这样你的动画可以保持高效,并且你的工作流也更可控。
所以,在实现一些小的交互动效的时候,就多考虑考虑CSS动画。
对于一些复杂控制的动画,使用javascript比较可靠。
#post-title {
display: -webkit-box;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
- opacity=0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定一些 事件,如 click 事件,那么点击该区域,也能触发点击事件的
- visibility=hidden,该元素 隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件
- display=none, 把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删除掉一样
多个相邻(兄弟或者父子关系)普通流的块元素垂直方向 marigin 会重叠
- 折叠的结果为:
- 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
- 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
- 两个外边距一正一负时,折叠结果是两者的相加的和。
- 固定定位 fixed:
- 元素的位置相对于浏览器窗口是固定位置,即使窗口是滚动的它也不会移动。
- Fixed 定位使元素的位置与文档流无关,因此不占据空间。
- Fixed 定位的元素和其他元素重叠。
- 相对定位 relative:
- 如果对一个元素进行相对定位,它将出现在它所在的位置上。
- 然后,可以通过设置垂直 或水平位置,让这个元素“相对于”它的起点进行移动。
- 在使用相对定位时,无论是 否进行移动,元素仍然占据原来的空间。
- 因此,移动元素会导致它覆盖其它框。
- 绝对定位 absolute:
- 绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于
<html>
。 - absolute 定位使元素的位置与文档流无关,因此不占据空间。
- absolute 定位的元素和其他元素重叠。
- 粘性定位 sticky:
- 元素先按照普通文档流定位,然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位。
- 而后,元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。
- 默认定位 Static:
- 默认值。没有 定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。
- inherit:
- 规定应该从父元素继承 position 属性的值。
开放题。CSS3 边框如 border-radius,box-shadow 等;CSS3 背景如 background-size, background-origin 等;CSS3 2D,3D 转换如 transform 等;CSS3 动画如 animation 等。 参考 https://www.cnblogs.com/xkweb/p/5862612.html
- 降低请求量
- 合并资源,减少 HTTP 请求数,minify / gzip 压缩,webP,lazyLoad。
- 加快请求速度
- 预解析 DNS,减少域名数,并行加载,CDN 分发。
- 缓存
- HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存 localStorage。
- 渲染
- JS/CSS 优化,加载顺序,服务端渲染,pipeline。
检测页面加载时间一般有两种方式:
- 一种是被动去测:
- 就是在被检测的页面置入脚本或 探针,当用户访问网页时,探针自动采集数据并传回数据库进行分析
- 另一种主动监测的方式
- 即主动的搭建分布式受控环境,模拟用户发起页面访问请求,主动采集性能数 据并分析,在检测的精准度上,专业的第三方工具效果更佳,比如说性能极客
Last modified 9mo ago