HTML 5 新特性

HTML5 新特性 语义标签 增强型表单 视频和音频 Canvas绘图 SVG绘图 地理定位 拖拽API WebWorker WebStorage WebSocket 语义标签 语义化标签使得页面的内容结构化,可以使开发者更方便清晰地构建页面的布局 标签 描述 <header> 定义了文档的头部区域 <footer> 定义了文档的尾部区域 <nav> 定义文档的导航 <section> 定义文档中的书 <acticle> 定义页面独立的内容区域 <aside> 定义页面侧边栏内容 <details> 定义用户可以看到或隐藏的额外细节 <summary> 标签包含details元素的标题 <dialog> 定义对话框 <figure> 定义自包含内容,如图表 <main> 定义文档主内容 增强型表单 HTML5新增input输入特性,改善更好的输入控制和验证 输入类型 描述 color 主要用于选取颜色 date 选取日期 datetime 选取日期(UTC时间) datetime-local 选取日期(无时区) month 选择一个月份 week 选择周和年 time 选择一个时间 email 包含email地址的输入域 number 数值的输入域 url url地址的输入域 tel 定义输入电话号码的字段 search 用于搜索域 range 一个范围内数字值的输入域 HTML5也新增了五个表单元素 ...

September 24, 2024

小红书-社招-5年 · 第 2 轮 · 技术面试

