新前端面试问题(9问)总结(前端面试问项目问题怎么说)

作者头像
风月
回答于 2023-05-29 10:44:03 阅读 383

2023.05.22 - 2023.05.23 更新前端面试问题总结(9道题)
获取更多面试相关问题可以访问
github 地址:
https://github.com/pro-collection/interview-question/issues
gitee 地址:
https://gitee.com/yanleweb/interview-question/issues

目录:

中级开发者相关问题【共计 3 道题】369.一直在 window 上面挂东西是否有什么风险【web应用场景】【出题公司: 腾讯】370.[React] createContext 和 useContext 有什么区别, 是做什么用的【热度: 367】【web框架】【出题公司: 百度】371.Object.prototype.hasOwnProperty() 作用是啥【热度: 1,176】【JavaScript】【出题公司: 小米】高级开发者相关问题【共计 6 道题】368.什么是领域模型【热度: 1,092】【web应用场景】372.幽灵依赖 是什么【工程化】【出题公司: 美团】373.Babel Polyfill 了解多少【热度: 200】【工程化】【出题公司: 美团】374.Antd(Ant Design)的 Tooltip 组件是如何实现的?【web框架】【出题公司: 阿里巴巴】375.深度 SEO 优化的方式有哪些, 从技术层面来说【web应用场景】【出题公司: 百度】376.SSR 了解多少【热度: 486】【工程化】【出题公司: 京东】中级开发者相关问题【共计 3 道题】369.一直在 window 上面挂东西是否有什么风险【web应用场景】【出题公司: 腾讯】

在前端开发中,将内容或应用程序运行在浏览器的全局window对象上可能会带来一些潜在的风险。以下是一些需要注意的风险:

命名冲突:window对象是浏览器的全局对象,它包含许多内置属性和方法。如果您在全局命名空间中定义的变量或函数与现有的全局对象属性或方法发生冲突,可能会导致意外行为或错误。安全漏洞:在全局window对象上挂载的代码可以访问和修改全局的数据和功能。这可能导致安全漏洞,特别是当这些操作被恶意利用时。攻击者可能通过篡改全局对象来窃取用户敏感信息或执行恶意代码。代码维护性:过多地依赖全局window对象可能导致代码的维护困难。全局状态的过度共享可能导致代码变得难以理解和调试,尤其在大型应用程序中。

为了减轻这些风险,建议采用以下最佳实践:

使用模块化开发:将代码模块化,避免对全局window对象的直接依赖。使用模块加载器(如ES Modules、CommonJS、AMD)来管理模块之间的依赖关系,以减少全局命名冲突和代码冗余。使用严格模式:在JavaScript代码中使用严格模式("use strict"),以启用更严格的语法检查和错误处理。严格模式可以帮助捕获潜在的错误和不安全的行为。显式访问全局对象:如果确实需要访问全局window对象的属性或方法,请使用显式访问方式,如window.localStorage、window.setTimeout()等。避免直接引用全局属性,以减少冲突和误用的风险。谨慎处理第三方代码:在使用第三方库或框架时,注意审查其对全局window对象的使用方式。确保库或框架的操作不会产生潜在的安全风险或全局命名冲突。370.[React] createContext 和 useContext 有什么区别, 是做什么用的【热度: 367】【web框架】【出题公司: 百度】

关键词:createContext useContext、useContext 使用、createContext 使用

createContext 和 useContext

createContext和useContext是React中用于处理上下文(Context)的两个钩子函数,它们用于在组件之间共享数据。

createContext用于创建一个上下文对象,该对象包含Provider和Consumer两个组件。createContext接受一个初始值作为参数,该初始值将在没有匹配的Provider时被使用。

useContext用于在函数组件中访问上下文的值。它接受一个上下文对象作为参数,并返回当前上下文的值。

具体区别和用途如下:

createContext:createContext用于创建一个上下文对象,并指定初始值。它返回一个包含Provider和Consumer组件的对象。Provider
组件用于在组件树中向下传递上下文的值,而Consumer组件用于在组件树中向上获取上下文的值。

const MyContext = createContext(initialValue); useContext:useContext用于在函数组件中访问上下文的值。它接受一个上下文对象作为参数,并返回当前上下文的值。使用useContext可以避免使用Consumer组件进行嵌套。

const value = useContext(MyContext);

使用上下文的主要目的是在组件树中共享数据,避免通过逐层传递props的方式传递数据。上下文可以在跨组件层级的情况下方便地共享数据,使组件之间的通信更加简洁和灵活。

使用步骤如下:

使用createContext创建一个上下文对象,并提供初始值。在组件树中的某个位置使用Provider组件,将要共享的数据通过value属性传递给子组件。在需要访问上下文数据的组件中使用useContext钩子,获取上下文的值。

需要注意的是,上下文中的数据变化会触发使用该上下文的组件重新渲染,因此应谨慎使用上下文,避免无谓的性能损耗。

代码示范

当使用createContext和useContext时,以下是一个简单的代码示例:

import React, { createContext, useContext } from 'react'; // 创建上下文对象 const MyContext = createContext(); // 父组件 function ParentComponent() { const value = 'Hello, World!'; return ( // 提供上下文的值 <MyContext.Provider value={value}> <ChildComponent /> </MyContext.Provider> ); } // 子组件 function ChildComponent() { // 使用 useContext 获取上下文的值 const value = useContext(MyContext); return <div>{value}</div>; } // 使用上述组件 function App() { return <ParentComponent />; }

在上述示例中,我们首先使用createContext创建一个上下文对象MyContext。然后,在ParentComponent组件中,我们通过MyContext.Provider
组件提供了上下文的值,值为'Hello, World!'。在ChildComponent组件中,我们使用useContext钩子获取了上下文的值,并将其显示在页面上。

最终,我们在App组件中使用ParentComponent组件作为根组件。当渲染应用程序时,ChildComponent将获取到上下文的值并显示在页面上。

通过这种方式,ParentComponent提供了上下文的值,ChildComponent通过useContext钩子获取并使用该值,实现了组件之间的数据共享。

371.Object.prototype.hasOwnProperty() 作用是啥【热度: 1,176】【JavaScript】【出题公司: 小米】

关键词:
Object.prototype.hasOwnProperty

Object.prototype.hasOwnProperty()


Object.prototype.hasOwnProperty()是JavaScript中Object原型对象上的方法。它用于检查一个对象是否具有指定的属性(即对象自身拥有的属性),并返回一个布尔值表示结果。

hasOwnProperty()方法的作用是检查对象是否包含特定的属性,而不会考虑该属性是否继承自原型链。它接受一个字符串参数,表示要检查的属性名。如果对象自身拥有该属性,则返回true
;如果对象没有该属性或该属性是从原型链继承的,则返回false。

以下是hasOwnProperty()方法的使用示例:

const obj = { prop1: 'value1', prop2: 'value2', }; console.log(obj.hasOwnProperty('prop1')); // true console.log(obj.hasOwnProperty('prop3')); // false

在上述示例中,obj对象拥有prop1属性,因此obj.hasOwnProperty('prop1')返回true。然而,obj对象没有prop3属性,因此obj.hasOwnProperty('prop3')
返回false。

使用hasOwnProperty()方法可以帮助我们确定属性是对象自身的属性还是继承自原型链。这在进行属性遍历或属性存在性检查时非常有用。请注意,hasOwnProperty()
方法只能检查对象自身的属性,不能检查原型链上的属性。如果需要检查原型链上的属性,可以使用in运算符或
Object.prototype.hasOwnProperty.call()方法。

hasOwnProperty和instanceof 区别

hasOwnProperty和instanceof是两个不同的操作符,用于在JavaScript中进行不同类型的检查。

hasOwnProperty:hasOwnProperty是Object原型对象上的方法,用于检查一个对象是否具有指定的属性(即对象自身拥有的属性),并返回一个布尔值表示结果。它是针对对象属性的检查。instanceof:instanceof是JavaScript的一个操作符,用于检查一个对象是否是某个构造函数的实例。它用于检查对象的类型。

以下是两者之间的区别:

hasOwnProperty是用于检查对象是否具有特定的属性,它关注的是对象自身的属性,不涉及对象的类型。它只检查对象自身的属性,不会检查原型链上的属性。instanceof是用于检查对象是否是某个构造函数的实例,它关注的是对象的类型。它会检查对象的原型链上是否存在指定构造函数的原型对象。

使用示例:

const obj = { prop: 'value' }; console.log(obj.hasOwnProperty('prop')); // true console.log(obj instanceof Object); // true console.log(obj instanceof Array); // false

在上述示例中,obj对象拥有prop属性,因此obj.hasOwnProperty('prop')返回true。同时,obj对象是Object构造函数的实例,因此obj instanceof Object
返回true,但不是Array构造函数的实例,因此obj instanceof Array返回false。

总结而言,hasOwnProperty用于检查对象是否拥有特定的属性,而instanceof用于检查对象的类型。

高级开发者相关问题【共计 6 道题】368.什么是领域模型【热度: 1,092】【web应用场景】

关键词:前端领域模型

什么是领域模型

领域模型是软件开发中用于描述领域(业务)概念和规则的一种建模技术。它通过定义实体、值对象、关联关系、行为等元素,抽象出领域的核心概念和业务规则,帮助开发人员理解和设计软件系统。

以下是领域模型中常见的一些元素:

实体(Entity):实体是领域模型中具有唯一标识的对象,通常代表领域中的具体事物或业务对象。实体具有属性和行为,并且可以通过其标识进行唯一标识和识别。值对象(Value Object):值对象是没有唯一标识的对象,通常用于表示没有明确生命周期的属性集合。值对象的相等性通常基于其属性值,而不是标识。例如,日期、时间、货币等都可以作为值对象。关联关系(Association):关联关系描述了不同实体之间的关系和连接。关联关系可以是一对一、一对多、多对多等不同类型。关联关系可以带有方向和导航属性,用于表示实体之间的关联和导航。聚合(Aggregation):聚合是一种特殊的关联关系,表示包含关系,即一个实体包含其他实体。聚合关系是一种强关联,被包含实体的生命周期受到包含实体的控制。领域事件(Domain Event):领域事件表示领域中发生的具体事件或状态变化。它可以作为触发业务逻辑的信号,通常用于解耦和处理领域中的复杂业务流程。聚合根(Aggregate Root):聚合根是聚合中的根实体,它代表整个聚合的一致性边界。通过聚合根,可以对整个聚合进行操作和维护。领域服务(Domain Service):领域服务是一种封装了领域逻辑的服务,用于处理领域中的复杂业务操作或跨实体的操作。它通常与具体实体无关,提供一些无状态的操作。

通过建立领域模型,开发人员可以更好地理解和表达领域的业务需求和规则,从而指导软件系统的设计和实现。领域模型可以作为开发团队之间沟通的工具,也可以用于生成代码、进行自动化测试等。

前端系统应该如何划分领域模型

在前端系统中划分领域模型的方式可以根据具体业务需求和系统复杂性进行灵活调整。以下是一些常见的划分领域模型的方式:

模块划分:将前端系统按照模块进行划分,每个模块对应一个领域模型。模块可以根据功能、业务领域或者页面进行划分。每个模块可以有自己的实体、值对象、关联关系和业务逻辑。页面划分:将前端系统按照页面进行划分,每个页面对应一个领域模型。每个页面可以有自己的实体、值对象和关联关系,以及与页面相关的业务逻辑。组件划分:将前端系统按照组件进行划分,每个组件对应一个领域模型。每个组件可以有自己的实体、值对象和关联关系,以及与组件相关的业务逻辑。组件可以是页面级别的,也可以是更细粒度的功能组件。功能划分:将前端系统按照功能进行划分,每个功能对应一个领域模型。功能可以是用户操作的具体功能模块,例如登录、注册、购物车等。每个功能可以有自己的实体、值对象和关联关系,以及与功能相关的业务逻辑。

