【详细精选】前端面试题(2026精选附详细解答)包含10w数据展示优化、前端核心

【详细精选】前端面试题(2026精选附详细答案)包含10w数据展示优化、前端核心

【支持与反对请投票和评论区留言】尽管前端已经非常内卷,开猿节流,甚至怀疑会被AI取代,但小y认为:前端依然是一门学科、一个岗位。不管是全栈还是前端,都会有存在的必要和价值

直接上干货!!

前端面试题详细解答

1. ES6新特性详解(重要10个)

核心特性

// 1. let和const - 块级作用域let x =10;// 可重新赋值const y =20;// 不可重新赋值,但对象属性可修改// 2. 箭头函数constadd=(a, b)=> a + b;// 特点:没有自己的this,继承父级this;不能作为构造函数// 3. 模板字符串const name ="John";const greeting =`Hello, ${name}!`;// 支持多行字符串// 4. 解构赋值const[a, b]=[1,2];// 数组解构const{name, age}={name:"John",age:25};// 对象解构// 5. 默认参数functiongreet(name ="Guest"){return`Hello, ${name}`;}// 6. 扩展运算符const arr1 =[1,2];const arr2 =[...arr1,3,4];// [1, 2, 3, 4]const obj1 ={a:1};const obj2 ={...obj1,b:2};// {a: 1, b: 2}// 7. 对象简写const x =10, y =20;const point ={x, y};// 等同于 {x: x, y: y}// 8. Promiseconst promise =newPromise((resolve, reject)=>{setTimeout(()=>resolve("Done"),1000);});// 9. async/await(ES8,但通常归为ES6+)asyncfunctionfetchData(){const data =await promise;return data;}// 10. 类(Class)classPerson{constructor(name){this.name = name;}greet(){return`Hello, I'm ${this.name}`;}staticcreate(name){returnnewPerson(name);}}

其他重要特性

  • 模块化import/export
  • Symbol:唯一标识符
  • Set/Map:新的数据结构
  • for…of循环:遍历可迭代对象
  • 生成器函数function*
  • Proxy/Reflect:元编程
  • 可选链操作符?.(ES2020)
  • 空值合并运算符??(ES2020)

2. 什么是跨域

同源策略

// 同源条件:协议、域名、端口必须完全相同// http://example.com:80 ≠ https://example.com:80 (协议不同)// http://example.com:80 ≠ http://api.example.com:80 (域名不同)// http://example.com:80 ≠ http://example.com:8080 (端口不同)

跨域解决方案

1.CORS(跨域资源共享)
// 服务器设置响应头 res.setHeader('Access-Control-Allow-Origin','http://localhost:3000'); res.setHeader('Access-Control-Allow-Methods','GET, POST, PUT'); res.setHeader('Access-Control-Allow-Headers','Content-Type'); res.setHeader('Access-Control-Allow-Credentials','true');// 允许携带cookie// 简单请求 vs 预检请求// 简单请求:GET/HEAD/POST,Content-Type为特定值// 预检请求:非简单请求前会发送OPTIONS请求
2.JSONP
// 客户端functionhandleResponse(data){ console.log(data);}// 动态创建script标签const script = document.createElement('script'); script.src ='http://api.example.com/data?callback=handleResponse'; document.body.appendChild(script);// 服务器响应handleResponse({data:"some data"});
3. 代理服务器
// 开发环境代理(webpack配置) module.exports ={devServer:{proxy:{'/api':{target:'http://api.example.com',changeOrigin:true,pathRewrite:{'^/api':''}}}}};
4. WebSocket
// WebSocket不受同源策略限制const socket =newWebSocket('ws://api.example.com');
5. Nginx反向代理
# nginx配置 location /api/ { proxy_pass http://api.example.com/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } 

3. 监听数组变化

Vue2的实现原理

// 1. 重写数组方法const arrayProto =Array.prototype;const arrayMethods = Object.create(arrayProto);const methodsToPatch =['push','pop','shift','unshift','splice','sort','reverse']; methodsToPatch.forEach(function(method){const original = arrayProto[method]; Object.defineProperty(arrayMethods, method,{value:function(...args){const result =original.apply(this, args);const ob =this.__ob__;// 获取新增的元素let inserted;switch(method){case'push':case'unshift': inserted = args;break;case'splice': inserted = args.slice(2);break;}// 对新增元素进行响应式处理if(inserted) ob.observeArray(inserted);// 通知依赖更新 ob.dep.notify();return result;},enumerable:false,writable:true,configurable:true});});// 2. 替换数组的原型const arr =[1,2,3]; Object.setPrototypeOf(arr, arrayMethods);

Vue3的实现原理

// 使用Proxy代理整个数组functionreactiveArray(arr){returnnewProxy(arr,{get(target, key){// 处理数组的特殊情况if(key ==='length')return target.length;const value = target[key];// 如果访问的是方法,绑定正确的thisif(typeof value ==='function'){returnvalue.bind(target);}return value;},set(target, key, value, receiver){const oldValue = target[key];// 设置属性值const result = Reflect.set(target, key, value, receiver);// 判断是新增还是修改const type =Number(key)< target.length ?'SET':'ADD';// 触发更新if(type ==='ADD'|| oldValue !== value){trigger(target, key, type);}return result;}});}

4. v-if vs v-show

原理对比

<template> <!-- v-if:条件渲染 --> <div v-if="show">使用v-if</div> <!-- v-show:条件显示 --> <div v-show="show">使用v-show</div> </template> <script> export default { data() { return { show: true }; } }; </script> 

差异对比表

特性v-ifv-show
DOM操作条件为false时,元素从DOM移除元素始终在DOM中,只切换display属性
编译/卸载切换时触发组件的生命周期钩子不触发生命周期钩子
性能初始渲染开销小,切换开销大初始渲染开销大,切换开销小
使用场景不频繁切换,条件很少改变频繁切换,需要保持状态
配合使用可与v-else、v-else-if配合没有配套指令

源码分析

// v-if的编译结果functionrender(){return show ?createElement('div','v-if内容'):createEmptyVNode();}// v-show的编译结果functionrender(){returncreateElement('div',{directives:[{name:'show',value: show }],style:{display: show ?'':'none'}},'v-show内容');}

5. 网页加载优化

性能指标(Core Web Vitals)

  1. LCP(最大内容绘制) < 2.5秒
  2. FID(首次输入延迟) < 100毫秒
  3. CLS(累计布局偏移) < 0.1

优化策略

1. 代码优化
// 代码分割constLazyComponent=()=>import('./LazyComponent.vue');// 路由懒加载const routes =[{path:'/home',component:()=>import('./views/Home.vue')}];// Webpack配置优化 module.exports ={optimization:{splitChunks:{chunks:'all',// 代码分割cacheGroups:{vendor:{test:/[\\/]node_modules[\\/]/,name:'vendors'}}}}};
2. 资源优化
<!-- 图片优化 --><imgsrc="image.jpg"srcset="image-320w.jpg 320w, image-480w.jpg 480w"sizes="(max-width: 600px) 480px, 800px"loading="lazy"<!--懒加载--> alt="描述文本" > <!-- 预加载关键资源 --><linkrel="preload"href="font.woff2"as="font"type="font/woff2"crossorigin><linkrel="preload"href="critical.css"as="style"><linkrel="prefetch"href="next-page.html"><!-- 预取 -->
3. 缓存策略
// Service Worker缓存 self.addEventListener('install',event=>{ event.waitUntil( caches.open('v1').then(cache=>{return cache.addAll(['/','/styles/main.css','/script/main.js']);}));});
4. 使用Lighthouse分析
# 命令行使用 npx lighthouse https://example.com --view # 生成报告 npx lighthouse https://example.com --output=json --output-path=report.json 

6. 浏览器渲染过程

详细流程

1. 构建DOM树
// HTML → DOM树// <html> → DOM节点// <body> → DOM节点// <div> → DOM节点
2. 构建CSSOM树
/* CSS → CSSOM树 */body{font-size: 16px;}div{color: red;}
3. 渲染树构建
  • 结合DOM和CSSOM
  • 排除不可见元素(display: none)
4. 布局(重排)
// 计算每个元素的位置和大小// 触发重排的操作: element.style.width ='100px'; element.style.height ='200px'; window.getComputedStyle(element);
5. 绘制(重绘)
// 填充像素// 触发重绘的操作: element.style.color ='red'; element.style.backgroundColor ='#fff';
6. 合成
// GPU加速的图层合成 element.style.transform ='translateX(100px)';// 触发合成层

优化建议

// 避免强制同步布局functionbadExample(){// 读取 → 写入 → 读取 → 写入const width = element.offsetWidth;// 触发重排 element.style.width = width +10+'px';// 触发重排}functiongoodExample(){// 读取 → 读取 → 写入 → 写入const width = element.offsetWidth;const height = element.offsetHeight; element.style.width = width +10+'px'; element.style.height = height +10+'px';}

7. 节流和防抖

防抖(Debounce)

// 原理:在事件被触发n秒后再执行,如果在这n秒内又被触发,则重新计时functiondebounce(fn, delay){let timer =null;returnfunction(...args){const context =this;// 清除之前的定时器clearTimeout(timer);// 设置新的定时器 timer =setTimeout(()=>{fn.apply(context, args);}, delay);};}// 使用场景:搜索框输入、窗口resizeconst searchInput = document.getElementById('search'); searchInput.addEventListener('input',debounce(function(){ console.log('搜索:',this.value);},500));

节流(Throttle)

// 原理:规定在一个单位时间内,只能触发一次函数// 时间戳实现functionthrottle(fn, delay){let lastTime =0;returnfunction(...args){const now = Date.now();const context =this;if(now - lastTime >= delay){fn.apply(context, args); lastTime = now;}};}// 定时器实现functionthrottle(fn, delay){let timer =null;let lastArgs =null;returnfunction(...args){ lastArgs = args;if(!timer){ timer =setTimeout(()=>{fn.apply(this, lastArgs); timer =null;}, delay);}};}// 使用场景:滚动加载、按钮点击 window.addEventListener('scroll',throttle(function(){ console.log('滚动位置:', window.scrollY);},100));

结合版(加强版节流)

functionenhancedThrottle(fn, delay, options ={}){const{ leading =true, trailing =true}= options;let timer =null;let lastTime =0;let lastArgs =null;returnfunction(...args){const context =this;const now = Date.now();// 计算剩余时间const remaining = delay -(now - lastTime);// 更新参数 lastArgs = args;if(remaining <=0){// 时间到了,执行函数if(timer){clearTimeout(timer); timer =null;}if(leading){fn.apply(context, args);} lastTime = now;}elseif(!timer && trailing){// 设置定时器,确保最后一次执行 timer =setTimeout(()=>{fn.apply(context, lastArgs); timer =null; lastTime = Date.now();}, remaining);}};}

8. 闭包

基本概念

// 闭包:能够访问其他函数作用域中变量的函数functionouter(){const name ="John";// 局部变量functioninner(){ console.log(name);// 访问外部函数的变量}return inner;// 返回内部函数}const closureFn =outer();closureFn();// "John"

实际应用

1. 数据私有化
functioncreateCounter(){let count =0;// 私有变量return{increment(){ count++;return count;},decrement(){ count--;return count;},getCount(){return count;}};}const counter =createCounter(); console.log(counter.increment());// 1 console.log(counter.increment());// 2 console.log(counter.getCount());// 2
2. 函数工厂
functioncreateMultiplier(multiplier){returnfunction(x){return x * multiplier;};}const double =createMultiplier(2);const triple =createMultiplier(3); console.log(double(5));// 10 console.log(triple(5));// 15
3. 模块模式
const myModule =(function(){let privateVar =0;functionprivateMethod(){return privateVar;}return{publicMethod(){ privateVar++;returnprivateMethod();}};})(); console.log(myModule.publicMethod());// 1

内存管理

// 闭包可能导致内存泄漏functionleakMemory(){const largeArray =newArray(1000000).fill('data');returnfunction(){ console.log('仍然持有largeArray的引用');// largeArray不会被垃圾回收};}// 解决方案:及时释放引用functionnoLeak(){let largeArray =newArray(1000000).fill('data');const result = largeArray.length;// 使用完后设为null largeArray =null;returnfunction(){ console.log('不持有largeArray的引用');return result;};}

9. 浏览器线程

主要线程

1. 主线程(UI线程)
// 负责:DOM渲染、JavaScript执行、用户交互// 注意:JavaScript是单线程的 console.log(1);setTimeout(()=> console.log(2),0); console.log(3);// 输出:1, 3, 2(因为有事件循环)
2. 浏览器内核线程
  • GUI渲染线程:解析HTML/CSS,构建DOM树
  • JavaScript引擎线程:执行JavaScript代码
  • 事件触发线程:管理事件队列
  • 定时器触发线程:setTimeout/setInterval
  • 异步HTTP请求线程:XMLHttpRequest

事件循环机制

// 微任务(Microtask) vs 宏任务(Macrotask) console.log('script start');// 同步任务setTimeout(()=>{ console.log('setTimeout');// 宏任务},0); Promise.resolve().then(()=>{ console.log('promise1');// 微任务}).then(()=>{ console.log('promise2');// 微任务}); console.log('script end');// 执行顺序:// 1. script start// 2. script end// 3. promise1// 4. promise2// 5. setTimeout

Web Workers

// 主线程const worker =newWorker('worker.js'); worker.postMessage({data:'Hello'}); worker.onmessage=function(event){ console.log('收到worker消息:', event.data);};// worker.js(另一个线程) self.onmessage=function(event){const result =heavyComputation(event.data); self.postMessage(result);};functionheavyComputation(data){// 耗时操作return data.toUpperCase();}

10. Vue3 vs Vue2区别

核心差异对比表

特性Vue2Vue3
响应式原理Object.definePropertyProxy
Composition APIOptions APIComposition API + Options API
性能较慢更快(打包体积小40%)
TypeScript支持一般完善
Fragment不支持支持多根节点
Teleport不支持支持
Suspense不支持支持
Tree-shaking有限更好的支持

响应式系统

// Vue2响应式const data ={count:0}; Object.defineProperty(data,'count',{get(){ console.log('获取count');return value;},set(newValue){ console.log('设置count'); value = newValue;}});// Vue3响应式const data ={count:0};const proxy =newProxy(data,{get(target, key){ console.log(`获取${key}`);return target[key];},set(target, key, value){ console.log(`设置${key}`); target[key]= value;returntrue;}});

Composition API示例

<template> <div> <p>Count: {{ count }}</p> <p>Double: {{ doubleCount }}</p> <button @click="increment">Increment</button> </div> </template> <script> import { ref, computed, onMounted } from 'vue'; export default { setup() { // 响应式数据 const count = ref(0); // 计算属性 const doubleCount = computed(() => count.value * 2); // 方法 function increment() { count.value++; } // 生命周期 onMounted(() => { console.log('组件已挂载'); }); return { count, doubleCount, increment }; } }; </script> 

性能优化

// Vue3的静态提升const _hoisted_1 ={id:"app"};// 静态节点提升const _hoisted_2 =/*#__PURE__*/createVNode("div",null,"静态内容");// 静态节点// Vue3的Patch Flagconst vnode ={type:'div',props:{id:'app',class:'container'},children:[{type:'span',children:'动态内容',patchFlag:1/* TEXT */}]};

11. new关键字

实现原理

// new关键字的作用functionPerson(name){this.name = name;}const john =newPerson('John');// 模拟new的实现functionmyNew(constructor,...args){// 1. 创建一个空对象const obj ={};// 2. 将对象的原型指向构造函数的prototype Object.setPrototypeOf(obj, constructor.prototype);// 3. 将构造函数的this绑定到新对象const result =constructor.apply(obj, args);// 4. 如果构造函数返回对象,则返回该对象,否则返回新对象return result instanceofObject? result : obj;}const john2 =myNew(Person,'John');

详细步骤分析

functionAnimal(name){this.name = name;this.speak=function(){return`${this.name} makes a noise`;};// 如果构造函数返回一个对象,new表达式会返回这个对象// return { custom: 'object' };}Animal.prototype.eat=function(){return`${this.name} eats food`;};// 使用newconst animal =newAnimal('Dog');// 等同于const animal ={}; animal.__proto__ =Animal.prototype;Animal.call(animal,'Dog');

12. bind、call、apply的区别

基本用法对比

const person ={name:'John',greet:function(greeting, punctuation){return`${greeting}, ${this.name}${punctuation}`;}};const anotherPerson ={name:'Jane'};// call:立即调用,参数逐个传递 person.greet.call(anotherPerson,'Hello','!');// "Hello, Jane!"// apply:立即调用,参数数组传递 person.greet.apply(anotherPerson,['Hi','!!']);// "Hi, Jane!!"// bind:返回新函数,不立即调用const boundGreet = person.greet.bind(anotherPerson,'Hey');boundGreet('?');// "Hey, Jane?"

手写实现

// 实现callFunction.prototype.myCall=function(context,...args){// 如果context是null或undefined,指向全局对象 context = context || window;// 创建唯一key,避免属性冲突const fnKey =Symbol('fn');// 将函数作为context的方法 context[fnKey]=this;// 执行函数const result = context[fnKey](...args);// 删除添加的方法delete context[fnKey];return result;};// 实现applyFunction.prototype.myApply=function(context, argsArray =[]){ context = context || window;const fnKey =Symbol('fn'); context[fnKey]=this;const result = context[fnKey](...argsArray);delete context[fnKey];return result;};// 实现bindFunction.prototype.myBind=function(context,...bindArgs){const originalFn =this;returnfunctionboundFn(...callArgs){// 判断是否作为构造函数调用(使用new)const isConstructorCall =new.target !==undefined;if(isConstructorCall){// 如果是new调用,忽略绑定的thisreturnneworiginalFn(...bindArgs,...callArgs);}else{// 普通调用,使用绑定的thisreturnoriginalFn.apply(context,[...bindArgs,...callArgs]);}};};

实际应用场景

// 1. 借用数组方法处理类数组对象functionsum(){// arguments是类数组,没有数组方法const args =Array.prototype.slice.call(arguments);return args.reduce((acc, val)=> acc + val,0);}// 2. 构造函数继承functionParent(name){this.name = name;}functionChild(name, age){Parent.call(this, name);// 继承属性this.age = age;}// 3. 事件处理函数绑定thisclassButton{constructor(){this.text ='Click me';// 使用bind保持this指向this.handleClick =this.handleClick.bind(this);}handleClick(){ console.log(this.text);}}

13. TypeScript装饰器

装饰器类型

// 类装饰器functionClassDecorator(constructor:Function){console.log('类装饰器执行'); constructor.prototype.newProperty ='added by decorator';}// 方法装饰器functionMethodDecorator( target:any, propertyKey:string, descriptor: PropertyDescriptor ){console.log(`方法装饰器:${propertyKey}`);const originalMethod = descriptor.value; descriptor.value=function(...args:any[]){console.log(`调用方法:${propertyKey}`);returnoriginalMethod.apply(this, args);};}// 属性装饰器functionPropertyDecorator(target:any, propertyKey:string){console.log(`属性装饰器:${propertyKey}`);}// 参数装饰器functionParameterDecorator( target:any, propertyKey:string, parameterIndex:number){console.log(`参数装饰器:${propertyKey}的第${parameterIndex}个参数`);}// 访问器装饰器functionAccessorDecorator( target:any, propertyKey:string, descriptor: PropertyDescriptor ){console.log(`访问器装饰器:${propertyKey}`);}// 装饰器工厂functionLogDecorator(message:string){returnfunction(target:any, propertyKey:string, descriptor?: PropertyDescriptor){console.log(`${message}: ${propertyKey}`);};}

实际应用示例

// 1. 日志装饰器functionlog(target:any, propertyKey:string, descriptor: PropertyDescriptor){const originalMethod = descriptor.value; descriptor.value=function(...args:any[]){console.log(`调用 ${propertyKey},参数:`, args);const result =originalMethod.apply(this, args);console.log(`返回结果:`, result);return result;};}// 2. 自动绑定this装饰器functionautobind( _target:any, _propertyKey:string, descriptor: PropertyDescriptor ){const originalMethod = descriptor.value;const adjustedDescriptor: PropertyDescriptor ={ configurable:true, enumerable:false,get(){// 返回绑定this的方法returnoriginalMethod.bind(this);}};return adjustedDescriptor;}// 3. 验证装饰器functionvalidate( target:any, propertyKey:string, descriptor: PropertyDescriptor ){const originalMethod = descriptor.value; descriptor.value=function(...args:any[]){// 参数验证逻辑 args.forEach((arg, index)=>{if(arg ===undefined|| arg ===null){thrownewError(`参数 ${index} 不能为空`);}});returnoriginalMethod.apply(this, args);};}// 使用示例classUserService{private users:string[]=[];@log@validateaddUser(@ParameterDecorator name:string){this.users.push(name);returnthis.users;}@autobindgetUsers(){returnthis.users;}}

14. 10w数据展示优化

虚拟列表实现

<template> <div ref="container" @scroll="handleScroll" > <!-- 撑开容器,显示滚动条 --> <div :style="{ height: totalHeight + 'px' }" ></div> <!-- 可视区域内容 --> <div :style="{ transform: `translateY(${offset}px)` }" > <div v-for="item in visibleData" :key="item.id" :style="{ height: itemHeight + 'px' }" > {{ item.content }} </div> </div> </div> </template> <script> export default { props: { data: { type: Array, required: true }, itemHeight: { type: Number, default: 50 }, buffer: { type: Number, default: 5 } }, data() { return { startIndex: 0, // 开始索引 endIndex: 0, // 结束索引 offset: 0 // 偏移量 }; }, computed: { // 总高度 totalHeight() { return this.data.length * this.itemHeight; }, // 容器高度 containerHeight() { return this.$refs.container?.clientHeight || 0; }, // 可见区域项数 visibleCount() { return Math.ceil(this.containerHeight / this.itemHeight); }, // 实际渲染的数据 visibleData() { const start = Math.max(0, this.startIndex - this.buffer); const end = Math.min(this.data.length, this.endIndex + this.buffer); return this.data.slice(start, end); } }, mounted() { this.updateVisibleData(); }, methods: { handleScroll() { const scrollTop = this.$refs.container.scrollTop; // 计算开始索引 this.startIndex = Math.floor(scrollTop / this.itemHeight); // 计算结束索引 this.endIndex = Math.min( this.data.length, this.startIndex + this.visibleCount ); // 计算偏移量 this.offset = this.startIndex * this.itemHeight; }, updateVisibleData() { this.startIndex = 0; this.endIndex = Math.min(this.data.length, this.visibleCount); } } }; </script> <style> .virtual-list-container { height: 500px; overflow-y: auto; position: relative; } .virtual-list-phantom { position: absolute; left: 0; top: 0; right: 0; z-index: -1; } .virtual-list-content { position: absolute; left: 0; top: 0; right: 0; } .virtual-list-item { display: flex; align-items: center; padding: 0 16px; box-sizing: border-box; border-bottom: 1px solid #eee; } </style> 

时间分片渲染

// 使用requestAnimationFrame分批渲染functionrenderLargeData(data, container, chunkSize =100){let index =0;functionrenderChunk(){const fragment = document.createDocumentFragment();for(let i =0; i < chunkSize && index < data.length; i++, index++){const item = document.createElement('div'); item.textContent = data[index]; fragment.appendChild(item);} container.appendChild(fragment);// 如果还有数据,继续渲染下一批if(index < data.length){requestAnimationFrame(renderChunk);}}renderChunk();}// 使用Web Worker处理数据const worker =newWorker('data-processor.js'); worker.postMessage({action:'process',data: largeData }); worker.onmessage=function(event){const processedData = event.data;// 在主线程渲染处理后的数据};

15. 时间切片

基本原理

// 使用requestIdleCallback实现时间切片functiontimeSlicingWork(unitsOfWork){let currentIndex =0;functiondoWork(deadline){// 在空闲时间内执行工作单元while(currentIndex < unitsOfWork.length && deadline.timeRemaining()>0){performUnitOfWork(unitsOfWork[currentIndex]); currentIndex++;}// 如果还有工作,继续调度if(currentIndex < unitsOfWork.length){requestIdleCallback(doWork);}else{ console.log('所有工作完成');}}requestIdleCallback(doWork);}// React中的时间切片实现(简化版)functionworkLoop(deadline){let shouldYield =false;while(nextUnitOfWork &&!shouldYield){// 执行工作单元 nextUnitOfWork =performUnitOfWork(nextUnitOfWork);// 检查是否需要让出控制权 shouldYield = deadline.timeRemaining()<1;}// 如果还有工作,继续调度if(nextUnitOfWork){requestIdleCallback(workLoop);}}requestIdleCallback(workLoop);

实际应用示例

// 1. 大数据处理functionprocessBigData(data, processItem, chunkSize =100){returnnewPromise((resolve)=>{let index =0;const results =[];functionprocessChunk(deadline){while(index < data.length && deadline.timeRemaining()>0){const chunk = data.slice(index, index + chunkSize);// 处理数据块for(const item of chunk){ results.push(processItem(item));} index += chunkSize;// 更新进度updateProgress((index / data.length)*100);}if(index < data.length){// 还有数据,继续处理requestIdleCallback(processChunk);}else{// 处理完成resolve(results);}}requestIdleCallback(processChunk);});}// 2. 长列表渲染优化classVirtualScroller{constructor(container, items, renderItem){this.container = container;this.items = items;this.renderItem = renderItem;this.renderedItems =newSet();}renderVisibleItems(){const visibleRange =this.getVisibleRange();const itemsToRender =[];for(let i = visibleRange.start; i < visibleRange.end; i++){if(!this.renderedItems.has(i)){ itemsToRender.push(i);}}// 使用时间切片分批渲染this.renderWithTimeSlice(itemsToRender);}renderWithTimeSlice(itemIndices){let index =0;constrenderBatch=(deadline)=>{while(index < itemIndices.length && deadline.timeRemaining()>0){const itemIndex = itemIndices[index];const item =this.items[itemIndex];// 渲染单个项目const element =this.renderItem(item, itemIndex);this.container.appendChild(element);this.renderedItems.add(itemIndex); index++;}if(index < itemIndices.length){requestIdleCallback(renderBatch);}};requestIdleCallback(renderBatch);}}

React Concurrent Mode中的时间切片

// React 18+中的并发特性import{ startTransition, useDeferredValue }from'react';functionSearchResults({ query }){const deferredQuery =useDeferredValue(query);return(<div><SlowList query={deferredQuery}/></div>);}// 在事件处理中使用startTransitionfunctionhandleChange(e){setInput(e.target.value);// 将setQuery标记为过渡更新startTransition(()=>{setQuery(e.target.value);});}// 这会告诉React这个更新不是紧急的,可以被中断

最后,欢迎对前端岗位是否会被AI取代投票。如觉得面试题有用,评论区留言,会继续更新小中大厂常见精选面试题

Read more

CodeBuddy Code + 腾讯混元打造“AI识菜通“

CodeBuddy Code + 腾讯混元打造“AI识菜通“

目录 CodeBuddy Code + 腾讯混元打造"AI识菜通" CodeBuddy Code使用指南 1. 背景信息 2. 下载安装 3. 登录 4. 测试 腾讯混元API接入指南 1. 开通腾讯混元大模型 2. 获取腾讯云密钥 3. 腾讯混元API文档 AI识菜通开发指南 1. 开发提示词 2. CodeBuddy.md开发文档 3. 全速开发 成果展示 1. 部署阶段 2. 首页 3. 设置API密钥 4. 识别菜单 5. 点餐进入购物车 CodeBuddy Code + 腾讯混元打造"AI识菜通" CodeBuddy

【AI大模型前沿】阿里通义千问 Qwen3-Coder:开启智能代码生成与代理式编程新时代

【AI大模型前沿】阿里通义千问 Qwen3-Coder:开启智能代码生成与代理式编程新时代

系列篇章💥 No.文章1【AI大模型前沿】深度剖析瑞智病理大模型 RuiPath:如何革新癌症病理诊断技术2【AI大模型前沿】清华大学 CLAMP-3:多模态技术引领音乐检索新潮流3【AI大模型前沿】浙大携手阿里推出HealthGPT:医学视觉语言大模型助力智能医疗新突破4【AI大模型前沿】阿里 QwQ-32B:320 亿参数推理大模型,性能比肩 DeepSeek-R1,免费开源5【AI大模型前沿】TRELLIS:微软、清华、中科大联合推出的高质量3D生成模型6【AI大模型前沿】Migician:清华、北大、华科联手打造的多图像定位大模型,一键解决安防监控与自动驾驶难题7【AI大模型前沿】DeepSeek-V3-0324:AI 模型的全面升级与技术突破8【AI大模型前沿】BioMedGPT-R1:清华联合水木分子打造的多模态生物医药大模型,开启智能研发新纪元9【AI大模型前沿】DiffRhythm:西北工业大学打造的10秒铸就完整歌曲的AI歌曲生成模型10【AI大模型前沿】R1-Omni:阿里开源全模态情感识别与强化学习的创新结合11【AI大模型前沿】Qwen2.5-Omni:

低门槛实现 AI 文档解析 | TextIn xParse Dify插件使用教程

低门槛实现 AI 文档解析 | TextIn xParse Dify插件使用教程

TextIn xParse Dify插件简介 Dify是一个开源的大语言模型(LLM)应用开发平台,旨在简化和加速生成式AI应用的创建和部署。它结合了后端即服务(BaaS)和LLMOps的理念,为开发者提供了用户友好的界面和强大的工具,有效降低了AI应用开发的门槛。 TextIn xParse是一个端到端文档处理AI基础设施,致力于将非结构化文档高效转化为可查询、可分析的数据资产。 目前TextIn xParse插件已在Dify市场上架,帮助用户搭建工作流,提供强大的文档解析和处理能力。 * Dify官网地址:https://dify.ai/zh * xParse Dify插件下载地址:https://marketplace.dify.ai/plugins/intsig-textin/xparse xParse在Dify中的使用方法 一、xParse Dify插件亮点 * 多种解析引擎支持:支持TextIn自研高性能解析引擎(推荐)、MinerU、PaddleOCR等多种行业内先进的解析引擎,可根据文档类型灵活选择。 * 强大的文档处理能力:支持PDF、Wor

从指令到执行:OpenClaw 底层原理深度拆解 —— 一台真正会 “动手” 的本地 AI 引擎

从指令到执行:OpenClaw 底层原理深度拆解 —— 一台真正会 “动手” 的本地 AI 引擎

前言 当我们对 OpenClaw 发出一句自然语言指令:“把桌面所有超过一周的截图归档到 D 盘,再把今天的工作记录整理成 Markdown 并推送到 GitHub。” 传统 AI 会给出步骤,而 OpenClaw 会直接做完。 绝大多数文章只告诉你 OpenClaw “能做什么”,却极少解释它到底是如何做到的: * 一段文字,是怎么变成可执行的系统操作? * 它凭什么能跨 IM、跨平台、跨模型统一工作? * 高权限执行,底层是如何保证安全与可控? * 本地运行、隐私闭环,在架构上究竟如何实现? 本文不讲功能、不讲教程,只讲原理。从意图解析、任务编排、执行引擎、权限沙箱到多模态交互,带你从 0 到 1 理解 OpenClaw 的技术本质:它不是一个聊天机器人,而是一套本地优先、可解释、可审计、