← 第 1 轮 · 返回本次面经 · 已是最后一轮 → 本轮概述: 该轮面试主要考察了浏览器的工作原理、缓存策略、跨域、Vue生命周期、组件通信等方面的知识。题目涉及理论知识和实际应用场景。 本轮共 14 道题。答案默认折叠,便于先自行作答。 1. 详细讲一下从url输入网址到页面渲染的过程 题库原题:简单描述从输入网址到页面显示的过程 题目要点 当输入URL到页面加载完成,发生了以下几个关键过程: DNS解析:浏览器将URL解析为对应的IP地址。这个过程涉及多级DNS服务器,从本地缓存开始,如果没有找到,则递归查询根域名服务器、顶级域名服务器,直到找到目标服务器的IP地址。 TCP连接:浏览器通过三次握手与服务器建立TCP连接。一旦连接建立,浏览器可以发送HTTP请求。 HTTP请求:浏览器构建HTTP请求报文,通过TCP连接发送到服务器。请求报文包含请求行、请求头和请求正文。 服务器处理请求:服务器接收HTTP请求,解析请求内容,执行相应的处理(如数据库查询、文件读取等),并构建HTTP响应报文。 HTTP响应:服务器将响应报文通过TCP连接发送回浏览器。响应报文包含状态码、响应头和响应正文。 浏览器解析渲染:浏览器接收到HTTP响应后,解析HTML文档构建DOM树,解析CSS构建CSSOM树,合并两者形成渲染树,然后开始渲染页面。 连接结束:当浏览器完成页面渲染或收到服务器关闭连接的信号时,浏览器会发送TCP连接关闭的信号,服务器收到后,双方断开连接。 参考答案 很多大公司面试喜欢问这样一道面试题,输入URL到看见页面发生了什么? 简单来说,共有以下几个过程: DNS解析 发起TCP连接 发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 连接结束 下面我们来看看具体的细节。 DNS解析 DNS解析实际上就是寻找你所需要的资源的过程。假设你输入www.baidu.com,而这个网址并不是百度的真实地址,互联网中每一台机器都有唯一标识的IP地址,这个才是关键,但是它不好记,乱七八糟一串数字谁记得住啊,所以就需要一个网址和IP地址的转换,也就是DNS解析。 DNS解析其实是一个递归的过程。 输入www.google.com网址后,首先在本地的域名服务器中查找,没找到去根域名服务器查找,没有再去com顶级域名服务器查找,,如此的类推下去,直到找到IP地址,然后把它记录在本地,供下次使用。大致过程就是.-> .com ->google.com. -> www.google.com.。 (最后这个.对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上) DNS优化 既然已经懂得了解析的具体过程,我们可以看到上述一共经过了N个过程,每个过程有一定的消耗和时间的等待,因此我们得想办法解决一下这个问题! DNS缓存 DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,ISP服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。 DNS负载均衡 比如访问baidu.com的时候,每次响应的并非是同一个服务器(IP地址不同),一般大公司都有成百上千台服务器来支撑访问。DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡。 发起TCP连接 TCP提供一种可靠的传输,这个过程涉及到三次握手,四次挥手。 三次握手 第一次握手: 客户端发送syn包(Seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认; 第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(Seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。 握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。 四次挥手 数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,假设客户端主动关闭,服务器被动关闭。 第一次挥手: 客户端发送一个FIN,用来关闭客户端到服务器的数据传送,也就是客户端告诉服务器:我已经不 会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,客户端依然会重发这些数据),但是,此时客户端还可以接受数据。 FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。 第二次挥手: 服务器收到FIN包后,发送一个ACK给对方并且带上自己的序列号seq,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。 ...

February 1, 2026

小红书-社招-3年 · 第 2 轮 · 技术面试

← 第 1 轮 · 返回本次面经 · 第 3 轮 → 本轮概述: 这一轮主要考察了小程序的性能优化、核心监控指标、首屏时间的计算、业务价值验证、高频事件处理等方面的知识。 本轮共 11 道题。答案默认折叠,便于先自行作答。 1. 小程序性能优化做了哪些事情? 题库原题:小程序可以做哪些性能优化? 题目要点 小程序性能优化围绕逻辑层与视图层分离架构展开,重点是减少 setData 频率与数据体积,控制列表节点数量,优化首包体积与启动链路,并通过分包加载、WXS 与懒加载等手段降低渲染压力。核心原则是减少跨线程通信与避免无意义重渲染,从架构层面解决性能瓶颈。 参考答案 小程序的性能优化,不能只从“前端渲染”角度看。它的运行模型和 Web 不同,存在 逻辑层(JSCore)与视图层(WebView)分离 的架构特征,核心瓶颈往往出在: 跨线程通信成本 setData 传输体积 渲染节点数量 包体与启动链路 优化必须围绕这些机制展开。 一、理解运行架构是前提 以 微信小程序 为例: 逻辑层:JS 执行环境 视图层:WebView 渲染 两层通过 JSON 序列化通信 每一次 setData: 数据序列化 线程间传输 视图层 diff 真实节点更新 所以小程序性能优化的第一原则是: 减少跨线程通信的数据量与次数。 二、控制 setData 的粒度与频率 1. 避免大对象全量更新 错误方式: this.setData({ form: newFormObject }) 如果 form 很大,每次都会整体传输。 正确方式: this.setData({ "form.username": value }) 使用路径更新,最小化数据传输。 2. 合并多次 setData 多次调用: ...

February 1, 2026

小红书-社招-1年 · 第 2 轮 · 技术面试

← 第 1 轮 · 返回本次面经 · 已是最后一轮 → 本轮概述: 这一轮主要考察了项目经验和技术选型,包括Vue3+TS的选择理由、UI框架的优势、TypeScript的应用、组件化方案、Canvas离屏渲染、Service Worker等内容。 本轮共 14 道题。答案默认折叠,便于先自行作答。 1. 讲一下你觉的最有成就感的项目 题目要点 实际问题, 创新性, 用户价值, 项目背景, 技术选型, 实现过程, 最终效果, 亮点, 贡献 参考答案 最有成就感的项目通常是那些能够解决实际问题、具有创新性并且对用户有显著价值的项目。在回答这个问题时,可以从项目的背景、目标、技术选型、实现过程以及最终效果等方面进行详细描述。重点突出项目的亮点和自己在其中的贡献。 2. 项目为什么选择Vue3+TS而非React 题目要点 Vue3 + TypeScript 的选择通常基于团队技术栈一致性、Composition API 带来的逻辑复用能力、与 TypeScript 的良好类型推导,以及在中后台场景中更成熟的生态和更低的工程复杂度,从而提升整体开发效率与可维护性。 参考答案 在技术选型阶段通常会综合考虑团队技术栈、项目复杂度以及开发效率等因素。对于以中后台系统或业务管理平台为主的项目,Vue3 在整体开发体验和约束能力上往往更容易形成统一规范。 首先是框架设计层面的差异。Vue3 通过 Composition API 将逻辑拆分为可组合的函数单元,在复杂业务场景下可以很好地解决 Options API 中逻辑分散的问题,同时又保留了模板语法,使得结构、逻辑、样式之间的职责划分更加清晰。对于需要长期维护的业务项目,这种组织方式通常更容易理解和维护。 其次是 TypeScript 的结合程度。Vue3 在框架层面对 TypeScript 做了较深的适配,例如 defineComponent、setup、ref、reactive 等 API 都有较完整的类型推导能力,配合 &lt;script setup&gt; 可以获得较好的类型提示和开发体验。在大型项目中,类型系统能够帮助提前暴露接口契约问题,提高代码的可维护性。 另外在生态与工程效率方面,Vue3 在国内中后台领域的组件生态较成熟,例如组件库、低代码平台以及相关工具链都比较完善,能够快速搭建业务系统。对于团队成员技术背景主要偏 Vue 的情况下,可以降低学习成本和沟通成本,提高整体开发效率。 从工程复杂度角度看,React 在灵活性上更强,但很多能力需要通过生态组合实现,例如状态管理、表单方案等,需要额外制定规范。Vue3 本身提供了较完整的开发范式,在团队规模较大的情况下更容易形成统一的代码风格。 3. NutUI在营销活动中相比其他UI框架有什么优势 题目要点 移动端, 轻量, 高性能, 易于使用, 组件库, 用户体验, 开发效率, 按需加载, 应用体积 ...

February 1, 2026

字节-技术中台-校招 · 第 2 轮 · 二面

← 第 1 轮 · 返回本次面经 · 已是最后一轮 → 本轮要点: 本次面试主要考察小程序、前端基础及算法等方面的知识。 本轮共 17 道题。答案默认折叠,便于先自行作答。 1. 讲一下你的小程序项目 题目要点 这是一个典型的主观型问题,没有唯一的标准答案。面试官主要考察候选人的项目经验、技术选型能力、问题解决能力以及对小程序生态的整体理解。 答题时建议围绕项目背景、个人职责、技术挑战与解决方案、项目成果与思考等方面展开,体现出系统性和条理性。 参考答案 在我的某某项目中,我主要负责开发一个基于微信小程序的某某功能模块,比如一个校园服务小程序,其中我负责了课程表、成绩查询以及校园活动发布的功能。 项目启动之初,我们对需求进行了详细的分析。我选择了小程序作为技术栈,主要是考虑到其轻量级、无需下载安装的特性,能够快速触达用户,并且微信生态提供了丰富的API支持,例如微信支付、地理位置等,非常适合我们校园服务的场景。在技术选型上,我们使用了原生小程序开发模式,结合了小程序自定义组件的能力,将课程表、活动列表等通用UI和逻辑封装成可复用组件,大大提高了开发效率和代码的可维护性。 在开发过程中,我遇到了一些挑战。例如,课程表数据的展示,由于涉及到大量的时间和格子计算,以及复杂的状态管理,我采用了组件化的方式来解耦视图和逻辑。为了避免频繁调用setData导致性能问题,我仔细规划了数据结构,并通过局部更新和事件代理的方式,将数据更新的粒度控制到最小,确保了界面的流畅性。此外,在处理校园活动图片上传和展示时,也遇到了图片内存飙升的问题,我通过启用lazy-load属性,并对图片进行后端压缩和CDN分发,有效解决了内存占用过高的问题,提升了用户体验。在保证安全性的前提下,对于用户敏感信息,我们严格遵循小程序的加密存储和传输规范。 项目上线后,用户反馈良好,尤其是加载速度快、操作流畅得到了肯定。通过这个项目,我不仅深化了对小程序双线程架构、生命周期、组件化等核心概念的理解,也锻炼了我在实际项目中解决复杂性能问题的能力。同时,也让我认识到在项目开发中,前期的技术选型、架构设计以及对潜在性能瓶颈的预判都是至关重要的。 2. 小程序的架构组成 题目要点 宿主环境: 了解小程序运行的载体,如微信、支付宝等App提供的运行环境。 双线程模型: 掌握小程序的逻辑层和视图层分离,通过异步通信机制进行数据交换。 组件系统: 熟悉小程序内置组件和自定义组件的构成。 数据层: 理解小程序数据管理和更新机制。 小程序生命周期: 熟悉小程序应用和页面的生命周期函数。 参考答案 1.1 原理说明 宿主环境: 小程序运行在一个特定的宿主环境中,这个环境由微信、支付宝等App提供。它为小程序提供了运行所需的API、渲染能力、文件系统等。 双线程模型: 小程序采用双线程模型,即逻辑层和视图层分别运行在不同的线程中。 逻辑层: 运行在JSCore(或V8引擎)中,负责处理业务逻辑、数据请求、数据处理等,使用JavaScript编写。它不直接操作DOM。 视图层: 负责渲染页面,使用WebView(或独立的渲染引擎)渲染WXML和WXSS。 通信机制: 逻辑层和视图层之间通过Native层进行异步通信。视图层将用户操作(如点击、输入)传递给逻辑层,逻辑层处理后将数据变化通知视图层进行更新。 组件系统: 小程序提供了一套丰富的基础组件,如view、text、image等,开发者也可以基于这些基础组件创建自定义组件,实现模块化开发。 数据层: 小程序的数据管理主要通过Page.prototype.data和this.setData进行。数据变化后,通过双线程通信机制同步到视图层,触发视图更新。 1.2 核心用法 + 示例代码 在小程序中,开发者主要通过JavaScript编写逻辑层代码,WXML构建页面结构,WXSS定义页面样式。 app.js 定义小程序的全局逻辑,app.json 进行全局配置,app.wxss 定义全局样式。 每个页面由 .js(逻辑)、.json(配置)、.wxml(结构)、.wxss(样式)组成。 示例:页面数据更新 // page.js Page({ data: { message: 'Hello Mini Program!' }, onLoad: function() { setTimeout(() => { this.setData({ message: 'Data Updated!' }); }, 2000); } }); 这种架构分离了业务逻辑和页面渲染,提高了性能和安全性,也方便平台对小程序进行管控。 1.3 常见误区或面试陷阱 误区: 认为小程序是基于浏览器内核直接运行的H5页面。实际上,小程序运行在独立的宿主环境,有其特定的渲染机制和API。 误区: 将双线程通信理解为同步通信。实际上是异步通信,需要注意数据同步的时序问题。 陷阱: 不清楚小程序无法直接操作DOM的原因,本质上是为了安全和性能考量,避免开发者直接对渲染层进行复杂操作,影响性能和用户体验。 3. 小程序和 H5 在开发和使用上有哪些主要的区别和优势? 题目要点 运行环境: 区分小程序和H5的运行载体和能力限制。 开发模式: 掌握两种技术栈的开发流程和工具链。 性能: 对比加载速度、运行流畅度等方面的差异。 功能和权限: 了解各自能调用的系统能力和接口。 用户体验: 分析用户感知到的流畅性、便捷性。 分发和推广: 比较获取用户、传播的难易程度。 参考答案 1.1 原理说明 ...

September 2, 2025

字节跳动-商业化-校招 · 第 2 轮 · 二面

← 第 1 轮 · 返回本次面经 · 已是最后一轮 → 本轮要点: 本次面试主要考察前端基础(CSS布局、JavaScript原型链)、React框架深入理解(虚拟DOM、性能优化)、设计模式应用以及算法能力。 本轮共 13 道题。答案默认折叠,便于先自行作答。 1. 实现一个三栏布局,左右两侧固定宽度,中间区域自适应 题目要点 面试官出这道题主要想确认哪些知识维度? 考生对CSS布局(如Flexbox, Grid, 浮动, 定位, 表格布局等)的掌握程度。 考生如何处理不同元素之间的空间分配和自适应能力。 该题所考知识点中有哪些高频实际应用点? 页面整体布局,如经典后台管理系统布局(侧边栏固定,内容区自适应)。 组件内部布局,如卡片、列表项中固定图标/按钮,内容区域自适应。 参考答案 1.1 原理说明 三栏布局是一种常见的网页布局方式,其核心在于实现左右两边固定宽度,中间内容区域根据可用空间自适应。这要求布局方案能够灵活处理流体宽度和固定宽度元素的共存,并且能够正确处理元素之间的堆叠和清除浮动等问题。不同的CSS布局技术提供了不同的实现原理和特性,选择合适的方案取决于兼容性要求、布局复杂度和维护成本。 1.2 核心用法 + 示例代码 以下是几种实现三栏布局的常见方法,并说明其原理和适用场景: 1.2.1 Flexbox 布局 原理: Flexbox (弹性盒子) 是一种一维布局模式,它在父容器中管理子项的分布和对齐。通过设置主轴和交叉轴,可以非常灵活地控制子元素的排列。 使用场景: 现代浏览器环境下的首选布局方式,适用于需要灵活对齐、空间分配的场景。 示例代码: <div class="container-flex"> <div class="left">Left</div> <div class="center">Center</div> <div class="right">Right</div> </div> .container-flex { display: flex; /* 开启Flex布局 */ } .left, .right { width: 200px; /* 左右固定宽度 */ flex-shrink: 0; /* 防止收缩 */ } .center { flex-grow: 1; /* 中间区域自适应,占据剩余空间 */ } 优势: 代码简洁,语义化好,对齐和分配空间非常方便。 1.2.2 Grid 布局 ...

September 2, 2025

京东-物流-秋招 · 第 2 轮 · 第二轮

← 第 1 轮 · 返回本次面经 · 已是最后一轮 → 面试时间: 60分钟 本轮共 16 道题。答案默认折叠,便于先自行作答。 1. 前端和后端有什么区别? 题目要点 职责分工不同,前端关注用户体验,后端关注业务逻辑,但需要密切协作完成产品开发。 参考答案 前端和后端在职责、技术栈、关注点等方面都有明显区别。前端主要负责用户界面和交互体验,使用HTML、CSS、JavaScript等技术,关注的是如何让用户更好地使用产品。后端则负责业务逻辑处理、数据存储、系统架构等,使用Java、Python、Node.js等语言,关注的是系统的稳定性、安全性和性能。 工作内容上,前端需要将设计稿转化为可交互的页面,处理用户输入、数据展示、页面跳转等;后端需要设计数据库结构、编写API接口、处理业务逻辑、确保数据安全等。思维方式也不同,前端更多从用户角度思考问题,注重体验和视觉效果;后端更多从系统角度思考,注重逻辑严谨性和数据一致性。 但两者并不是完全独立的,现代Web开发中前后端需要密切协作,通过API接口进行数据交互,共同完成产品功能。随着技术发展,界限也在模糊,比如Node.js让前端开发者也能做后端开发。 2. 如果现在有一个需要前后端协作的功能开发需求,你认为前端和后端在沟通和配合上最重要的是什么? 题目要点 API接口设计一致性、数据格式规范、清晰的沟通方式、完善的联调流程是协作的关键。 参考答案 最重要的是在项目开始前就API接口的设计达成一致。这包括接口的URL设计、请求方法、参数格式、返回数据结构、错误处理方式等。清晰的接口文档能够避免后续很多沟通成本和返工问题。 其次是建立统一的数据格式规范。比如时间格式、状态码定义、分页参数等,这些看似细节的问题如果不提前约定,会在开发过程中产生很多摩擦。还要约定好错误处理机制,什么情况下返回什么状态码,错误信息的格式等。 沟通方式也很重要。建议使用统一的协作工具,如Postman分享API文档,或者使用Swagger等工具生成接口文档。定期的技术评审会议也必不可少,确保双方对需求理解一致。 最后是要建立联调测试的流程。前端可以先用Mock数据开发,后端接口完成后再进行联调,这样能够并行开发,提高效率。 3. 项目是怎么接到的? 题目要点 通过课程项目、实验室项目、实习项目和个人项目等多种渠道积累开发经验。 参考答案 主要通过几个渠道获得项目经验。首先是课程项目,在Web开发、软件工程等课程中,老师会布置一些实际的开发任务,比如开发一个在线学习平台、图书管理系统等。这些项目虽然规模不大,但涵盖了完整的开发流程。 实验室项目是另一个重要来源。导师的研究项目中经常需要开发一些数据展示、实验管理的Web系统,会让研究生参与开发。这类项目更贴近实际应用,需求也更复杂一些。 还有就是实习期间参与的公司项目。虽然作为实习生主要是辅助开发,但能够接触到真实的商业项目,了解完整的产品开发流程。 另外也会主动寻找一些开源项目参与贡献,或者自己发起一些小项目来练习新技术。比如看到一个有趣的API,就会想着用它开发一个小应用来练手。 4. 讲一个你觉得最有成就感的项目 题目要点 科研数据可视化平台,解决了性能优化和数据适配的技术挑战,最终被多个实验室采用。 参考答案 最有成就感的是在实验室开发的一个科研数据可视化平台。这个项目是为了帮助实验室的研究人员更好地分析和展示实验数据。 项目的挑战在于需要处理大量的科研数据,并且要支持多种图表类型的动态切换。数据量大的时候页面会卡顿,用户体验很差。通过学习和实践,使用了虚拟滚动技术处理大列表,用Web Workers在后台处理数据计算,用Canvas替代DOM渲染复杂图表,最终解决了性能问题。 另一个难点是不同研究方向的数据格式差异很大,需要设计一个灵活的数据适配层。通过抽象出通用的数据模型,并提供配置化的字段映射功能,让系统能够适应不同的数据格式。 最终这个平台不仅在我们实验室使用,还被其他几个实验室采用,帮助研究人员提高了数据分析效率。看到自己开发的系统真正解决了实际问题,并且得到用户认可,这种成就感是最大的收获。 5. 前端怎么样才是一种好的体验? 题目要点 性能优化、交互反馈改进、错误处理优化、移动端适配、基于反馈的持续改进。 参考答案 好的前端体验应该是用户感知不到技术存在的体验。首先是性能方面,页面加载要快,交互要流畅,用户不应该感受到明显的等待时间。这需要做好资源优化、懒加载、缓存策略等。 界面设计要直观易懂,用户能够快速找到需要的功能,操作流程要符合用户习惯。响应式设计也很重要,在不同设备上都能提供良好的体验。 交互反馈要及时准确。用户的每个操作都应该有明确的反馈,比如按钮点击效果、加载状态提示、操作结果通知等。错误处理要友好,当出现问题时,要给用户清晰的错误信息和解决建议。 可访问性也是好体验的重要组成部分。要考虑到不同能力用户的需求,比如键盘导航、屏幕阅读器支持等。 最后是要保持一致性,整个应用的交互模式、视觉风格、信息架构都要保持统一,让用户形成稳定的使用预期。 6. 平时怎么学习前端的? 题目要点 系统性学习、实践项目、阅读源码、关注社区、记录总结、保持好奇心。 参考答案 学习前端主要通过几个渠道。首先是系统性学习,通过在线课程平台如慕课网、极客时间等学习完整的技术体系。看技术书籍也很重要,比如《JavaScript高级程序设计》、《CSS权威指南》等经典书籍能够建立扎实的基础。 实践是最重要的学习方式。会跟着教程做一些小项目,然后尝试改进和扩展功能。GitHub上有很多优秀的开源项目,通过阅读源码能够学到很多最佳实践。 技术社区是获取最新信息的重要渠道。经常浏览掘金、思否、MDN等网站,关注前端技术的发展趋势。参加一些技术分享会和线上讲座,能够了解行业动态和实际应用经验。 建立了自己的学习笔记系统,将学到的知识点整理成文档,定期回顾和总结。还会写一些技术博客,通过输出来加深理解。 保持好奇心很重要,看到新技术会主动去了解和尝试。比如最近学习了WebAssembly、微前端等新技术,虽然可能暂时用不到,但能够拓宽技术视野。 7. 最近了解到的新技术讲一下 题目要点 WebAssembly提供高性能计算能力,微前端解决大型应用架构问题,新CSS特性增强布局能力。 ...

July 27, 2025

V8 引擎的优化机制

V8 是 Google 开发的 JavaScript 引擎(用于 Chrome、Node.js 等),它的核心优化机制可以总结为:即时编译(JIT) + 隐式类型优化 + 内联缓存 + 垃圾回收机制,通过这些方式来大幅提升 JS 的执行性能。 一、V8 的执行流程 V8 不直接解释执行 JavaScript,而是: 解析(Parser):将 JS 源码解析为 AST(抽象语法树) 生成字节码(Bytecode):由 Ignition 引擎生成并执行初始字节码 收集类型信息(Profiler):运行时收集变量类型、函数调用等信息 优化编译(JIT):将热点代码交给 TurboFan 引擎编译为高效的机器码 二、核心优化机制 1. 隐藏类(Hidden Class)与内联缓存(Inline Cache) 为了优化对象属性访问,V8 引入了隐藏类机制,类似 C++ 中的类结构: 初次创建对象时,生成一个隐藏类(HiddenClass) 添加属性时会生成新的隐藏类链表结构 相同结构的对象共享隐藏类,从而使访问更快 不要动态给对象添加属性,尽量保持对象结构稳定。 内联缓存:缓存某个属性的访问位置,使得后续同样结构的对象访问不必重新查找。 function Person(name) { this.name = name; } const p1 = new Person("Tom"); const p2 = new Person("Jerry"); // 内联缓存会优化 this.name 的访问路径 2. 类型反馈与优化编译(Type Feedback + JIT) V8 在执行字节码时会收集类型信息(比如函数参数、返回值的类型),并标记频繁调用的代码为“热点代码”: 热点代码会被交给 TurboFan 做优化编译 编译时使用收集到的类型信息来生成专用的机器码(类型特化) 例如: function add(a, b) { return a + b; } add(1, 2); // 优化为整数加法 add("a", "b"); // 类型变化 -> 去优化 不要在同一个函数中混用不同类型,可能导致优化失败或退化。 ...

December 17, 2024

元素、组件、实例和节点

React 中的元素、组件、实例和节点,是React中关系密切的4个概念,也是很容易让React 初学者迷惑的4个概念。现在,老干部就来详细地介绍这4个概念,以及它们之间的联系和区别,满足喜欢咬文嚼字、刨根问底的同学(老干部就是其中一员)的好奇心。 元素 (Element) React 元素其实就是一个简单JavaScript对象,一个React 元素和界面上的一部分DOM对应,描述了这部分DOM的结构及渲染效果。一般我们通过JSX语法创建React 元素,例如: const element = <h1 className='greeting'>Hello, world</h1>; element是一个React 元素。在编译环节,JSX 语法会被编译成对React.createElement()的调用,从这个函数名上也可以看出,JSX语法返回的是一个React 元素。上面的例子编译后的结果为: const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' ); 最终,element的值是类似下面的一个简单JavaScript对象: const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world' } } React 元素可以分为两类:DOM类型的元素和组件类型的元素。DOM类型的元素使用像h1、div、p等DOM节点创建React 元素,前面的例子就是一个DOM类型的元素;组件类型的元素使用React 组件创建React 元素,例如: const buttonElement = <Button color='red'>OK</Button>; buttonElement就是一个组件类型的元素,它的值是: const buttonElement = { type: 'Button', props: { color: 'red', children: 'OK' } } 对于DOM类型的元素,因为和页面的DOM节点直接对应,所以React知道如何进行渲染。但是对于组件类型的元素,如buttonElement,React是无法直接知道应该把buttonElement渲染成哪种结构的页面DOM,这时就需要组件自身提供React能够识别的DOM节点信息,具体实现方式在介绍组件时会详细介绍。 有了React 元素,我们应该如何使用它呢?其实,绝大多数情况下,我们都不会直接使用React 元素,React 内部会自动根据React 元素,渲染出最终的页面DOM。更确切地说,React元素描述的是React虚拟DOM的结构,React会根据虚拟DOM渲染出页面的真实DOM。 组件 (Component) React 组件,应该是大家最熟悉的React中的概念。React通过组件的思想,将界面拆分成一个个可以复用的模块,每一个模块就是一个React 组件。一个React 应用由若干组件组合而成,一个复杂组件也可以由若干简单组件组合而成。 React组件和React元素关系密切,React组件最核心的作用是返回React元素。这里你也许会有疑问:React元素不应该是由React.createElement() 返回的吗?但React.createElement()的调用本身也是需要有“人”负责的,React组件正是这个“责任人”。React组件负责调用React.createElement(),返回React元素,供React内部将其渲染成最终的页面DOM。 既然组件的核心作用是返回React元素,那么最简单的组件就是一个返回React元素的函数: function Welcome(props) { return <h1>Hello, {props.name}</h1>; } Welcome是一个用函数定义的组件。如果使用类(class)定义组件,返回React元素的工作具体就由组件的render方法承担,例如: ...