在划分领域模型时,需要根据具体业务的复杂性和团队的组织方式进行调整。重要的是识别系统中的核心业务概念和规则,并将其抽象成适当的实体和值对象。同时,要保持领域模型的聚合性和一致性,避免出现过于庞大和紧耦合的领域模型。划分的领域模型应该易于理解、扩展和维护,以支持前端系统的开发和演进。

372.幽灵依赖 是什么【工程化】【出题公司: 美团】幽灵依赖 是什么

“幽灵依赖”(Ghost Dependency)是指在项目的node_modules目录中存在但未被实际使用的依赖包。

在使用 npm 或者其他包管理工具安装依赖包时,有时会出现安装了一些不需要的或者不正确的依赖包的情况。这些依赖包在项目中没有被显式地引用或使用,但仍然存在于node_modules目录中,占用了项目的存储空间。

幽灵依赖可能会产生以下问题:

占用存储空间:未使用的依赖包会增加项目的体积,占用存储空间。对于大型项目或频繁部署的项目来说,这可能会造成不必要的存储资源浪费。增加构建时间:未使用的依赖包可能会增加构建过程中的解析和处理时间,导致构建过程变慢。这会影响开发人员的开发效率和项目的部署速度。潜在的安全风险:未使用的依赖包可能包含漏洞或安全风险,但由于没有使用,可能没有及时更新或修复这些问题,增加了项目的安全隐患。

为了解决幽灵依赖的问题,可以采取以下措施:

定期检查依赖:定期检查项目的依赖,识别和删除未使用的依赖包。可以使用工具如npm-check-unused、depcheck等来帮助检测和清理未使用的依赖。精简依赖:审查项目的依赖关系,仅安装和保留必要的依赖包。避免过度依赖,只安装项目所需的模块,减少项目体积和构建时间。更新依赖包:确保项目中使用的依赖包都是最新版本,并及时更新已知的安全漏洞和问题。这可以通过定期检查依赖包的更新和使用工具如npm audit来实现。

通过处理幽灵依赖,可以提高项目的整洁性、性能和安全性,并减少不必要的开销和风险。

pnpm 是如何解决幽灵依赖问题的

pnpm 是一个基于 npm 的包管理工具,它采用了一种称为"快速硬链接(Fast Hard Links)"的机制来解决幽灵依赖问题。

传统的 npm 或 yarn 安装依赖时,每个项目都会在node_modules目录下创建依赖包的副本。这导致了大量的重复文件,尤其是对于多个项目都使用同一依赖包时。

而 pnpm 通过使用快速硬链接机制,在全局的存储位置(默认为~/.pnpm-store)只保存一份依赖包,而不是为每个项目都复制一份。这样就避免了幽灵依赖问题,减少了存储空间的占用。

当使用 pnpm 安装依赖时,它会在项目的node_modules目录下创建一个.modules.yaml
文件,记录项目所需的依赖包和版本信息。实际的依赖包文件通过硬链接指向全局存储位置中的依赖包。这意味着不同项目之间可以共享相同的依赖包,但每个项目都拥有自己的依赖版本。

通过这种方式,pnpm 解决了幽灵依赖的问题,同时减少了存储空间的使用。它还具有一些其他的优点,如更快的安装速度、更少的网络传输和更好的缓存利用率。

需要注意的是,pnpm 仍然会将项目中的所有依赖安装在node_modules目录下,但它使用硬链接的方式避免了重复文件的复制,从而解决了幽灵依赖问题。

373.Babel Polyfill 了解多少【热度: 200】【工程化】【出题公司: 美团】

关键词:Babel Polyfill 原理、Babel Polyfill 作用、Babel Polyfill 使用、Babel Polyfill 按需加载

Babel Polyfill 作用是啥

