对于门户网站,最重要的就是:搜索引擎的优化(SEO)、不同设备兼容性、网站性能以及用户体验,可以通过以上几点作为切入点进行门户网站技术选型依据。
- **技术选型:**在技术选型初期应选择有利于SEO优化的开源框架,如:Next.js…,为后期做网站搜索引擎优化,提升网站排名铺垫基础。
- **搜索引擎优化:**创建高质量、原创且有价值的内容,确保与目标关键词相关;多使用h1、h2、以及p标签等语义化标签,以提高内容的可读性和搜索引擎理解;确保网站在不同尺寸的屏幕上有足够好的显示效果,同时应兼容移动端,适配更主流的搜索引擎;优化图片、压缩文件、使用浏览器缓存等方法来提高网站加载速度。
- **网站更新维护:**定期更新网站内容,确保信息的时效性;同时,定期检查和维护网站的技术方面,以防止漏洞和问题的积累。
2、Vue与React的区别
**
Vue.js
**和**React.js**
都是流行的前端 JavaScript 框架,用于构建用户界面;但由于框架设计方式不同,差异化的存在,导致双方也各有利弊。
- 双向数据绑定 vs 单向数据流:
Vue
通过双向数据绑定,当数据变化时,视图会自动更新,而视图的变化也会反馈到数据上。这通过v-model
指令来实现。React
采用单向数据流,数据的流动是自上而下的,通过props从父组件传递到子组件。为了实现组件间的通信,React
使用了回调函数或Redux
等状态管理工具。
- 组件化:
Vue
提供了更直观的组件化系统,通过Vue文件可以包含模板、脚本和样式。父子组件之间的通信相对简单,也支持自定义事件。React
组件化同样强大,但更注重组件的纯粹性和函数式编程风格。父子组件通信需要通过props和回调函数,而状态管理工具可用于更复杂的应用。
- 模板语法和JSX:
Vue
使用基于HTML的模板语法,直接在模板中使用Js表达式。这使得模板相对更易读,更容易上手。React
使用JSX,一种Js的语法扩展,它在Js中嵌套HTML。这提供了更灵活的表达方式,但可能对初学者有一定的学习曲线。
3、Vue2和Vue3的差异,以及双向绑定原理的变化
Vue 3相对于Vue 2,引入了性能优化、Composition API、模板编译改进、Teleport组件等新特性,提高了开发体验和整体性能。
- **性能优化:**Vue 3通过更好的响应性系统和虚拟DOM的优化实现了更高的性能。它引入了更细粒度的依赖追踪和静态提升等机制,使得更新和渲染更为高效。
- **Composition API:**Composition API是Vue 3引入的一项重大变化。它允许开发者通过函数组织逻辑,而不再依赖于选项对象。这使得代码更容易组织、重用和维护,特别是在处理复杂逻辑的情况下。
- **模板编译:**Vue 3的模板编译器生成更紧凑的代码,这有助于减小应用的体积,并提高运行时性能。新的编译器还支持一些新特性,如片段(fragments)和动态模板内容。
- **全局API的变化:在Vue 3中,全局的
Vue
对象被移除,一些全局API变成了createApp
的实例方法。例如,全局的mixin
现在需要通过app.mixin
**来调用。 - **TS支持:**Vue 3对TypeScript的支持更加完善。它通过重写了大部分代码以提供更好的类型推断,使得使用TypeScript时更容易发现和解决错误。
- **Teleport组件:**Vue 3引入了Teleport组件,使得在DOM中的不同位置渲染组件更为方便。这在处理全局弹窗、模态框等场景时非常有用。
- **更好的递归组件:**在Vue 3中,递归组件的性能得到了显著改进,使得处理大规模数据渲染时更为高效。
- **新的API:Vue 3引入了一些新的API,如
ref
和reactive
用于响应式数据,toRefs
用于解构响应式对象,watchEffect
**用于创建副作用等,这些API使得开发更为灵活和便捷。 - 双向绑定原理:
- Vue 2使用**
Object.defineProperty
对数据进行劫持,即通过给对象的属性添加getter
和setter
**来实现对数据的监控 - Vue 3使用**
Proxy
对象代替了Object.defineProperty
**,提供了更灵活和高效的数据劫持方式。Proxy可以监听整个对象,而不是每个属性。
- Vue 2使用**
4、性能优化怎么做
- 压缩代码:对 JavaScript、CSS 和 HTML 文件进行压缩,减小文件大小,加快加载速度。
- 减少 HTTP 请求:合并文件、使用 CSS 精灵、使用 Data URIs 来减少页面请求次数。
- 使用 CDN:使用内容分发网络(CDN)来加速静态资源的加载。
- 优化图片:使用适当大小和格式的图片,尽量减少图片大小,可以使用工具如 ImageOptim 或 TinyPNG 来优化图片。
- 懒加载:延迟加载不必要的资源,如图片、视频等,以提高页面加载速度。
- 减少重绘和重排:避免频繁的 DOM 操作,可以使用 CSS3 动画代替 JavaScript 动画,减少页面的重绘和重排。
- 使用缓存:利用浏览器缓存来存储静态资源,减少重复加载。
- 代码优化:避免使用不必要的库和插件,精简代码,减少不必要的计算和操作。
- 异步加载脚本:使用 defer 或 async 属性来异步加载 JavaScript 文件,避免阻塞页面加载。
5、对webpack的理解,以及性能优化的底层实现
- **定义:
Webpack
**是一个现代化的前端构建工具,它主要用于将多个模块打包成一个或多个静态资源文件。它具有很多强大的功能,如代码分割、模块化管理、静态资源处理等,可以帮助开发者更高效地组织和管理前端代码。 - 性能优化的实现逻辑:
- 代码分割:Webpack支持将代码拆分成多个小模块,按需加载,从而减少初始加载的文件大小,提高页面的加载速度。通过使用
import()
函数或动态导入语法,Webpack可以根据需要异步加载模块。 - Tree Shaking:**
Tree Shaking
是指通过静态代码分析,识别并删除项目中未被使用的代码。Webpack
**利用JavaScript的模块化特性,可以进行静态分析,找出未被引用的代码并且在打包过程中将其删除,从而减少最终打包文件的体积。 - 模块热替换(HMR):**
Webpack
**内置了模块热替换功能,可以在开发过程中实现实时更新。HMR允许我们在不刷新整个页面的情况下,只更新修改的模块,提高开发效率。 - 缓存:**
Webpack
**会为每个生成的文件生成唯一的哈希值,这样可以保证文件内容发生变化时,文件名也会跟着变化。这种方式可以使浏览器缓存失效,确保用户获取到最新的资源。 - 代码压缩和优化:
Webpack
提供了压缩JavaScript、CSS文件的插件,如UglifyJSPlugin
和OptimizeCSSAssetsPlugin
,可以将代码进行混淆、删除无用代码、优化变量等,从而减小文件体积,提高加载速度。
- 代码分割:Webpack支持将代码拆分成多个小模块,按需加载,从而减少初始加载的文件大小,提高页面的加载速度。通过使用
6、除了loader、图片压缩还可通过什么实现webpack优化
- 代码分割(Code Splitting): 使用Webpack的代码分割功能,将代码分割成更小的块,以便在需要时按需加载。这可以减少初始加载时间并提高页面性能。
- 懒加载(Lazy Loading): 通过懒加载将一些模块延迟加载到需要时再加载,而不是在初始加载时一次性加载所有内容。这可以提高页面的初始加载速度,并降低资源的使用量。
- Tree Shaking: 使用Webpack的Tree Shaking功能可以消除未使用的代码,减少打包后的文件大小。这可以通过配置Webpack来实现,通常与ES6模块和静态分析工具(如UglifyJS)一起使用。
- 代码压缩(Minification): 使用Webpack的压缩插件(如UglifyJSWebpackPlugin)来压缩和混淆JavaScript代码,以减小文件大小并提高加载速度。
- 缓存(Caching): 配置Webpack以生成带有内容哈希的文件名,以便在文件内容发生更改时进行缓存失效。这可以通过设置output.filename和output.chunkFilename来实现。
- 模块解析优化(Module Resolution Optimization): 优化Webpack的模块解析过程,以减少解析时间并提高构建性能。可以通过配置resolve选项来指定解析规则和解析模块的路径。
- 使用CDN: 将一些通用的库(如React、Vue等)以及一些公共资源(如字体、样式表等)托管在CDN上,以减轻服务器负载并加快资源加载速度。
- Webpack性能分析(Webpack Bundle Analyzer): 使用Webpack Bundle Analyzer工具分析构建后的包,找出构建过程中存在的性能瓶颈,并根据分析结果进行优化。
- 并行构建(Parallel Building): 使用Webpack的并行构建功能(如thread-loader、parallel-webpack等)来加速构建过程,特别是在大型项目中可以显著提高构建速度。
- 持久化缓存(Persistent Caching): 使用持久化缓存来加速Webpack的构建过程,以便在多次构建时重用之前的缓存结果,从而减少重复工作。
7、实现一个Peomise.all
- 理论步骤:
- 创建一个自定义的
myPromiseAll
函数,接收一个包含多个Promise对象的数组作为参数。 - 内部创建一个新的Promise对象,用于返回最终的结果。
- 判断传入的参数是否为数组,如果不是,则直接返回一个被拒绝的Promise,并提示参数类型错误。
- 创建一个计数器
count
,用于记录已经完成的Promise数量。 - 创建一个结果数组
results
,用于存储每个Promise的执行结果。 - 遍历传入的Promise数组,对每个Promise对象进行处理:
- 使用
.then()
方法注册一个回调函数,在Promise对象完成时将结果存入results
数组,并将count
加1。 - 使用
.catch()
方法注册一个错误处理函数,在Promise对象被拒绝时,直接将整个myPromiseAll
的Promise对象拒绝,并传递错误信息。
- 使用
- 返回内部创建的Promise对象。
- 创建一个自定义的
- 代码示例:
function myPromiseAll(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
reject(new Error('参数应为一个Promise数组'));
}
const count = 0;
const results = [];
for (let i = 0; i < promises.length; i++) {
promises[i]
.then(result => {
results[i] = result;
count++;
if (count === promises.length) {
resolve(results);
}
})
.catch(error => {
reject(error);
});
}
});
}
// 使用时,可以将多个Promise对象传入myPromiseAll函数,并使用.then()方法获取最终的结果:
const promise1 = new Promise(resolve => setTimeout(() => resolve('Promise 1'), 1000));
const promise2 = new Promise(resolve => setTimeout(() => resolve('Promise 2'), 2000));
const promise3 = new Promise(resolve => setTimeout(() => resolve('Promise 3'), 3000));
myPromiseAll([promise1, promise2, promise3])
.then(results => console.log(results))
.catch(error => console.error(error));
8、从 new Vue()
到页面挂载成功,Vue都执行了什么
最后
我可以将最近整理的前端面试题分享出来,其中包含HTML、CSS、JavaScript、服务端与网络、Vue、浏览器、数据结构与算法等等,还在持续整理更新中,希望大家都能找到心仪的工作。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
篇幅有限,仅展示部分截图: