-
- 单连接多资源的方式,减少服务端的链接压力,内存占用更少,连接吞吐量更大
-
由于 TCP 连接的减少而使网络拥塞状况得以改善,同时慢启动时间的减少,使拥塞和丢包恢复速度更快
-
首部压缩
-
服务端推送:能够在客户端发送第一个请求到服务端时,提前把一部分内容推送给客户端,放入缓存当中,这可以避免客户端请求顺序带来的并行度不高,从而导致的性能问题。
-
TCP 连接复用,则使用同一个 TCP 连接来传输多个 HTTP 请求,避免了 TCP 连接建立时的三次握手开销,和初建 TCP 连接时传输窗口小的问题。
-
二进制分帧
-
HTTPS 有两个作用,一是确定请求的目标服务端身份,二是保证传输的数据不会被网络中间节点窃听或者篡改。
-
❝
HTTPS 是使用加密通道来传输 HTTP 的内容。但是 HTTPS 首先与服务端建立一条 TLS 加密通道。TLS 构建于 TCP 协议之上,它实际上是对传输的内容做一次加密,所以从传输内容上看,HTTPS 跟 HTTP 没有任何区别。
❞
17. ['1', '2', '3'].map(parseInt)
输出什么?
- 乍一看可能会说出
[1, 2, 3]
,其实不然,答案是[1, NaN, NaN]
[“1”, “2”, “3”].map(parseInt);
// parseInt(string, radix) 接收2个参数,(要处理的值, 解析时的基数)
// 基数是一个介于2和36之间的整数
// 平铺一下
[“1”, “2”, “3”].map((item, idx) => parseInt(item, idx));
parseInt(“1”, 0); // 1 radix为 0时该值无效,且第一个参数不以“0x”和“0”开头时,按照10为基数处理。这个时候返回1
parseInt(“2”, 1); // NaN 当radix小于2并且大于36或第一个参数的第一个非空格字符不能转换为数字。
parseInt(“3”, 2); // NaN 基数为2(2进制)表示的数中,最大值小于3,所以无法解析,返回NaN
18. Set/Map/WeakSet/WeakMap 区别?
- Set
❝
- 成员不能重复
- 只有健值,没有健名,有点类似数组。
- 可以遍历,方法有 add, delete, has
❞
- WeakSet
❝
- 只能储存对象引用,不能存放值,而 Set 对象都可以
- 成员都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的应用,随时可以消失。可以用来保存 DOM 节点,不容易造成内存泄漏
- 不能遍历,方法有 add, delete, has
❞
- Map
❝
- 本质上是健值对的集合,类似集合
- 可以遍历,方法很多,方便跟各种数据格式进行转换
❞
- WeakMap
❝
- 直接受对象作为健名(null 除外),不接受其他类型的值作为健名
- 健名所指向的对象,不计入垃圾回收机制
- 不能遍历,方法同 get, set, has, delete
❞
19. 描述下 es5/es6 继承的区别?
class
的声明没有被变量提升,类似let/const
的声明,不能前置使用;
var t = new Test(); // Test is not defined
class Test {}
class
声明内部会启用严格模式
class Test {
constructor() {
empty = “test”; // empty is not defined
}
}
class
的所有方法(包括静态方法和实例方法)都是不可枚举的
class Text {
constructor() {
this.a = 1;
}
func1() {}
func2() {}
}
console.log(Object.keys(Text)); // []
console.log(Object.keys(Text.prototype)); // []
Object.keys(new Text()); // [‘a’]
function Func() {
this.a = 1;
this.fun1 = function () {};
this.fun2 = function () {};
}
Func.prototype.func3 = function () {};
console.log(Object.keys(Func)); // []
console.log(Object.keys(Func.prototype)); // [‘func3’]
Object.keys(new Func()); // [‘a’, ‘func1’, ‘func2’]
class
的所有方法(包括静态方法和实例方法)都没有原型对象prototype
,所以也没有constructor
,不能使用 new 来调用其方法
var a = new Text();
new a.func1(); // a.test is not a constructor
- 必须使用
new
调用class
Text(); // Class constructor A cannot be invoked without ‘new’
new Text();
20. 简述下浏览器的渲染过程?
-
解析 HTML,生成 DOM 树,解析 CSS,生成 CSSOM 树
-
将 DOM 树和 CSSOM 树结合,生成渲染树(Render Tree)
❝
构建渲染树:
- 从 DOM 树的根节点开始遍历每个可见节点。
- 对于每个可见的节点,找到 CSSOM 树中对应的规则,并应用它们。
- 根据每个可见节点以及其对应的样式,组合生成渲染树。
❞
-
Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
-
Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
-
Display:将像素发送给 GPU,展示在页面上。(这一步其实还有很多内容,比如会在 GPU 将多个合成层合并为同一个层,并展示在页面中。而 css3 硬件加速的原理则是新建合成层,这里我们不展开,之后有机会会写一篇博客)
浏览器渲染过程
21. 回流和重绘?
- 重绘:由于节点的几何属性发生改变或者由于样式发生变化而不影响布局的成为重绘。
❝
例如 outline, visibility, color、background-color 等,重绘的代价是高昂的,因为浏览器必须验证 DOM 树上其他节点元素的可见性。
❞
- 回流:回流是布局或者几何属性需要改变就称为回流。回流是影响浏览器性能的关键因素,因为其变化涉及到部分页面(或是整个页面)的布局更新。一个元素的回流可能会导致了其所有子元素以及 DOM 中紧随其后的节点、祖先节点元素的随后的回流。
❝
大部分的回流将导致页面的重新渲染,回流必定会导致重绘,但是,重绘不一定会引发回流
❞
22. 如何优化重绘重排?
- 1.浏览器优化
❝
现代浏览器大多都是通过
队列机制
来批量更新布局,浏览器会把修改操作放在队列中,至少一个浏览器刷新(即 16.6ms)才会清空队列,但当你获取布局信息的时候,队列中可能有会影响这些属性或方法返回值的操作,即使没有,浏览器也会强制清空队列
,触发回流与重绘来确保返回正确的值。
以下属性或方法的使用都会强制刷新队列,应避免频繁使用:
- offsetTop、offsetLeft、offsetWidth、offsetHeight
- scrollTop、scrollLeft、scrollWidth、scrollHeight
- clientTop、clientLeft、clientWidth、clientHeight
- width、height
- getComputedStyle()
- getBoundingClientRect()
❞
- 2.减少重绘与回流
❝
- 使用 transform 替代 to
- 使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局)
- 避免使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局。
- 尽可能在 DOM 树的最末端改变 class,回流是不可避免的,但可以减少其影响。尽可能在 DOM 树的最末端改变 class,可以限制了回流的范围,使其影响尽可能少的节点。
- 避免设置多层内联样式,CSS 选择符从右往左匹配查找,避免节点层级过多。
- 将动画效果应用到 position 属性为 absolute 或 fixed 的元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流,同时,控制动画速度可以选择 requestAnimationFrame
- 避免使用 CSS 表达式,可能会引发回流。
- 将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点,例如 will-change、video、iframe 等标签,浏览器会自动将该节点变为图层。
- CSS3 硬件加速(GPU 加速),使用 css3 硬件加速,可以让 transform、opacity、filters 这些动画不会引起回流重绘 。但是对于动画的其它属性,比如 background-color 这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。
- 避免频繁操作样式,最好一次性重写 style 属性,或者将样式列表定义为 class 并一次性更改 class 属性。
- 避免频繁操作 DOM,创建一个 documentFragment,在它上面应用所有 DOM 操作,最后再把它添加到文档中。
- 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
- 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
❞
23. 介绍下 js 的模块化?
- Commonjs(2009):号召规范服务端的 js 接口,形成了 ServerJs 规范(即 CommonJs)CommonJS 内的模块规范成为了 Node.js 的标准实现规范
// file module.js
// 对外输出
module.exports = {
a: 1,
b: 2,
};
// file test.js 引入一个模块
var test = require(“module.js”).a; // 1
- AMD(2009):js 模块的异步加载 ,
require.js
、curl
是其对应实现
❝
- 源自 CommonJS,但是 异步的加载的
- 模块下载完后,立即执行加载,所有模块加载完毕进入回调
- 随着以 npm (遵循 CommonJS 规范)为主导的依赖管理机制的统一,越来越多的开发者放弃了使用 AMD 模式。
❞
// file module.js 定义一个模块
define(function () {
return {
a: 1,
b: 2,
};
});
// file hello.js 引入一个模块
define([“./module.js”], function (module) {
console.log(module.a, module.b);
});
- UMD(2011):为了支持一个模块同时兼容 AMD 和 CommonJs 规范,适用于 同时支持浏览器端和服务端引用的第三方库,提出了 UMD 规范
// 定义一个模块
(function (root, factory) {
if (typeof define === “function” && define.amd) {
// AMD
define([“jquery”, “underscore”], factory);
} else if (typeof exports === “object”) {
// Node, CommonJS之类的
module.exports = factory(require(“jquery”), require(“underscore”));
} else {
// 浏览器全局变量(root 即 window)
root.returnExports = factory(root.jQuery, root._);
}
})(this, function ($, _) {
// 方法
function a() {} // 私有方法,因为它没被返回 (见下面)
function b() {} // 公共方法,因为被返回了
function c() {} // 公共方法,因为被返回了
// 暴露公共方法
return {
b: b,
c: c,
};
});
- CMD(2011):
require.js
需要提前声明 所依赖的库,为了做到 看起来"使用时才加载"(就近依赖),创造了 sea.js,同时其对应 CMD 规范,下载完后,并不立即执行,回调函数中遇到 require 才执行加载模块
// 定义一个模块
define(function (require, exports, module) {
// …
});
//sea.js:
define(function (require, exports, module) {
var mod_A = require(“dep_A”);
var mod_B = require(“dep_B”);
var mod_C = require(“dep_C”);
});
- ES2015 Modules(2015):导入的值也是只读不可变对象(丧失了 CommonJS 的修改特性,但也是一个优点,保证了 ES6 Modules 的依赖关系是确定(Deterministic)的,和运行时的状态无关,从而也就保证了 ES6 Modules 是可以进行可靠的静态分析的。),不像 CommonJS 是一个内存的拷贝
// file module.js
export const a = 1;
export function b (){
}
export default {
c: 3
}
// file test.js
import {a, b}, c from ‘./module.js’
24. ES6 转换为 ES5 中间经历了什么?
❝
这里其实我们可以参考 babel 的实现思路
❞
- 将代码字符串解析成抽象语法树,即所谓的 AST
❝
可以使用
@babel/parser
的parse
方法,将代码字符串解析成 AST;
❞
- 对 AST 进行处理,在这个阶段可以对 ES6 代码进行相应转换,即转成 ES5 代码
❝
使用
@babel/core
的transformFromAstSync
方法,对 AST 进行处理,将其转成 ES5 并生成相应的代码字符串;过程中,可能还需要使用@babel/traverse
来获取依赖文件等。
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
HTTP
-
HTTP 报文结构是怎样的?
-
HTTP有哪些请求方法?
-
GET 和 POST 有什么区别?
-
如何理解 URI?
-
如何理解 HTTP 状态码?
-
简要概括一下 HTTP 的特点?HTTP 有哪些缺点?
-
对 Accept 系列字段了解多少?
-
对于定长和不定长的数据,HTTP 是怎么传输的?
-
HTTP 如何处理大文件的传输?
-
HTTP 中如何处理表单数据的提交?
-
HTTP1.1 如何解决 HTTP 的队头阻塞问题?
-
对 Cookie 了解多少?
-
如何理解 HTTP 代理?
-
如何理解 HTTP 缓存及缓存代理?
-
为什么产生代理缓存?
-
源服务器的缓存控制
-
客户端的缓存控制
-
什么是跨域?浏览器如何拦截响应?如何解决?
g-2htqKUHf-1710584991670)]
[外链图片转存中…(img-UoOpDWde-1710584991670)]
[外链图片转存中…(img-25x17UsN-1710584991671)]
[外链图片转存中…(img-vC0dkEZj-1710584991671)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
[外链图片转存中…(img-nrfoWy0p-1710584991671)]
HTTP
-
HTTP 报文结构是怎样的?
-
HTTP有哪些请求方法?
-
GET 和 POST 有什么区别?
-
如何理解 URI?
-
如何理解 HTTP 状态码?
-
简要概括一下 HTTP 的特点?HTTP 有哪些缺点?
-
对 Accept 系列字段了解多少?
-
对于定长和不定长的数据,HTTP 是怎么传输的?
-
HTTP 如何处理大文件的传输?
-
HTTP 中如何处理表单数据的提交?
-
HTTP1.1 如何解决 HTTP 的队头阻塞问题?
-
对 Cookie 了解多少?
-
如何理解 HTTP 代理?
-
如何理解 HTTP 缓存及缓存代理?
-
为什么产生代理缓存?
-
源服务器的缓存控制
-
客户端的缓存控制
-
什么是跨域?浏览器如何拦截响应?如何解决?