Babel Polyfill 的作用是在旧版本浏览器中提供对新的JavaScript特性和API的支持。当使用Babel进行代码转换时,它只会转换语法,而不会转换新的API和全局对象(如Promise、Map、Set等)。

旧版本的浏览器可能不支持这些新的API和全局对象,因此在运行使用这些特性的代码时会抛出错误。为了解决这个问题,可以使用Babel Polyfill来填充缺失的功能,以确保代码在旧版本浏览器中正常运行。

Babel Polyfill通过修改全局对象和原型链,添加缺失的方法和属性,使得代码能够在不支持这些功能的浏览器中运行。它会检测当前环境的特性支持情况,并根据需要自动加载所需的Polyfill代码。

使用Babel Polyfill可以让开发人员在编写代码时不必过多考虑浏览器的兼容性,而专注于使用最新的JavaScript特性和API。它提供了一种简单方便的方式来填充浏览器的功能差异,确保代码在各种浏览器环境中具有一致的行为。

如何使用

要使用 Babel Polyfill,需要按照以下步骤进行设置:

安装依赖:首先,确保你的项目已经安装了 Babel 相关的依赖包。这包括 @babel/core、@babel/preset-env 和 @babel/polyfill。你可以使用 npm 或者 yarn 进行安装:

npm install --save-dev @babel/core @babel/preset-env @babel/polyfill 配置 Babel:在项目根目录下创建一个 .babelrc 文件,并添加以下配置:

{ "presets": [ "@babel/preset-env" ] }

这样的配置将告诉 Babel 使用 @babel/preset-env 预设来进行转换。

导入 Polyfill:在你的入口文件(通常是项目的主 JavaScript 文件)中导入 Babel Polyfill。你可以使用 import 语句或者 require 来导入 Polyfill:

使用 import(适用于 ES6 模块):

import '@babel/polyfill';

使用 require(适用于 CommonJS 模块):

require('@babel/polyfill');

导入 Polyfill 的位置很重要,通常应该在你的应用程序代码之前导入,以确保 Polyfill 在应用程序代码之前被加载和执行。

配置目标浏览器:为了让 Babel Polyfill 根据目标浏览器进行特性填充,你可以在 .babelrc 文件中的 @babel/preset-env配置中指定目标浏览器的选项。例如,你可以在配置中添加 targets
属性:

{ "presets": [ [ "@babel/preset-env", { "targets": { "browsers": [ "last 2 versions", "ie >= 11" ] } } ] ] }

这样,Polyfill 将根据所选的目标浏览器填充相应的功能。

完成以上步骤后,Babel Polyfill 将根据配置在目标浏览器中填充所需的功能,以确保你的代码在旧版本浏览器中正常运行。请注意,Polyfill 会增加你的应用程序的大小,因此请考虑仅填充所需的功能,以减小文件大小并优化性能。

按需加载 Polyfill

Babel Polyfill 默认会填充所有缺失的功能,但如果你只需要按需加载特定功能,可以使用 core-js 库的按需加载特性。下面是按需加载 Babel Polyfill 的步骤:

安装依赖:确保你的项目已经安装了必要的依赖。除了之前提到的 Babel 相关依赖外,你还需要安装 core-js。

npm install --save-dev @babel/core @babel/preset-env core-js 配置 Babel:在 .babelrc 文件中,添加以下配置:

{ "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage", "corejs": 3 } ] ] }

useBuiltIns 选项设置为 "usage" 表示按需加载特性,而 "corejs": 3 指定了使用的 core-js 版本。

导入 Polyfill:在需要使用特定功能的文件中,按需导入所需的 Polyfill。例如,如果你需要填充 Promise 和 Array.prototype.includes,你可以按如下方式导入:

import 'core-js/features/promise'; import 'core-js/features/array/includes';

这样只会加载和填充所需的功能,而不会加载整个 Polyfill 库。你可以根据具体的功能需求进行按需导入。

请注意,使用按需加载的方式可以减小应用程序的文件大小,并且只填充需要的功能,但需要确保在使用相关功能之前已经导入了相应的 Polyfill。

