2023.10.02 - 2023.10.21 更新前端面试问题总结(16道题)
获取更多面试相关问题可以访问
github 地址: github.com/pro-collect…
gitee 地址: gitee.com/yanleweb/in…
目录:
-
中级开发者相关问题【共计 8 道题】
- 586.[React] react router 主要包有哪些,主要 api 有哪些?【web框架】【出题公司: 阿里巴巴】
- 588.全局样式命名冲突和样式覆盖问题怎么解决?【热度: 772】【CSS】【出题公司: 腾讯】
- 589.css module 是什么?【热度: 346】【CSS】【出题公司: 腾讯】
- 591.[React] useLayoutEffect 和 useEffect 有什么区别?【热度: 313】【web框架】【出题公司: 腾讯】
- 595.[Vue] 响应式为何要从 Object.defineProperty 改为 proxy?【热度: 352】【工程化】【出题公司: 阿里巴巴】
- 599.[代码实现] 不使用 setTimeout 来实现 setInterval【热度: 231】【代码实现/算法】【出题公司: 腾讯】
- 600.[代码实现] 手写 dom 分段渲染【热度: 280】【代码实现/算法】【出题公司: 阿里巴巴】
- 601.[代码实现] 手写数组降维flat方法【热度: 244】【代码实现/算法】【出题公司: 阿里巴巴】
-
高级开发者相关问题【共计 8 道题】
- 587.[React] 如何实现转场动画?【web框架】【出题公司: 阿里巴巴】
- 590.[React] 如何避免不必要的渲染?【热度: 632】【web框架】【出题公司: 腾讯】
- 592.在 webpack 中,通常用于 css 提取的工具是什么?【热度: 269】【工程化】【出题公司: 腾讯】
- 593.在你的项目中, 使用过哪些 webpack loader, 说一下他们的作用【热度: 361】【工程化】【出题公司: 阿里巴巴】
- 594.在你的项目中, 使用过哪些 webpack plugin, 说一下他们的作用【热度: 361】【工程化】【出题公司: 阿里巴巴】
- 596.为何 http2 非常快速的就过度到了 HTTP3 ?【热度: 945】【网络】【出题公司: 腾讯】
- 597.http1.1 的 keep-alive 和 http2 的多路复用 有什么区别?【热度: 87】【网络】【出题公司: 腾讯】
- 598.PM2 部署 nodejs 有哪些优势?【热度: 199】【Nodejs】【出题公司: 腾讯】
中级开发者相关问题【共计 8 道题】
586.[React] react router 主要包有哪些,主要 api 有哪些?【web框架】【出题公司: 阿里巴巴】
React Router是React官方提供的用于构建单页应用的路由库,主要包括以下几个主要包和API:
主要包:
- react-router-dom:用于Web应用的路由库。
- react-router-native:用于原生应用(如React Native)的路由库。
- react-router-config:用于配置静态路由的工具包。
主要API:
- BrowserRouter:一个使用HTML5 history API实现的路由器组件,用于在Web应用中处理路由。
- HashRouter:一个使用URL hash值实现的路由器组件,用于在不支持HTML5 history API的Web应用中处理路由。
- Route:定义了路由匹配规则及对应的组件,可以在路由器中使用。
- Switch:用于渲染与当前URL匹配的第一个Route或Redirect,只能包含Route或Redirect组件。
- Link:用于创建导航链接,点击后会更新URL,触发路由的切换。
- NavLink:与Link类似,但在匹配当前URL时会添加指定的样式。
其他常用API:
- Redirect:用于重定向到指定的路由。
- withRouter:高阶组件,用于将路由器的相关信息(如history、location)传递给被包裹的组件。
- useHistory:自定义hook,用于在函数式组件中获取history对象。
- useLocation:自定义hook,用于在函数式组件中获取location对象。
- useParams:自定义hook,用于在函数式组件中获取路由参数。
- useRouteMatch:自定义hook,用于在函数式组件中获取与当前URL匹配的路由信息。
以上是React Router的主要包和API。根据具体的需求,你可以使用这些API来构建和处理路由相关的逻辑。
588.全局样式命名冲突和样式覆盖问题怎么解决?【热度: 772】【CSS】【出题公司: 腾讯】
关键词:全局样式命名冲突
在前端开发过程中,有几种常见的方法可以解决全局样式命名冲突和样式覆盖问题:
- 使用命名空间(Namespacing):给样式类名添加前缀或命名空间,以确保每个组件的样式类名不会冲突。例如,在一个项目中,可以为每个组件的样式类名都添加一个唯一的前缀,例如
.componentA-button和.componentB-button,这样可以避免命名冲突。 - 使用BEM命名规范:BEM(块、元素、修饰符)是一种常用的命名规范,可以将样式类名分成块(block)、元素(element)和修饰符(modifier)三个部分,以确保样式的唯一性和可读性。例如,
.button表示一个块,.button__icon表示一个元素,.button--disabled表示一个修饰符。 - 使用CSS预处理器:CSS预处理器(如Sass、Less)可以提供变量、嵌套规则和模块化等功能,可以更方便地管理样式并避免命名冲突。例如,可以使用变量来定义颜色和尺寸,使用嵌套规则来组织样式,并将样式拆分成多个模块。
- 使用CSS模块:CSS模块提供了在组件级别上限定样式作用域的能力,从而避免了全局样式的冲突和覆盖。每个组件的样式定义在组件内部,使用唯一的类名,确保样式的隔离性和唯一性。
- 使用CSS-in-JS解决方案:CSS-in-JS是一种将CSS样式直接写入JavaScript代码中的方法,通过将样式与组件绑定,可以避免全局样式的冲突问题。一些常见的CSS-in-JS解决方案包括Styled Components、Emotion和CSS Modules with React等。
589.css module 是什么?【热度: 346】【CSS】【出题公司: 腾讯】
关键词:css module 概念、css module 作用
CSS Modules 是一种用于组织和管理 CSS 的技术。它通过在编译时为每个 CSS 类名生成唯一的标识符,并将它们作为 JavaScript 对象的属性导出。这样,可以确保每个类名在整个应用程序中的唯一性,避免样式冲突。
使用 CSS Modules,可以将 CSS 文件与组件文件绑定在一起,这样每个组件都有自己的 CSS 作用域,样式只会应用于特定的组件,不会影响其他组件。这种隔离性和局部作用域有助于降低样式冲突和维护 CSS 的复杂性。
CSS Modules 还提供了一些其他功能,例如:
- 局部作用域: CSS Modules 允许在组件中定义局部样式,这些样式仅适用于该组件。这样,可以避免全局样式造成的副作用,并使组件更加可重用。
- 类名和样式的映射: 使用 CSS Modules,可以通过导入生成的样式对象,将类名映射到组件中的类名,并将其应用于相应的元素。这样可以方便地将样式与组件关联起来,并跟踪样式的变化。
- 继承和组合: CSS Modules 支持继承和组合样式。可以通过使用类名组合和继承规则,将多个样式应用于同一个元素或组件。
总结来说,CSS Modules 提供了一种更可靠和可维护的方式来管理 CSS,通过实现局部作用域和唯一类名标识符,帮助开发者避免样式冲突和提高样式的可重用性。
591.[React] useLayoutEffect 和 useEffect 有什么区别?【热度: 313】【web框架】【出题公司: 腾讯】
关键词:useLayoutEffect 和 useEffect 区别
useLayoutEffect 和 useEffect 的主要区别在于它们执行的时机。
- useLayoutEffect: useLayoutEffect 是在 DOM 更新完成但在浏览器绘制之前同步执行的钩子函数。它会在 DOM 更新之后立即执行,阻塞浏览器的绘制过程。这使得它更适合于需要立即获取最新 DOM 布局信息的操作,如测量元素尺寸或位置等。使用 useLayoutEffect 可以在更新后同步触发副作用,从而保证 DOM 的一致性。
- useEffect: useEffect 是在组件渲染完毕后异步执行的钩子函数。它会在浏览器完成绘制后延迟执行,不会阻塞浏览器的绘制过程。这使得它更适合于处理副作用操作,如发送网络请求、订阅事件等。使用 useEffect 可以将副作用操作放到组件渲染完成后执行,以避免阻塞浏览器绘制。
总结:
- useLayoutEffect 是同步执行的钩子函数,在 DOM 更新后立即执行,可能会阻塞浏览器的绘制过程;
- useEffect 是异步执行的钩子函数,在浏览器完成绘制后延迟执行,不会阻塞浏览器的绘制过程。
通常情况下,应优先使用 useEffect,因为它不会阻塞浏览器的渲染,并且能够满足大多数的副作用操作需求。只有在需要获取最新的 DOM 布局信息并立即触发副作用时,才需要使用 useLayoutEffect。
595.[Vue] 响应式为何要从 Object.defineProperty 改为 proxy?【热度: 352】【工程化】【出题公司: 阿里巴巴】
关键词:vue Object.defineProperty、vue proxy 使用
Vue 在早期版本中使用了 Object.defineProperty 来实现响应式系统。但是,在 Object.defineProperty 中存在一些限制和局限性,导致在某些场景下无法完全满足需求。因此,Vue 在最新的版本中引入了 Proxy 来替代 Object.defineProperty。
以下是一些 Proxy 相对于 Object.defineProperty 的优势:
- 功能更强大:
Proxy可以代理整个对象,而Object.defineProperty只能对已存在的属性进行拦截。使用Proxy可以在对象级别上进行拦截、代理、验证等操作。 - 更易于使用和理解:
Proxy提供了一组更直观和易于理解的 API,使开发者可以更容易地创建和管理代理。 - 性能优化:
Proxy针对属性的访问和修改都提供了更佳的性能优化。而Object.defineProperty在拦截属性访问和修改时会有一定的性能损耗。 - 更好的嵌套支持:
Proxy可以代理嵌套对象的属性,而Object.defineProperty只能对顶层对象的属性进行拦截。
总的来说,Proxy 相对于 Object.defineProperty 在功能上更强大、使用更便捷、性能更优,并且在更复杂的场景下也能提供更好的支持。因此,Vue 在新版本中选择了使用 Proxy 来实现响应式系统。
599.[代码实现] 不使用 setTimeout 来实现 setInterval【热度: 231】【代码实现/算法】【出题公司: 腾讯】
关键词:实现setInterval、requestAnimationFrame实现setInterval、setTimeout实现setInterval
如果不使用 setTimeout 来实现 setInterval,可以使用 requestAnimationFrame 函数和时间戳来实现定时循环。下面是实现的代码示例:
实现方式1
function mySetInterval(callback, interval) {
let startTime = Date.now();
let elapsedTime = 0;
function loop() {
const currentTime = Date.now();
const deltaTime = currentTime - startTime;
if (deltaTime >= interval) {
callback();
startTime = currentTime;
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
return {
clear: function() {
startTime = 0;
elapsedTime = 0;
}
};
}
这个实现中,我们通过 requestAnimationFrame 函数来循环执行 loop 函数。在 loop 函数中,我们获取当前时间戳 currentTime,并计算与上一次执行的时间间隔 deltaTime 。如果 deltaTime 大于等于指定的间隔时间 interval,则执行回调函数 callback,并更新 startTime 为当前时间,以便下一次判断。
最后,返回一个具有 clear 方法的对象,用于清除定时器。调用 clear 方法时,将 startTime 和 elapsedTime 重置为初始值。
实现方式2
const obj = {
timer: null,
setInterval: function(callback, interval) {
const now = Date.now
let startTime = now()
let endTime = startTime
const self = this
const loop = function() {
self.timer = requestAnimationFrame(loop)
endTime = now()
if (endTime - startTime >= interval) {
startTime = endTime = now()
callback && callback()
}
}
this.timer = requestAnimationFrame(loop)
return this.timer
},
clearInterval: function() {
cancelAnimationFrame(this.timer)
}
}
let count = 0
const timer = obj.setInterval(() => {
console.log('interval...')
count++
if (count >= 3) {
obj.clearInterval()
}
}, 500)
实现方式3
使用 setTimeout 来实现
/**
* setTimeout 版本
*/
function _setIntervalUseTimeout(
fn: () => void,
millisec: number,
count?: number
) {
let timer: number;
function interval() {
if (typeof count === 'undefined' || count-- > 0) {
timer = setTimeout(interval, millisec);
try {
fn();
} catch (e: any) {
count = 0;
throw e.toString();
}
}
}
timer = setTimeout(interval, millisec);
return {
clear: () => clearTimeout(timer),
};
}
600.[代码实现] 手写 dom 分段渲染【热度: 280】【代码实现/算法】【出题公司: 阿里巴巴】
关键词:dom 分段渲染
分时函数案例:把1秒创建1000个DOM节点,改成每隔200毫秒创建10个节点,这样不用短时间在页面中创建大量的DOM。
var timeChunk = function(arr, fn, count, interval) {
var timer = null;
var data = null;
var start = function() {
for (var i = 0; i < Math.min(count || 1, arr.length); i++) {
fn(arr.shift());
}
}
return function() {
timer = setInterval(function() {
if (arr.length == 0) {
clearInterval(timer);
timer = null;
return;
}
start();
}, interval || 200)
}
}
var arr = [];
for (var i = 0; i < 1000; i++) {
arr.push(i);
}
var renderDOMList = timeChunk(arr, function(data) {
var div = document.createElement('div');
div.innerHTML = data;
document.body.appendChild(div);
}, 10, 200);
renderDOMList();
601.[代码实现] 手写数组降维flat方法【热度: 244】【代码实现/算法】【出题公司: 阿里巴巴】
关键词:JS数组降维、reduce数组降维
原生Array.prototype.flat方法接受一个depth参数,默认值为1,depth表示要降维的维数:
输出结果:
const arr = [1, [2, 3], [4, [5, 6]]]
console.log(arr.flat(1)) // [1, 2, 3, 4, [5, 6]]
console.log(arr.flat(Infinity)) // [1, 2, 3, 4, 5, 6]
reduce + 递归实现方案
// MDN: 可查看更多flat实现方法
function flat(arr = [], depth = 1) {
if (arr.length === 0) {
return []
}
let result = []
if (depth > 0) {
result = arr.reduce((acc, val) => {
return acc.concat(Array.isArray(val) ? flat(val, depth - 1) : val)
}, [])
} else {
result = arr.slice()
}
return result
}
const arr = [1, 2, 3, [1, 2, 3, 4, [2, 3, 4]]]
const myResult1 = flat(arr, 1)
const originResult1 = arr.flat(1)
const myResult2 = flat(arr, Infinity)
const originResult2 = arr.flat(Infinity)
console.log(myResult1) // [1, 2, 3, 1, 2, 3, 4, [2, 3, 4]]
console.log(originResult1) // [1, 2, 3, 1, 2, 3, 4, [2, 3, 4]]
console.log(myResult2) // [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
console.log(originResult2) // [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
高级开发者相关问题【共计 8 道题】
587.[React] 如何实现转场动画?【web框架】【出题公司: 阿里巴巴】
这个问题非常复杂, 我这边用白话文解释一下原理, 若有不对的地方, 请大家更正:
如果没有专场动画, 那么在路由切换的一瞬间, 加载下一个路由页面的组件, 注销上一个路由页面的组件;
但是如果加上专场动画, 比如专场动画时间为 500ms, 那么, 在咋合格 500ms 过程中, 首先要加载下一个路由页面的组件, 然后加载上一个渐进的动画。 同时不能注销掉当前路由, 需要给当前路由加载一个渐出的动画。 需要当两个页面完成动画时间, 完成页面覆盖切换之后, 然后注销上一个路由页面的组件;
所以涉及到的知识点:
- 如何做页面跳转拦截;
- 如何在页面路由组件不跳转的同时, 加载下一个页面的组件;
- 配置页面层级;
- 如何执行、加载、完成专场动画;
- 动画结束的时候手动注销组件;
具体实现, 可以参考以下两个文档:
590.[React] 如何避免不必要的渲染?【热度: 632】【web框架】【出题公司: 腾讯】
关键词:react 渲染优化
在 React 中,有几种方法可以避免不必要的渲染,以提高性能和优化应用程序的渲染过程:
- 使用 PureComponent 或 shouldComponentUpdate 方法:继承 PureComponent 类或在自定义组件中实现 shouldComponentUpdate 方法,以检查组件的 props 和 state 是否发生变化。如果没有变化,则阻止组件的重新渲染。这种方式适用于简单的组件,并且可以自动执行浅比较。
- 使用 React.memo 高阶组件:使用 React.memo 包装函数组件,以缓存组件的渲染结果,并仅在其 props 发生变化时重新渲染。这种方式适用于函数组件,并且可以自动执行浅比较。
- 避免在 render 方法中创建新对象:由于对象的引用发生变化,React 将会认为组件的 props 或 state 发生了变化,从而触发重新渲染。因此,应尽量避免在 render 方法中创建新的对象,尤其是在大型数据结构中。
- 使用 key 属性唯一标识列表项:在渲染列表时,为每个列表项指定唯一的 key 属性。这样,当列表项重新排序、添加或删除时,React 可以更准确地确定哪些列表项需要重新渲染,而不是重新渲染整个列表。
- 使用 useCallback 和 useMemo 避免不必要的函数和计算:使用 useCallback 缓存函数引用,以确保只有在其依赖项发生变化时才重新创建函数。使用 useMemo 缓存计算结果,以确保只有在其依赖项发生变化时才重新计算结果。这些钩子函数可以帮助避免不必要的函数创建和计算过程,从而提高性能。
- 使用 React.lazy 和 Suspense 实现按需加载组件:使用 React.lazy 函数和 Suspense 组件可以实现按需加载组件,只在需要时才加载组件代码。这可以减少初始渲染时的资源负载。
592.在 webpack 中,通常用于 css 提取的工具是什么?【热度: 269】【工程化】【出题公司: 腾讯】
关键词:mini-css-extract-plugin作用、mini-css-extract-plugin使用
概念
在 webpack 中,通常使用 mini-css-extract-plugin 来提取 CSS。它是一个独立的插件,可以将 CSS 从 JavaScript 文件中提取出来,生成独立的 CSS 文件。 使用 mini-css-extract-plugin 可以优化代码分离和缓存,以及提高加载速度。
通过配置 webpack 的插件选项,可以将 mini-css-extract-plugin 添加到 webpack 构建流程中。在配置中,需要将该插件实例化,并指定输出的 CSS 文件名和路径。 一旦配置完成并运行 webpack 构建,mini-css-extract-plugin 就会将 CSS 提取到独立的文件中,而不是将其嵌入到 JavaScript 文件中。
示例代码如下:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
// ...其他配置
module: {
rules: [
// ...其他规则
{
test: /.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
};
在上述示例中,MiniCssExtractPlugin.loader 是用于提取 CSS 的 loader。css-loader 用于处理 CSS 文件的导入和解析。 MiniCssExtractPlugin则是插件实例,用于配置输出的 CSS 文件名。
基本API使用
下面是 MiniCssExtractPlugin 的常用参数及其说明:
| 参数名 | 类型 | 默认值 | 描述 | |
|---|---|---|---|---|
filename | string | [name].css | 输出的 CSS 文件名,可以包含 [name]、[id]、[contenthash] 等占位符变量,用于生成唯一的文件名。 | |
chunkFilename | string | undefined | 输出的 CSS 文件名的 chunk 文件名,可以包含 [name]、[id]、[contenthash] 等占位符变量。 | |
ignoreOrder | boolean | false | 是否忽略 CSS 导入顺序。 | |
insert | function | string | head | 用于指定 CSS 文件的插入位置。可以是字符串(head、body)或自定义函数。 |
publicPath | string | undefined | 设置在 CSS 文件中使用的公共路径。 | |
attributes | object | {} | 附加到 link 标签的自定义属性。 | |
chunkLoadTimeout | number | 120000 | 加载 CSS chunk 的超时时间(毫秒)。 | |
esModule | boolean | true | 是否使用 ES modules 规范导出 CSS 模块。 | |
experimentalUseImportModule | boolean | false | 是否在导出 CSS 模块时使用 import() 函数。**此选项需要 webpack 5+ | |
| 才能使用。** | ||||
hmr | boolean | undefined | 是否启用模块热替换(Hot Module Replacement)。**此选项需要 webpack 5+ | |
| 才能使用。** | ||||
ignoreOrder | boolean | false | 是否忽略 CSS 导入顺序。 | |
minimize | boolean | object | true | 是否对提取的 CSS 进行压缩。可以通过传入一个对象来设置压缩的选项。使用 cssnano 进行 CSS 压缩。 |
sourceMap | boolean | false | 是否生成 CSS 的 Source Map。 | |
moduleFilename | function | (getAssetPath => ${path.relative(options.context, getAssetPath('css'))}) | 用于自定义生成的 CSS 文件路径和文件名的函数。 | |
hot | boolean | undefined | 是否启用热模块替换(Hot Module Replacement)。**此选项需要 webpack 4.46.0+ | |
| 才能使用。** |
593.在你的项目中, 使用过哪些 webpack loader, 说一下他们的作用【热度: 361】【工程化】【出题公司: 阿里巴巴】
| Loader 名称 | 作用 |
|---|---|
babel-loader | 将 ES6+ 代码转换为 ES5 代码,以便在旧版浏览器中运行。 |
css-loader | 解析 CSS 文件,处理 CSS 中的依赖关系,并将 CSS 转换为 JS 模块。 |
style-loader | 将 CSS 代码以内联的方式注入到 HTML 页面中。 |
file-loader | 处理文件资源(如图片、字体等),将文件复制到输出目录,并返回文件路径。 |
url-loader | 与 file-loader 类似,但可以根据文件大小将文件转换为 Data URL(base64 格式)或文件路径。 |
sass-loader | 解析 Sass/SCSS 文件,并将其转换为 CSS 代码。 |
less-loader | 解析 Less 文件,并将其转换为 CSS 代码。 |
postcss-loader | 使用 PostCSS 处理 CSS,可以进行自动添加前缀、压缩、CSS Modules 等操作。 |
ts-loader | 将 TypeScript 代码转换为 JavaScript 代码。 |
eslint-loader | 在构建过程中使用 ESLint 进行代码检查。 |
stylelint-webpack-plugin | 在构建过程中使用 Stylelint 进行 CSS/SCSS 代码检查。 |
vue-loader | 解析 Vue 单文件组件(.vue 文件),并将其转换为 JavaScript 代码。 |
image-webpack-loader | 优化图片资源,包括压缩、转换格式等操作。 |
html-loader | 解析 HTML 文件,处理其中的引用资源(如图片、字体等),并返回处理后的 HTML 代码。 |
markdown-loader | 将 Markdown 文件转换为 HTML 代码。 |
json-loader | 解析 JSON 文件,并返回解析后的 JavaScript 对象。 |
eslint-loader | 在构建过程中使用 ESLint 进行代码检查。 |
tslint-loader | 在构建过程中使用 TSLint 进行 TypeScript 代码检查。 |
prettier-loader | 在构建过程中使用 Prettier 进行代码格式化。 |
stylelint-webpack-plugin | 在构建过程中使用 Stylelint 进行 CSS/SCSS 代码检查。 |
mini-css-extract-plugin | 提取 CSS 代码到单独的文件,而不是内联到 JavaScript 代码中。 |
optimize-css-assets-webpack-plugin | 压缩 CSS 代码。 |
terser-webpack-plugin | 压缩 JavaScript 代码。 |
这些 Loader 可以根据需要配置在 Webpack 的模块规则(module.rules)中,以实现对不同类型文件的处理和转换操作。
594.在你的项目中, 使用过哪些 webpack plugin, 说一下他们的作用【热度: 361】【工程化】【出题公司: 阿里巴巴】
下表列出了常见的 Webpack 插件及其作用:
| 插件名称 | 作用 |
|---|---|
HtmlWebpackPlugin | 自动生成 HTML 文件,并将打包后的资源自动注入到 HTML 中。 |
MiniCssExtractPlugin | 将 CSS 代码提取到单独的文件中,而不是内联到 JavaScript 中。 |
CopyWebpackPlugin | 将指定的文件或目录复制到输出目录。 |
CleanWebpackPlugin | 在每次构建之前清理输出目录,避免旧的文件残留。 |
DefinePlugin | 在编译过程中创建全局常量,可以在代码中直接使用。 |
HotModuleReplacementPlugin | 启用热模块更换(Hot Module Replacement),在开发过程中实现代码修改后实时更新页面,无需刷新。 |
ProvidePlugin | 自动加载模块,使模块在使用时可以直接使用对应的全局变量,无需引入。 |
MiniCssExtractPlugin | 将 CSS 代码提取到单独的文件中,而不是内联到 JavaScript 中。 |
OptimizeCSSAssetsPlugin | 压缩提取出的 CSS 文件。 |
uglifyjs-webpack-plugin | 压缩 JavaScript 代码。 |
webpack-bundle-analyzer | 分析打包后的文件大小,并可视化展示,方便优化打包结果。 |
CompressionWebpackPlugin | 使用 gzip 或其他压缩算法对文件进行压缩,减小文件大小,加快网络传输速度。 |
CopyWebpackPlugin | 将指定的文件或目录复制到输出目录。 |
FriendlyErrorsWebpackPlugin | 提供友好的构建错误提示和优化构建速度的功能。 |
ImageminWebpackPlugin | 压缩图片资源,减小文件大小,提升加载速度。 |
HotModuleReplacementPlugin | 启用热模块更换(Hot Module Replacement),在开发过程中实现代码修改后实时更新页面,无需刷新。 |
HtmlWebpackPlugin | 自动生成 HTML 文件,并将打包后的资源自动注入到 HTML 中。 |
IgnorePlugin | 忽略特定的模块,避免将其打包到最终的输出文件中。 |
BannerPlugin | 在打包的文件块顶部添加自定义的注释和信息。 |
webpack.DefinePlugin | 在编译过程中创建全局常量,可以在代码中直接使用。 |
webpack.ProgressPlugin | 在控制台输出构建进度信息。 |
webpack-bundle-analyzer | 分析打包后的文件大小,并可视化展示,方便优化打包结果。 |
webpackbar | 在命令行中显示构建进度条,提供更直观的构建进度信息。 |
这些插件可以根据需要配置在 Webpack 的插件列表(plugins)中,以实现对构建过程的各种增强和优化操作。
596.为何 http2 非常快速的就过度到了 HTTP3 ?【热度: 945】【网络】【出题公司: 腾讯】
关键词:http3
HTTP/2 被广泛采用后,HTTP/3 的出现是为了解决一些 HTTP/2 存在的问题以及提升性能。
HTTP/2 在性能方面确实有很大的改进,通过多路复用和头部压缩等特性,可以提高页面加载的速度和效率。然而,HTTP/2 仍然使用了基于 TCP 的传输层协议。TCP 的一些特性,如拥塞控制和传输层阻塞,可能造成延迟和性能下降。
HTTP/3 则引入了一种全新的传输层协议,即基于 UDP 的 QUIC(Quick UDP Internet Connections)。QUIC 具有更低的延迟和更好的拥塞控制,通过在应用层实现了可靠性和安全性,避免了在传输层和应用层之间的不必要的交互。
另外,HTTP/3 还支持多路复用、头部压缩等 HTTP/2 的特性。这意味着在 HTTP/3 中,仍然可以享受到 HTTP/2 带来的性能优势,同时还能更好地解决一些 HTTP/2 存在的问题。
综上所述,HTTP/3 之所以被广泛采用是因为它在 HTTP/2 的基础上进一步提升了性能,并解决了一些 HTTP/2 存在的问题,提供了更快速和更可靠的页面加载体验。
597.http1.1 的 keep-alive 和 http2 的多路复用 有什么区别?【热度: 87】【网络】【出题公司: 腾讯】
关键词:http1.1 keep-alive、http2 多路复用
HTTP/1.1 的 keep-alive 和 HTTP/2 的多路复用是两种不同的技术机制,它们都旨在提高 HTTP 协议的性能和效率,但具有不同的实现方式和特点。
-
HTTP/1.1 的 keep-alive:
- 在 HTTP/1.1 中,默认情况下,每个请求都需要建立一个新的 TCP 连接,请求完成后即关闭连接。
- 为了减少这种连接建立和关闭的开销,HTTP/1.1 引入了 keep-alive 机制,允许在一个 TCP 连接上发送多个 HTTP 请求和响应。
- keep-alive 通过在响应头中添加
Connection: keep-alive字段来启用。 - 使用 keep-alive 可以减少连接建立和关闭的开销,提高性能。
-
HTTP/2 的多路复用:
- HTTP/2 使用二进制协议而不是文本协议,通过在一个 TCP 连接上同时发送多个请求和响应,实现了多路复用。
- 在 HTTP/2 中,请求和响应被切分为多个帧,每个帧都有一个帧头,可以根据帧头中的流标识符将帧重新组装成完整的请求或响应。
- 多路复用允许多个请求和响应同时在一个 TCP 连接上进行传输,避免了 HTTP/1.1 中的队头阻塞问题。
- 多路复用提高了并发性能,减少了延迟,提升了 Web 页面的加载速度。
总结: HTTP/1.1 的 keep-alive 通过在一个 TCP 连接上发送多个请求和响应来减少连接建立和关闭的开销,提高性能。而 HTTP/2 的多路复用则通过在一个 TCP 连接上同时发送多个请求和响应,实现了并发传输,提高了并发性能和加载速度。
598.PM2 部署 nodejs 有哪些优势?【热度: 199】【Nodejs】【出题公司: 腾讯】
关键词:PM2 Nodejs
PM2部署Node.js应用程序有以下几个优势:
- 进程管理和监控:PM2可以自动监控Node.js应用程序的运行状态,并在进程崩溃或无响应时自动重启进程。它还提供了实时的日志输出和监控面板,方便查看和分析应用程序的运行情况。
- 无缝部署和热重载:使用PM2可以实现无缝部署Node.js应用程序,无需手动停止和启动进程。通过使用PM2的热重载功能,可以在不中断服务的情况下重新加载应用程序代码,实现零停机更新。
- 环境管理和配置:PM2可以通过环境变量来管理应用程序的配置,如端口号、数据库连接等。它还支持在不同的环境(如开发、测试、生产)之间切换配置,方便应用程序的部署和管理。
- 高可用性和负载均衡:PM2支持启动多个进程,并自动在多个CPU核心间平衡负载。这样可以提高应用程序的并发处理能力和性能,确保应用的高可用性和稳定性。
- 集中化管理:PM2提供了命令行工具和Web界面,可以集中管理和操作所有的Node.js应用程序。通过PM2,可以方便地查看和管理进程、查看日志、监控性能指标等,提升管理效率。
综上所述,PM2提供了完善的进程管理和监控功能,以及便捷的部署和配置管理方式,可以大大简化Node.js应用程序的部署和运维工作,提高应用的可用性和性能。