A公司一面
1盒模型
块级盒模型,内联盒模型(转换---display:block,inline)
块级盒模型不设置宽高默认与父容器一样宽,每个块级模型会自动换行,
内联盒模型宽高无效
组成部分:margin,padding,border,content
标准盒模型,怪异盒模型(box-sizing:content-box、border-box)
2.块级元素水平垂直居中的方法
--------------------display: flex + margin: auto---------------
.wrapper {
background: yellow;
width: 500px;
height: 300px;
display: flex;
}
.block {
background: red;
width: 150px;
height: 150px;
margin: auto;
}
------------------display: flex + 主侧轴居中对齐---------------------
.wrapper {
background: yellow;
width: 500px;
height: 300px;
display: flex;
justify-content: center;
align-items: center
}
.block {
background: red;
width: 150px;
height: 150px;
}
----------------calc 计算函数 + 相对定位-------------
.wrapper {
position: relative;
background: yellow;
width: 500px;
height: 300px;
}
.block {
position: relative;
background: red;
width: 150px;
height: 150px;
top: calc(50% - 75px);
left: calc(50% - 75px);
}
3.js基本数据类型
null空值,undefined未定义String Number Boolean,Object
4.原型链?_proto 和prototype的区别?
__proto__属性是对象独有的,而prototype是函数独有的属性。
js里万物皆为对象,包括function,所以function也具有__proto__属性。
_proto__的作用就是指向它的原型对象,通俗来说的父对象。
当我们访问一个对象的属性时,对象内没有这个属性,就会访问__proto__指向的父对象,
若父对象也没有则会继续向上查找,直到顶端null。这就是原型链。
5,闭包
6.事件循环,(宿主环境)node、浏览器的事件循环的区别
宏任务包括:scrip整体代码、setTimeout、setInterval、setImmediate、I/O操作、UI 渲染
微任务包括:process.nextTick、Promise、Async/Await、MutationObserver
浏览器事件循环机制中,微任务的任务队列是在每个宏任务执行完之后执行。
Node事件循环机制中,微任务会在事件循环的各个阶段之间执行
一个阶段执行完毕,就会去执行微任务队列的任务。
微队列 > 延时队列 > 交互队列
7.为什么要用ts?
类型的定义,和编译器的代码校验,可使js代码更加规范,更具可读性,更容易排查错误
TS是JS的超集和延伸,TS可使用JS的库和代码
TS兼容性强,支持ES678
8webpack常用优化手段?打包太大如何处理,具体优化?
1、优化Loader搜索范围:
对于
Loader
来说,影响打包效率首当其冲必属Babel
了。因为Babel
会将代码转为字符串生成AST
,然后对AST
继续进行转变最后再生成新的代码,项目越大,转换代码越多,效率就越低。当然了,我们是有办法优化的。Webpack 是一个常用的前端构建工具,用于打包和编译 JavaScript、CSS、图片等资源文件。随着项目规模的增大,Webpack 打包后的文件大小也会变得越来越大,影响了页面的加载速度和性能。以下是一些常用的 Webpack 优化手段和具体优化建议:
代码分割(Code Splitting):通过将代码切分成多个小块,可以减少打包文件的大小。Webpack 支持多种代码分割方案,如使用
import()
动态导入、使用webpack.optimize.CommonsChunkPlugin
插件提取公共代码等。压缩代码:可以使用 Webpack 插件,如
UglifyJSPlugin
、terser-webpack-plugin
等来对代码进行压缩和混淆,减少文件大小。懒加载(Lazy Loading):对于一些较大的组件或页面,可以使用懒加载的方式,当组件或页面需要使用时再进行加载,从而减少首次加载时的文件大小。
图片压缩:使用 Webpack 插件,如
image-webpack-loader
来对图片进行压缩,减小图片文件的大小。移除未使用的代码:使用
Tree shaking
技术可以移除未使用的代码,减少文件大小。使用 CDN:将静态资源文件(如图片、字体等)托管在 CDN 上,减少文件请求和传输时间,提高页面的加载速度。
使用缓存:使用 Webpack 插件,如
cache-loader
、hard-source-webpack-plugin
等,可以将构建过程中的一些中间文件缓存起来,提高构建速度。
9.上线流程?
10.为什么老的项目加载页面要加载那么久?
页面体积过大:老的项目可能存在过多的冗余代码和资源文件,导致页面体积过大,加载时间过长。可以使用工具对项目进行代码压缩、资源文件优化等,减小页面体积。
服务器带宽限制:老的项目可能运行在带宽较小的服务器上,导致加载速度慢。可以升级服务器带宽或将项目迁移到带宽更大的服务器上,提高加载速度。
数据库性能问题:老的项目可能存在数据库性能问题,导致数据读取速度慢,从而影响页面加载速度。可以对数据库进行性能优化,如建立索引、合理分表等,提高数据读取速度。
缓存机制不完善:老的项目可能缺乏缓存机制,导致每次请求都需要重新加载数据,从而导致页面加载速度慢。可以对项目进行缓存优化,使用浏览器缓存、CDN 缓存等方式,减少请求次数和加载时间。
前端代码质量问题:老的项目可能存在前端代码质量问题,如代码耦合度高、性能低下等,导致页面加载速度慢。可以对前端代码进行优化,如分离组件、按需加载等,提高页面加载速度。
综上所述,对老的项目进行性能优化是提高页面加载速度的关键。需要对项目进行全面的分析和优化,从代码、资源、服务器、数据库等多个方面入手,优化项目性能,提高用户体验
11为什么要用微前端?写在同一个项目里面不行么?除了qiankun微前端的方案?
微前端是一种将前端应用程序拆分为更小、更易于维护的部分的方法,每个部分都可以由不同的团队开发和维护。这种方法可以使团队更加灵活、快速地开发和发布应用程序,同时也可以减少代码冲突和依赖冲突的可能性。
在同一个项目中编写所有代码可能会导致代码库过于庞大,难以维护和更新。而且,如果应用程序需要不断增长和扩展,它可能会变得笨重、不可靠或不易于理解。因此,将应用程序拆分为更小的部分,使不同的团队可以独立地开发和部署这些部分,可以帮助应用程序更好地适应变化和成长。
除了qiankun微前端的方案,还有其他的微前端解决方案。一些流行的解决方案包括Single-SPA、Mosaic、Piral、Luigi等等。选择哪种方案最适合您的应用程序取决于您的具体需求和技术堆栈。
。可以兼容不同的技术栈,每个子系统的技术栈都可以是不一样的。
。提高打包速度和部署速度
。无需顾及其它的模块如何编写,只需要管好自己的模块即可。每个子系统更加容易维护
A公司二面(leader面):
1,自我介绍
- 介绍自己的姓名和目前的职业身份,例如:“我是XXX,目前是一名前端开发者。”
- 提到自己的工作经验和技能,例如:“我有XX年的前端开发经验,精通HTML、CSS、JavaScript以及React等技术栈。”
- 强调自己的解决问题能力和独立开发能力,例如:“我擅长解决复杂的前端问题,并有独立开发项目的能力。”
- 提到自己对前端技术的热情和兴趣,例如:“我对前端技术充满热情,经常关注最新的前端技术和趋势,并不断学习提升自己的技能。”
- 最后,可以简单介绍一下自己的兴趣爱好或其他与工作相关的信息,例如:“在业余时间,我喜欢阅读前端技术相关的书籍,或者参加一些技术社区的活动。”
综上所述,自我介绍应该简洁明了,重点突出自己的工作经验、技能和热情,并且要展现出对前端技术的深入了解和不断学习的态度。
2.排序算法有多少?讲解下详细的冒泡排序?复杂度是多少?了解快排么?
序算法是一种用于排序一组数据的算法。常见的排序算法有多种,以下是其中的几种:
- 冒泡排序(Bubble Sort)
- 插入排序(Insertion Sort)
- 选择排序(Selection Sort)
- 快速排序(Quick Sort)
- 归并排序(Merge Sort)
下面简单介绍一下冒泡排序算法:
冒泡排序是一种简单的排序算法。它的思想是通过重复交换相邻两个元素的位置来实现排序。具体的步骤如下:
- 从第一个元素开始,依次比较相邻的两个元素的大小,如果前面的元素大于后面的元素,则交换它们的位置。
- 对每一对相邻的元素都做相同的操作,从第一对到最后一对,这样一次遍历后,最后一个元素就是最大的元素。
- 针对所有未排序的元素重复以上步骤,直到所有元素都排序完成。
冒泡排序的时间复杂度为 O(n^2),其中 n 是待排序元素的数量。具体的分析可以使用大 O 表示法进行推导。
以下是冒泡排序的示例代码(使用 JavaScript 语言实现):
javascriptCopy code
function bubbleSort(arr) {
var len = arr.length;
for (var i = 0; i < len - 1; i++) {
for (var j = 0; j < len - i - 1; j++) {
if (arr[j] > arr[j+1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
} } }
return arr; }
快速排序是另一种常见的排序算法,它的时间复杂度为 O(n log n)。快排的基本思路是选择一个基准元素,将数组分成两个子数组,一个子数组中的元素都小于基准元素,另一个子数组中的元素都大于基准元素,然后递归地对这两个子数组进行排序。
以下是快速排序的示例代码(使用 JavaScript 语言实现):
javascriptCopy code
function quickSort(arr) {
if (arr.length <= 1) { return arr;
}
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
var left = []; var right = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] < pivot) { left.push(arr[i]);
} else { right.push(arr[i]);
} }
return quickSort(left).concat([pivot], quickSort(right)); }
综上所述,不同的排序算法有不同的适用场景和性能特点,根据实际的需求和数据规模选择合适的排序算法非常重要。
3.斐波那契数列?二叉树高度怎么算?
4.Vue的生命周期?
父beforeCreate > 父created > 父beforeMount > 子beforeCreate > 子created > 子beforeMount > 子mounted > 父mounted
更新
父beforeUpdate > 子beforeUpdate > 子updated > 父updated
销毁
父beforeDestroy > 子beforeDestroy > 子destroyed > 父destroyed
父子组件及mixin的生命周期执行顺序
mixin的生命周期钩子在组件的生命周期钩子之前执行在父组件中引入了mixin,生命周期顺序如下:
mixin的beforeCreate > 父beforeCreate > mixin的created > 父created > mixin的beforeMount > 父beforeMount > 子beforeCreate > 子created > 子beforeMount > 子mounted > mixin的mounted >父mounted
5.MWM和MVC的区别?
MVC 通过分离 Model、View 和 Controller 的方式来组织代码结构。 其中 View 负责页面的显示逻辑,Model 负责存储页面的业务数据及操作。 View 和 Model 应用了观察者模式, 当 Model 层发生改变的时候它会通知有关 View 层更新页面。
Controller 层是 View 层和 Model 层的纽带,它主要负责用户与应用的响应操作,当用户与页面产生交互的时候,Controller 中的事 件触发器就开始工作了,通过调用 Model 层,来完成对 Model 的修 改,然后 Model 层再去通知 View 层更新。
(2)MVVM MVVM 分为 Model、View、ViewModel:
Model 代表数据模型,数据和业务逻辑都在 Model 层中定义;
View 代表 UI 视图,负责数据的展示;
ViewModel 负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作; Model 和 ViewModel 之间有着双向数据绑定的联系。因此当 Model 中 的数据改变时会触发 View 层的刷新,View 中由于用户交互操作而改变的数据也会在 Model 中同步。 这种模式实现了 Model 和 View 的数据自动同步,因此开发者只需要 专注于数据的维护操作即可,而不需要自己操作 DOM。
6.作用域与作用域链?
分为全局作用域、函数作用域和块级作用域
它就是一套规则,js会遵循这套规则来存储变量和查找变量。那JS引擎对我们的源代码进行一个词法分析、语法分析以及生成可执行的代码的工作。收集所有声明的标志符组成的一系列的查询,而用来制定一个规则确定当前执行的代码对这些标志符的访问权限,叫做作用域。那因为作用域制定了访问权限的规则,因此就形成了一个域的概念,也就是说在不同域下生命的变量,它是有访问权限的,这样就起到一个隔离变量的作用。作用域它是确定在编译阶段就已经确定好了,不会再变了
全局作用域是在任何地方都能访问到对象。比如说我们这个window对象。那函数作用域,是存在于函数内部的,声明为一个函数逐级的嵌套下去,一个函数a,它属于全局作用域,在函数a的内部我们再声明一个函数B。那么这个函数B就属于函数a,这个作用域下面,那它查找规则是这样的,他会先在函数B这个作用域去看一下有没有声明内这个变量,有,那么它就输出字符B,B作用域下面没有声明,他就会往上查找,那像这样主体向上查找就是作用链。
7.前端为什么会走向现在的这个方向(指编译后再执行)?
8.node现在可以做后台应用,你怎么看?
Node.js的优势,是降低开发的成本,以及提高开发人员的生产率。实际上,更重要的是,Node.js可以通过如下方面,为开发项目极大地提高应用程序的性能:
Node.js是无阻塞的,可以执行多项任务,并提供异步功能。由于进程是在某个线程中,而不是在队列中处理,因此它提高了服务器的活动性。Node.js采用的是JavaScript最快的V8 Chrome引擎。Node.js让应用程序更具有可扩展性。
实际传统的NodeJS开发在中大型项目上成功案例不多,即使在阿里大厂也仅仅是做中间层或者一些长尾应用上使用而已。其根本原因在于:NodeJS的后端开发群众基础和生态太弱
9.node有哪些做后台服务的中间件?
Node.js是一个非常流行的后端JavaScript运行时环境,有许多中间件可以用于构建后端服务。以下是一些常见的Node.js后端服务中间件:
Express:Express是一个流行的Web应用程序框架,可用于构建RESTful API和Web应用程序。它提供了路由、中间件、模板引擎和错误处理等功能。
Koa:Koa是一个轻量级的Web应用程序框架,与Express类似,但使用了ES6的Generator函数和async/await语法糖,使代码更加简洁、易读。
Connect:Connect是一个可插拔的中间件框架,可以将多个中间件组合在一起,构建复杂的Web应用程序。它与Express兼容,可以使用Express的中间件。
10.node如何启动一个应用服务器?
启动一个基本的Node.js应用服务器,需要以下几个步骤:
- 创建一个Node.js文件,例如app.js。可以使用文本编辑器打开该文件,输入以下代码:
const http = require('http'); const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello, World!\n'); }); server.listen(3000, () => { console.log('Server running at http://localhost:3000/'); }); 上述代码创建了一个HTTP服务器,监听端口号为3000。 当服务器收到请求时,它将响应“Hello, World!”文本。 node app.js 这将启动应用程序并监听端口号3000。可以使用Web浏览器访问http://localhost:3000/,应该会看到“Hello, World!”文本。如果看到这个文本,说明Node.js应用程序已经成功启动。 注意,这只是一个非常基本的示例,实际的Node.js应用程序可能需要使用其他模块或框架,如Express或Koa,来构建更复杂的服务器应用程序。
B公司一面:
1.自我介绍
2.前端端了解的技术栈掌握了多少? 聊一些比较擅长的
熟练掌握Vue和React的核心概念和使用方法,能够快速上手开发项目。可以谈谈自己对Vue和React的理解和认识,以及如何在项目中运用Vue和React的特性来提高开发效率和代码质量。
熟悉Vue和React的常用组件和库,能够根据项目需求选择合适的组件和库。可以谈谈自己在项目中使用过哪些常用组件和库,以及如何使用这些组件和库来实现项目需求。
对Vue和React的性能优化有一定的经验,能够针对项目进行性能分析和优化。可以谈谈自己在项目中如何对组件、网络请求、渲染性能等进行优化,提高项目的性能和用户体验。
对Vue和React的生态圈有一定的了解,能够根据项目需求选择合适的插件和库。可以谈谈自己在项目中使用过哪些插件和库,以及如何根据项目需求选择合适的插件和库。
在项目中使用Vue和React的同时,能够熟练使用相关的工具和框架,如Vue Router、Vuex、Redux等,来提高开发效率和代码质量。
聊了React的Hooks几个钩子的用法,聊了React Fiber的双缓存架构
React Hooks 可以让函数组件也拥有状态和生命周期等功能。常用的 Hooks 包括 useState、useEffect、useContext、useReducer、useCallback、useMemo 等。
useState:useState Hook 可以让函数组件拥有状态。它返回一个数组,第一个值是当前状态的值,第二个值是修改状态的函数。
const [count, setCount] = useState(0);
useEffect:useEffect Hook 可以让函数组件拥有生命周期。它可以在组件渲染完成、更新完成、卸载完成等时刻触发回调函数。
useEffect(() => { // do something return () => { // cleanup } }, [count]);
useContext:useContext Hook 可以让函数组件访问 Context 中的值。
const theme = useContext(ThemeContext);
useReducer:useReducer Hook 可以让函数组件拥有状态和状态修改函数。它类似于 Redux 中的 reducer。
const [state, dispatch] = useReducer(reducer, initialState);
useCallback:useCallback Hook 可以缓存一个回调函数,避免因为引用变化导致组件重新渲染。
const handleClick = useCallback(() => { // do something }, [count]);
useMemo:useMemo Hook 可以缓存一个值,避免因为计算复杂度导致组件重新渲染。
const result = useMemo(() => { // do some complex calculation return result; }, [input]);
React Fiber,它采用双缓存架构来实现高效的渲染。React Fiber 的双缓存架构包括两个工作单元:当前工作单元和备用工作单元。在渲染过程中,React 会先将更新计划写入备用工作单元,然后再将备用工作单元交换为当前工作单元,从而实现无缝的更新。这种双缓存架构可以避免因为更新过程中出现的卡顿和闪烁等问题,从而提高了应用的渲染效率和用户体验。
3.转前端的原因?
4.聊一个的项目的技术难点?
5.有没有接触过TOC的特征,ToB和ToC的区别,TOB和To分别有什么特征,自己想从事的领域节奏应该是什么样的?
- ToB(面向企业)的特征
面向企业的 TOC 通常会关注以下几个方面:
- 效率提升:帮助企业提升业务效率,降低成本;
- 数据安全:提供可靠的数据保障和安全性;
- 定制化:可以根据企业需求进行定制化开发,满足不同的业务需求;
- 服务支持:提供专业的技术支持和售后服务。
- ToC(面向消费者)的特征
面向消费者的 TOC 通常会关注以下几个方面:
- 个性化:提供个性化的服务,根据消费者需求进行定制化;
- 用户体验:注重产品的用户体验,提供便捷的操作和友好的界面;
- 社交性:支持社交互动和分享,增强用户粘性;
- 便利性:提供便捷的服务,减少用户的等待时间和工作量。
聊了客户集体、并发性、兼容性等内容,以及关注的点不一样 (B->效率,C->体验)
6.你觉得你的前端还有哪些方向要补充的,转行对你有没有什么利益得失?
聊了性能、工程化、低代码、node等
7.对哪些技术吃的比较深一点?
8.Hooks的方式解决了什么问题?
以下是 React Hooks 解决的一些问题:
- 复用逻辑
在 React 16.7 之前,只有类组件才能使用状态和其他 React 特性,而函数组件只能是简单的纯函数。这导致开发者在实现复杂逻辑时不得不使用高阶组件、Render Props 等方式来复用代码。而使用 Hooks,可以将复杂逻辑封装成一个自定义 Hook,然后在不同的函数组件中进行复用,提高了代码的可读性和可维护性。
- 状态管理
在类组件中,通过 setState() 方法可以更新组件的状态。但是,在类组件中使用状态有时会产生不必要的代码复杂度,比如需要手动绑定 this、需要考虑 this 指向问题等。而 Hooks 的 useState() 方法可以让开发者在函数组件中使用状态,避免了这些问题。
- 生命周期
在类组件中,生命周期函数可以让开发者在组件生命周期的不同阶段执行相应的操作。但是,生命周期函数会让代码变得复杂和难以维护。而使用 Hooks,可以使用 useEffect() 方法在组件生命周期的不同阶段执行操作,使代码更加简洁和易于维护。
- 性能优化
在类组件中,为了优化性能,有时需要使用 shouldComponentUpdate() 方法进行组件的比较和更新。但是,这也会带来额外的代码复杂度。而使用 useMemo() 和 useCallback() 方法可以帮助开发者优化性能,减少不必要的组件更新,同时使代码更加简洁。
综上,React Hooks 在函数组件中引入了状态和其他 React 特性,使得开发者能够更方便地复用逻辑、管理状态、处理组件生命周期和优化性能,从而提高了代码的可读性和可维护性。
9.使用Hooks的方式,如何避免组件重复渲染?
10.既然避免重复渲染要我们自己去做,那useMemo和useCallback这些api是不是不应该存在呢?
useMemo
和useCallback
都是 React Hooks 中提供的用于性能优化的 API
- 提高性能
useMemo
和useCallback
都可以避免不必要的计算或函数创建,从而提高了应用的性能。useMemo
可以缓存函数的计算结果,避免多次计算相同的值,而useCallback
可以缓存函数的引用,避免函数重复创建,从而减少不必要的渲染和更新。
- 简化代码
使用
useMemo
和useCallback
可以使代码更加简洁,减少不必要的重复代码。例如,可以使用useMemo
缓存计算结果,然后在 JSX 中直接使用该结果,而不需要在每次渲染时都重新计算;使用useCallback
可以缓存回调函数的引用,避免在每次渲染时都创建新的回调函数。
- 更好的代码组织和可读性
使用
useMemo
和useCallback
可以更好地组织代码,使得代码的逻辑更加清晰。例如,可以将复杂的计算逻辑封装在一个useMemo
中,将回调函数封装在一个useCallback
中,从而使代码更加可读和易于维护。
- 支持条件渲染
使用
useMemo
和useCallback
可以支持条件渲染,即只有在某些条件满足时才执行相应的计算或创建函数。例如,在某些情况下,只有在某个状态发生变化时才需要重新计算某个值,这时可以使用useMemo
实现条件渲染。
11.浏览器如何解析页面?
- 接收服务器返回的静态资源后,对HTML文件进行解析,生成 DOM 树,也就是AST语法树。
- 解析 CSS 文件,生成 CSSOM 树。
- 将 DOM 树和 CSSOM 树合并,生成渲染树renderTree。
渲染树是一种包含了所有需要显示的元素的树形结构,但它并不包含所有元素,例如设置了 display:none 的元素不会被包含在渲染树中。
- 计算元素在视口中的位置和大小,生成布局。
- 将布局绘制到屏幕上,生成最终的页面。
最后,浏览器会将布局绘制到屏幕上,生成最终的页面。在绘制过程中,浏览器会将页面分成多个图层,对每个图层进行绘制,最后将这些图层合成为一个整体。
浏览器会使用缓存、预解析等技术来加速页面加载和渲染。
12.什么是重绘重排?
接收服务器返回的静态资源后,对HTML文件进行解析,生成 DOM 树,也就是AST语法树,解析 CSS 文件,生成 CSSOM 树。将 DOM 树和 CSSOM 树合并,生成渲染树renderTree
渲染树的根节点开始遍历,确定每个节点的位置信息尺寸大小,第一次确定节点的几何信息叫做布局,那后续当节点大小位置改动,就需要重新计算,这个时候就叫做回流
接着将每个节点绘制在屏幕上(背景色,什么字体颜色),这个阶段就叫做重绘。
那发生回流会重新计算节点的几何信息,而重绘不会重新计算,它直接进行绘制,所以显而易见的回流比重绘的代价更高,一些常见的触发重排和重绘的操作包括:
- 修改元素的几何属性,如宽度、高度、位置等。
- 修改元素的内容,包括文本、图片、子元素等。
- 修改元素的样式,如颜色、背景、字体等。
- 改变页面的结构,如添加、删除、移动元素等。
为了减少重排和重绘的次数,可以采用一些优化技巧,例如:
- 将修改样式的操作集中在一起执行,以减少重绘次数。
- 避免在布局或绘制时修改 DOM,可以先将其从文档流中删除,修改完成后再重新插入。
- 使用 CSS3 的 transform 和 opacity 属性可以避免对布局的影响,从而减少重排的次数。
- 避免频繁修改元素的样式或几何属性,可以使用 debounce(防抖)和throttle(节流)等技术来控制触发的频率。
13.文档中遇到第三方js资源,加载顺序及执行顺序?有什么策略控制加载顺序?说一下async和defer?
<script> 会阻塞HTML的解析
1通常要放在<body>内容的最后;
2使用defer属性提前加载外部脚本,但推迟到文档解析完后再执行,执行顺序与标签次序一致;
3使用async属性实现外部脚本加载过程中不阻塞页面解析,加载完成后停止页面解析并执行代码,执行顺序取决于加载完成的顺序;
4模块脚本的加载执行顺序与<script defer>一致;
async属性适用于内联的模块脚本。
14.有没有专门对性能优化做处理? 你做过哪些优化?
1、减少请求数量
1.1 图片处理
- 图片压缩:对于清晰度要求不高
- webpack 插件 npm install imagemin-webpack-plugin --save-dev 压缩
- 图片懒加载
- 对于那种图片比较多的页面,仅展示可视窗口内的图片,其他的等滚动到可视窗口再加载;
- 图片轮播组件也可以使用懒加载
- 懒加载方案:图片地址存放 img 标签的某个属性上,例如
data-src
,当图片再可视窗口范围内时,将src
属性替换成图片地址data-src
的值。- 把原本的 :scr="url", 替换为 v-lazy="url" vue-lazyload
- 使用字体图标来代替图片
- CSS 替换实现
1.3 使用缓存
使用cache-control或expires这类强缓存1.4 不使用css@import
使用css@import会造成额外的请求1.5 避免使用空的src和href
a标签设置空的href,会重定向到当前页面的地址
form设置空的method,会提交表单到当前页面的地址2、减少资源大小(压缩)
3、优化网络连接3.3 持久连接
使用keep-alive或者persistent来建立持久连接,降低了延时和连接建立的开销4、优化资源加载
4.1 资源加载位置4.2 资源加载时机
5、减少重绘回流
6、性能更好的API7、webpack性能优化
7.1 打包公共代码
使用CommonChunkPlugin插件,将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存到缓存区中供后续使用置项7.2 动态导入和按需加载
webpack提供了两种技术通过模块内联函数用来分离代码,优先选择的方式是ECMAScript提案的import()语法,第二种则是使用webpack特定的require.ensure7.3 删除无用的代码
tree shaking是一个术语,通常用于移除Javascripy上下文中的未引用代码7.4 长缓存优化
1、将hash替换成chunkhash,这样当chunk不变的时候,缓存依然有效
2、公共代码内联
使用html-webpack-inline-chunk-plugin插件将manifest.js内联到html文件中
15webpack之外的其他工具了解么? vite和webpack的区别?
1、webpack 服务器 启动速度比vite慢;由于vite启动的时候不需要打包,也就无需分析模块依赖、编译,所以启动速度非常快。
2、vite热更新比webpack快;vite在HRM方面,当某个模块内容改变时,让浏览器去重新请求该模块即可。
16上段工作的收获有哪些?17.最近在看什么书?
18.是否有做过npm包?
19.设计模式有哪些实践?
20.你提到过低代码,为什么会对低代码有兴趣?
反问:1.进来的话会充当什么角色,需要做的工作职责?
2.前端的技术栈主要用哪些?
3.项目组会变动么?
B公司二面(技术leader面)
1接触过前端工程化么?对前端工程化了解多少?
前端工程化就是为了让前端开发能够自成体系,个人认为应该从模块化、组件化、规范化、自动化四个方面思考。
2.你们公司的开发流程是怎样的?
3.你不喜欢和什么样的人合作?