374.Antd(Ant Design)的 Tooltip 组件是如何实现的?【web框架】【出题公司: 阿里巴巴】

Antd(Ant Design)的 Tooltip 组件是通过 CSS 和 JavaScript 结合实现的。

在 CSS 方面,Tooltip 组件使用了绝对定位和一些样式规则来定义 Tooltip 的外观。它通常包括一个触发元素和一个浮动在触发元素旁边的提示框。通过设置样式属性,如 position:
absolute、top、left、display 等,可以控制提示框的位置、显示和隐藏等。

在 JavaScript 方面,Tooltip 组件通过事件监听和操作 DOM
元素来实现交互行为。当鼠标悬停在触发元素上时,会触发相应的事件处理函数。在事件处理函数中,通常会修改提示框元素的样式或类名,以实现显示或隐藏提示框的效果。同时,还可以根据鼠标位置调整提示框的位置,使其相对于触发元素居中或显示在特定的位置。

另外,Tooltip 组件还支持一些额外的配置选项,如延迟显示、自定义内容等。这些选项可以通过传递属性或配置项给 Tooltip 组件来进行设置。

Tooltip 组件的动态偏移样式计算

监听触发元素的事件:Tooltip 组件通常在触发元素上监听鼠标悬停或点击等事件。获取触发元素的位置信息:在事件处理函数中,通过 DOM 操作获取触发元素的位置信息,包括宽度、高度、左偏移和上偏移等。计算偏移样式:根据触发元素的位置信息,结合组件配置项或属性中的偏移参数,计算出提示框相对于触发元素的偏移样式。设置提示框的样式:通过修改提示框元素的样式属性,如 top、left、transform 等,将计算得到的偏移样式应用于提示框,使其出现在预期的位置。

具体实现上述步骤的方式可以有多种,取决于具体的实现框架或库。一种常见的方式是使用 JavaScript 来监听事件、获取位置信息和设置样式,配合 CSS 来定义样式规则。

在实际开发中,可以使用一些常见的技术手段来计算动态偏移样式,例如:

使用 CSS 的 position: absolute 将提示框定位在触发元素的相对位置上。使用 JavaScript 的 getBoundingClientRect() 方法获取触发元素的位置信息,包括宽度、高度、左偏移和上偏移等。结合触发元素的位置信息和组件配置项中的偏移参数,通过计算得到最终的偏移值。将计算得到的偏移值应用于提示框的样式属性,如 top、left、transform 等,使其相对于触发元素进行动态偏移。

需要注意的是,具体的实现方式可能因框架、库或组件的不同而有所差异,但核心思想是通过监听事件、获取位置信息和计算样式来实现动态偏移效果。

375.深度 SEO 优化的方式有哪些, 从技术层面来说【web应用场景】【出题公司: 百度】

深度 SEO 优化涉及到一些技术层面的优化策略,以下是一些常见的方式:

网站结构优化:优化网站的结构,确保每个页面都可以被搜索引擎爬取和索引。使用合适的 HTML 标签和语义化的内容结构,使搜索引擎能够更好地理解页面的内容。网站速度优化:提升网站的加载速度对 SEO 很重要。通过压缩和合并 CSS 和 JavaScript 文件、优化图像、使用浏览器缓存、使用 CDN(内容分发网络)等技术手段来减少页面加载时间。页面渲染优化:确保搜索引擎可以正常渲染和索引使用 JavaScript 技术构建的单页面应用(SPA)或动态生成的内容。使用服务端渲染(SSR)或预渲染技术,确保搜索引擎能够获取到完整的页面内容。URL 优化:使用短、描述性的 URL,并使用关键词来优化 URL 结构。避免使用动态参数或过长的 URL。链接优化:内部链接和外部链接都对 SEO 有影响。在网站内部设置相关性强的链接,使页面之间相互连接。外部链接是获取更多外部网站链接指向自己网站的重要手段,可以通过内容创作和社交媒体推广来获得更多高质量的外部链接。Schema 标记:使用结构化数据标记(Schema Markup)来标识网页内容,帮助搜索引擎更好地理解和展示网页信息。可以使用 JSON-LD、Microdata 或 RDFa 等标记格式。XML 网站地图:创建和提交 XML 网站地图,提供网站的结构和页面信息,帮助搜索引擎更好地索引网站内容。Robots.txt 文件:通过 Robots.txt 文件来指示搜索引擎哪些页面可以被爬取和索引,哪些页面不可访问。HTTPS 加密:使用 HTTPS 协议来加密网站通信,确保数据安全和用户隐私,同时搜索引擎更倾向于收录和排名使用 HTTPS 的网站。移动友好性:优化网站在移动设备上的显示和用户体验,确保网站具备响应式设计或移动版网站,以及快速加载和友好的操作性。

