CSS
CSS 选择器优先级机制
有哪些隐藏元素的方法
CSS 3D 加速
css 变量的理解
-
增强代码可读性,易于复用
-
易于跨文档修改
-
使用
- 变量名大小写敏感,以 -- 开头如 --color
- css 变量也是有作用范围的
- :root 定义全局变量
:root { // :root 定义全局 --color: red; }- div { --color: red; } // 局部变量,作用于 div 元素及其后代元素。div 元素的子元素都可以使用这个变量。
- 使用变量,通过 var() 函数。 var(--color)
<div> <p>this is p</p></div> p { color: var(--color); }- 可以在任意元素中声明自定义属性。在段落标签、文档区域标签、侧边栏标签、根标签甚至伪元素中声明变量即可,它们与普通属性作用相同
- CSS 属性具有继承性与级联性,变量的值会继承父盒子的属性值
- CSS 变量可添加条件规则,如媒体类型
@media screen and (min-width: 768px) { --gutter: 30px}- CSS 变量用于 HTML 的样式属性
<html style="--color: red" id = 'dom'></html> 可以通过 js 设置 dom.style.setPropery('--color', 'blue')- 使用默认值
p { color: var(--color, black) // --color 没有值的话, 就使用 black 作为默认值 }- vue3 中怎么实现在 css 中绑定变量的
vue3 中 style 中 css 的变量的原理主要是依赖css 变量,在 vue3 中 css 变量的写法是这样的
h1{ color: v-bind(color); size: v-bind('state.size') // 支持 js 表达式,需要用引号包括起来 }- 实际的值会被编译成 css 自定义属性,自定义属性会通过样式内联的方式应用到该元素的父元素上,并且在源值变更的时候,可以响应式更新。
- 代码实现上就是 compileStyle 通过正则匹配将 v-bind 变成 var() 函数,变量名是根据组件 id 生成,生产环境是随机字符串
- 编译后要响应值的变化,就需要通过 js 控制 css
- 根据收集的 css 变量和 js 中暴露出来的变量生成 useCssVars
- useCssVars 主要做两件事情, 1. watchPostEffect(setVars) 组件更新后执行,2.监听子元素,子元素变化,也会执行更新。更新就是动态把属性写入到父元素的 style 属性中, 通过 style.setProperty('--color', 'red')
重排,重绘
css 选择器
link 和 @import 的区别
什么是响应式布局,如何实现
如何制作动画效果
position
BFC
CSS 盒子模型
行内元素,块元素
HTML
DOM 事件模型
DOM 树
Canvas 和 SVG 的区别
操作 DOM 是否可能比虚拟 DOM 性能更好
渲染合成层
图像编码格式
HTML 数据存储方案
聊聊 iframe
preload 机制是怎样的
有哪些常用 meta 标签
如何判断元素是否到达可视区域
HTTPS 加密
JS
instanceof 的作用和原理
bind ,apply 与 call 的实现
// call
Function.prototype.call = function(ctx, ...args) {
ctx= ctx || window
ctx.fn = this;
const result = ctx.fn(...args);
delete ctx.fn;
return result
}
// apply
Function.prototype.apply = function(ctx, arr = []) {
ctx= ctx || window
ctx.fn = this;
const result = ctx.fn(...arr);
delete ctx.fn;
return result
}
// bind
// 1. 第一个参数是上下文, 后面还可以传参数,返回的是一个函数, 函数可以继续接收参数
// 2. bind 后的函数可以作为构造函数使用,且绑定的上下文失效, 但是传入的参数可以用
Function.prototype.bind = function(ctx, ...args) {
const self = this;
function Fn() {}
function bound(...params) {
const context = this instanceof Fn ? this : ctx;
const result = self.apply(context,...args, ...params);
return result;
}
Fn.prototype = this.prototype;
bound.prototype = new Fn
return bound
}
原型链
Js 事件循环机制
JS 内存泄漏问题排查
V8 垃圾回收机制
UglifyJS 原理
作用域
history hash 路由
实现对象深拷贝
React 和 Vue diff 算法
Object.freeze 和 const 的区别
聊聊函数式编程
DOMContentLoaded 与 load 事件的区别
XHR 与 fetch 的区别
聊聊对 cookie 的理解
聊聊 requestIdleCallback 接口
聊聊对 AST 的理解
requestAnimationFrame 接口
实现一个发布订阅者模式
Promise 的实现
generator 原理
es5 实现继承
0.1 + 0.2 !== 0.3
js 变量提升
weakMap 和 Map 的区别
Proxy 和 Reflect
实现 lodash get 函数
尾递归是什么
为什么 ESModule 那么快
什么是立即执行函数
闭包作用及原理
柯里化
trim 方法实现
防抖和节流的实现
Vue
Vue 为什么要用 Proxy 代替 Object.defineProperty
Vue 中 style scoped 的原理
Vue 中的自定义指令
v-if 和 v-show 有什么区别
computed 属性
SFC 的 template 编译
Computed 和 Watch 有什么不同
Vue 的数据绑定机制是如何实现的
Vue nextTick
keep-alive
Vue 的生命周期有哪些,都做了什么事
Vue3 源码
Vuex 的原理
- 用法
import Vuex from 'vuex'
Vue.use(Vuex)
const store = Vuex.Store({
state: {},
getters: {
name(state) {
return state.name + 'hello'
}
},
mutations:{
mName(state, payload) {
return state.name + payload.name
}
},
actions: {
aName() {}
},
modules: {
userInfo: {
state: {},
getters: {},
mutations: {},
actions: {}
}
}
})
new Vue({
store
})
state 是响应性的
class Store {
constructor(options) {
this._s = new Vue({
data: {
state: options.state
}
})
}
get state () {
return this._s.state
}
}
getters 是一个代理
const getters = options.getters || {}
Object.keys(getters).forEach((getter) => {
Object.defineProperty(getters, getter, {
get() {
return getters[getter](this.state)
}
})
})
mutations
const mutations = options.mutations;
this.mutations = {};
Object.keys(mutations).forEach(mutation => {
this.mutations[mutation] = (payload) => {
mutations[mutation](this.state, payload)
}
})
commit(type, payload) {
this.mutations[type](payload)
}
actions
const actions = options.actions;
this.actions = {};
Object.keys(actions).forEach(action => {
this.actions[action] = (payload) => {
actions[action](this, payload)
}
})
dispatch(type, payload) {
this.actions[type](payload)
}
React
React fiber 原理及优点
useState 实现原理
function 组件和 class 组件的区别
- 类组件有生命周期,函数组件没有
- 类组件需要继承 Class,函数组件不需要
- 类组件可以获取实例化的 this,并且基于 this 做各种操作,函数组件不行
- 类组件内部可以定义并维护 state, 函数组件通过 hooks 维护 state。
setState 是同步还是异步的
- 17 版本,在调度中的是异步。不在调度中的是同步
- 18 版本,是异步的,
Redux 有哪些原则
- 单一数据源,整个应用的 state 保存在一颗 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
- state 是只读的,唯一改变 state 的方法就是触发 action, action 是用于描述一个已发生事件的对象。
- 使用纯函数来修改,为了描述 action 如何修改state, 需要编写 reducer。reducer 是纯函数,接收以前的 state 和 action, 返回新的 state。
useCallback 的原理
useTransition
为什么有时两次 setState 只执行一次
Redux 中间件机制
React 合成事件
React 性能优化点
受控组件
React 怎么捕获异常
Node
Koa 中间件原理
- 中间件的功能是可以访问请求对象, 响应对象和应用程序的请求-响应周期中通过 next 对下一个中间件函数的调用。
Node require 具体实现
websocket 连接建立的过程
pnpm,yarn, npm 包管理器的特点
进程通信方式
进程和线程的区别
Buffer
Node 中 Clustor 是如何实现端口复用的
peerDependencies 的理解
Node 中如何监听文件变化
Node 模块机制是怎样的
pipe 原理 (nodejs stream)
聊聊对 monorepo 的理解
Nodejs 的异常处理方式
HTTP
TCP 滑动窗口
HTTP 中 GET 和 POST的区别
聊聊 option 请求
浏览器并发连接限制
http 协议中 chunk 传输
http 代理服务器是什么
websocket
HTTP2.0 改进点
HTTP2 有什么问题, HTTP3 是什么
CDN 实现原理
浏览器缓存策略
三次握手和TCP重试机制
性能优化
前端性能优化指标 RAIL
检测页面白屏时间
浏览器处理 100K 的 js 文件和处理 100K 的图片文件,哪种更快
聊聊 JIT 优化是什么
聊聊浏览器缓存体系
前端性能优化
动画性能优化
网站大量图片加载慢的优化
puppeteer 性能
代码优化
Performance api
如何优化 Canvas 性能
为什么会出现白屏
优化页面白屏时间
收集页面异常
webpack
webpack-dev-server 实现原理
webpack HMR 原理
webpack 中的 Dependency Graph 的原理及实现
如何打包 NPM 库
插件机制
webpack 工作原理
loader
算法
合并二维有序数组成一维有序数组
爬楼梯
判断括号字符串有效
二叉树
求解平方根
判断单链表是否有环
斐波那契数列
数组去重
数组中和为 sum 的 n 个数
设计模式
适配器和外观模式的区别
数据结构
堆和栈是计算机内存中的两个重要概念,它们在数据存储和管理方面有着不同的特点和用途。
-
数据结构和管理方式:
- 栈(Stack)是一种后进先出(LIFO)的数据结构,数据按照一定的顺序存储在连续的内存区域中。栈的管理方式由编译器自动处理,包括分配和释放内存,无需手动管理。栈中的数据大小固定,不会动态改变。
- 堆(Heap)是一种动态分配内存的数据结构,数据存储在离散的内存区域中。堆的管理方式由开发人员手动处理,包括手动分配和释放内存。堆中的数据大小可以动态增减。
-
存储对象类型:
- 栈主要用于存储基本数据类型和引用类型的引用(指针),如整数、浮点数、布尔值、指针等。这些数据在栈上分配的内存空间很小,存取速度很快。
- 堆主要用于存储引用类型的对象,如数组、对象、函数等。这些对象在堆上分配的内存空间较大,存取速度相对较慢。
-
内存分配和回收:
- 栈的内存分配和回收是由编译器自动完成的,遵循栈帧(Stack Frame)的方式进行。当函数被调用时,函数的参数、局部变量和返回地址等数据会被分配到栈上,当函数执行完毕后,这些数据会被自动释放。
- 堆的内存分配和回收需要开发人员手动进行管理,通过特定的操作符(如new、delete或malloc、free)来分配和释放内存。如果开发人员没有正确地释放堆上的内存,就会导致内存泄漏。
-
运行速度:
-
由于栈的内存分配和回收是由编译器自动完成的,所以栈的存取速度比较快,效率较高。
-
堆的内存分配和回收需要手动管理,这涉及到更复杂的内存操作,因此堆的存取速度相对较慢,效率较低
-