December 17, 2024

浏览器的缓存机制

一、前言 缓存可以说是性能优化中简单高效的一种优化方式了。一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。 对于一个数据请求来说,可以分为发起网络请求、后端处理、浏览器响应三个步骤。浏览器缓存可以帮助我们在第一和第三步骤中优化性能。比如说直接使用缓存而不发起请求,或者发起了请求但后端存储的数据和前端一致,那么就没有必要再将数据回传回来,这样就减少了响应数据。 接下来的内容中我们将通过缓存位置、缓存策略以及实际场景应用缓存策略来探讨浏览器缓存机制。 如需获取思维导图或想阅读更多优质文章请猛戳GitHub博客 二、缓存位置 从缓存位置上来说分为四种,并且各自有优先级,当依次查找缓存且都没有命中的时候,才会去请求网络。 Service Worker Memory Cache Disk Cache Push Cache 1.Service Worker Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。 Service Worker 实现缓存功能一般分为三个步骤:首先需要先注册 Service Worker,然后监听到 install 事件以后就可以缓存需要的文件,那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件,否则就去请求数据。 当 Service Worker 没有命中缓存的时候,我们需要去调用 fetch 函数获取数据。也就是说,如果我们没有在 Service Worker 命中缓存的话,会根据缓存查找优先级去查找数据。但是不管我们是从 Memory Cache 中还是从网络请求中获取的数据,浏览器都会显示我们是从 Service Worker 中获取的内容。 2.Memory Cache Memory Cache 也就是内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。 一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。 那么既然内存缓存这么高效,我们是不是能让数据都存放在内存中呢? 这是不可能的。计算机中的内存一定比硬盘容量小得多,操作系统需要精打细算内存的使用,所以能让我们使用的内存必然不多。 当我们访问过页面以后,再次刷新页面,可以发现很多数据都来自于内存缓存 内存缓存中有一块重要的缓存资源是preloader相关指令(例如<link rel="prefetch">)下载的资源。总所周知preloader的相关指令已经是页面优化的常见手段之一,它可以一边解析js/css文件,一边网络请求下一个资源。 需要注意的事情是,内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验。 3.Disk Cache Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。 ...

December 17, 2024