这些是深度 SEO 优化的一些常见技术层面的策略,通过综合运用这些策略,可以提升网站的搜索引擎可见性和排名。需要根据具体情况和搜索引擎的最佳

376.SSR 了解多少【热度: 486】【工程化】【出题公司: 京东】

关键词:SSR 原理、SSR 实现

SSR 原理是啥

服务器端渲染(Server-Side Rendering,SSR)是一种前端渲染方式,其核心原理是在服务器端将动态生成的 HTML 页面发送给客户端,以便客户端在接收到页面时直接渲染显示,而不是在客户端使用 JavaScript
动态生成页面。

核心原理如下:

客户端发起请求:当用户访问一个 SSR 应用的页面时,客户端会向服务器发起请求。服务器处理请求:服务器接收到请求后,根据请求的路径和参数,获取对应的数据。数据获取和页面渲染:在服务器端,通过调用后端数据接口或其他数据源获取页面所需的数据。获取到数据后,服务器使用模板引擎或渲染框架将数据填充到页面模板中,生成完整的 HTML 页面。HTML 页面返回给客户端:服务器将生成的 HTML 页面作为响应返回给客户端。客户端渲染:客户端接收到服务器返回的 HTML 页面后,直接渲染显示页面内容。由于服务器已经将数据填充到了页面中,客户端无需再进行数据获取和页面渲染的过程,提升了页面的加载速度和用户体验。

SSR 的核心原理是在服务器端生成完整的 HTML 页面,并将其发送给客户端,使客户端能够更快地显示页面内容。相比于传统的客户端渲染(CSR),SSR 可以改善首次加载时的白屏时间和搜索引擎抓取等方面的问题。同时,SSR 也可以更好地支持
SEO(搜索引擎优化)和提供更好的性能体验给用户。

实现方案

前端实现服务器端渲染(SSR)的方案有以下几种:

基于 Node.js 的框架:使用 Node.js 的框架(如Express、Koa、Nest.js等)来构建服务器端应用程序,并在服务器端进行页面渲染。通过在服务器上运行 JavaScript 代码,将渲染好的页面直接返回给客户端。框架提供的 SSR 功能:一些前端框架(如Next.js、Nuxt.js、Angular Universal等)提供了内置的服务器端渲染功能,可以更方便地实现
SSR。这些框架会负责处理路由、数据预取和页面渲染等工作,并将渲染好的页面返回给客户端。预渲染:使用预渲染技术将静态页面提前生成,并部署到服务器上。在用户请求页面时,直接返回预渲染好的 HTML 页面,然后再由客户端接管页面的交互。这种方式适用于内容不经常变动或不需要动态数据的页面。后端代理:通过将前端应用程序的请求代理到服务器端,然后在服务器端进行页面渲染,并将渲染好的页面返回给客户端。这种方式适用于在现有的后端服务中添加 SSR 功能,而无需重写整个应用程序。

需要根据具体的项目需求、技术栈和框架选择合适的 SSR 实现方案。每种方案都有其优点和限制,综合考虑性能、开发体验、部署成本和维护复杂度等因素来做出决策。

声明:图文来源于互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请联系网站客服,一经查实,本站将立刻删除。

最新推荐