跳转至
本文阅读量

前端常见问题集锦

集锦列表

前端缓存有什么作用?

  • HTTP缓存机制指定过期时间有什么作用?

HTTP缓存机制是指浏览器和服务器之间缓存资源副本,以便下次请求时可以直接使用缓存的副本,而无需再次向服务器请求。HTTP缓存机制的作用是减少网络请求,提高页面加载速度。当浏览器向服务器请求某个资源时,如果该资源在缓存中,则直接从缓存中获取,不再向服务器请求,这样可以大大提高页面加载速度。但是,如果缓存过期,则需要向服务器请求该资源,这样才能获取最新的资源。因此,HTTP缓存机制的有效期可以用来指定缓存的有效期,以防止缓存过期,从而减少网络请求,提高页面加载速度。

1. HTTP缓存机制中,可以通过指定过期时间来控制缓存的有效期。在HTTP响应中,可以使用以下两个首部字段来指定过期时间:
- Cache-Control:用于指定缓存的有效期,单位为秒。
- Expires:用于指定缓存的到期时间,格式为GMT格式的日期。
2. Cache-Control优先级高于Expires,如果同时指定了这两个首部字段,则Cache-Control的设置将生效。
例如: 设置Cache-Control为31536000秒,表示缓存的有效期为1年: Cache-Control: max-age=31536000

  • 前端页面的缓存有什么作用?
1. 缓存可以减少服务器的负载,提高服务器的响应速度。
2. 缓存可以减少浏览器的请求次数,提高页面的加载速度。
  • 前端页面的缓存有哪些方法?

    1. 本地缓存:本地缓存是指浏览器缓存数据到本地磁盘,下次访问时直接从本地缓存中获取数据,减少网络请求。
    2. 内存缓存:内存缓存是指浏览器缓存数据到内存中,下次访问时直接从内存缓存中获取数据,减少网络请求。
    3. 服务器缓存:服务器缓存是指服务器缓存数据到本地磁盘,下次访问时直接从本地磁盘获取数据,减少网络请求。
    4. 网页快照:网页快照是指浏览器将当前页面的状态保存到本地磁盘,下次访问时直接从本地磁盘获取页面状态,减少页面渲染时间。
    

  • 前端页面的刷新有什么作用?

    1. 刷新页面可以清除浏览器的缓存,从而获取最新的资源。
    2. 刷新页面可以触发浏览器的重新渲染,从而更新页面显示。
    

页面的SEO有什么作用?

什么是SEO?

SEO(Search Engine Optimization,搜索引擎优化)是指通过对网站的页面内容进行优化,提升网站在搜索引擎结果中的排名,从而提高网站的流量。SEO的主要目标是让网站的页面内容可以被搜索引擎检索到,并被收录,因此,SEO的关键在于页面内容的质量。

SEO的工作原理是:搜索引擎通过爬虫抓取网站的网页,然后分析网页内容,根据页面内容生成索引,并将索引提交给搜索引擎,搜索引擎根据索引对网站进行排名,以便用户找到网站。

Vue 实现SEO

  • vue.js官网提供的 SSR(服务端渲染)

Vue.js官网提供了服务端渲染(SSR)的解决方案,可以将Vue.js应用渲染成HTML字符串,然后将HTML字符串发送给浏览器,实现SEO。

Vue.js SSR的实现主要分为两步:
服务器渲染:在服务器上运行Vue.js应用,生成HTML字符串,并将HTML字符串发送给浏览器。
客户端渲染:在浏览器上运行Vue.js应用,将渲染好的HTML字符串与Vue.js应用绑定,实现数据绑定、事件处理等功能。

1. 服务器渲染:
Vue.js SSR的服务器渲染主要依赖于Node.js,因此需要在服务器上安装Node.js环境。
首先,安装Vue.js SSR插件:npm install @vue/server-renderer
配置服务器端渲染脚本:Vue.js SSR插件渲染Vue.js应用
const { createRenderer } = require('@vue/server-renderer')
const Vue = require('vue')
const app = new Vue({
  template: '<div>Hello World</div>'
})
const renderer = createRenderer()
renderer.renderToString(app, (err, html) => {
  if (err) {
    console.error(err)
    return
  }
  console.log(html)
})

2. 客户端渲染
Vue.js SSR的客户端渲染主要依赖于Vue.js的客户端渲染插件,因此需要在浏览器上安装Vue.js客户端渲染插件。
安装Vue.js客户端渲染插件:npm install vue-server-renderer
配置客户端渲染脚本:Vue.js客户端渲染插件渲染Vue.js应用
const { createApp } = Vue
const app = createApp({
  template: '<div>Hello World</div>'
})
app.mount('#app')

3. 编写HTML文件
在服务器渲染脚本中,通过createRenderer()方法创建渲染器,并调用renderToString()方法渲染Vue.js应用,获取渲染后的HTML字符串。
在客户端渲染脚本中,通过createApp()方法创建Vue.js应用实例,并调用mount()方法将渲染好的HTML字符串与Vue.js应用绑定。
编写一个HTML文件,使用Vue.js客户端渲染插件渲染Vue.js应用:
<!DOCTYPE html>
<html>
<head>
  <title>Vue.js SSR</title>
</head>
<body>
  <div id="app"></div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
  <script>
    const { createApp } = Vue
    const app = createApp({
      template: '<div>Hello World</div>'
    })
    app.mount('#app')
  </script>
</body>
</html>

运行这个HTML文件,可以看到渲染好的Vue.js应用,Vue.js SSR的实现就完成了。

4. Vue.js SSR的配置主要有以下几点:
在服务器渲染脚本中,通过createRenderer()方法创建渲染器。
在渲染器的renderToString()方法中,传入Vue.js应用实例和回调函数,渲染Vue.js应用并获取渲染后的HTML字符串。
在客户端渲染脚本中,通过createApp()方法创建Vue.js应用实例,并调用mount()方法将渲染好的HTML字符串与Vue.js应用绑定。
  • vue + prerender-spa-plugin 实现SEO prerender-spa-plugin是一个基于webpack的插件,它可以帮助你在构建时预渲染你的SPA,并将渲染后的HTML、CSS、JavaScript等静态资源输出到指定目录,供搜索引擎爬虫使用。

1. 安装prerender-spa-plugin: npm install prerender-spa-plugin --save-dev
2. 在webpack.config.js中配置prerender-spa-plugin:
const PrerenderSPAPlugin = require('prerender-spa-plugin')
module.exports = {
  plugins: [
    new PrerenderSPAPlugin({
      // 输出路径
      outputDir: path.join(__dirname, 'dist'),
      // 预渲染的路由
      routes: ['/', '/about'],
      // 预渲染时需要渲染的模块
      renderer: new PrerenderSPAPlugin.PuppeteerRenderer({
        // 超时时间
        timeout: 5000,
        // 等待时间
        waitUntil: 'networkidle2'
      })
    })
  ]
}

3. 在package.json中添加"build": "npm run build:prerender"命令,执行npm run build:prerender命令,即可生成预渲染后的静态资源。
如何配置prerender-spa-plugin:
1. outputDir:指定输出路径,默认为dist。
2. routes:指定预渲染的路由,默认为['/']。
3. renderer:指定渲染器,默认为PrerenderSPAPlugin.PuppeteerRenderer。
4. timeout:指定超时时间,默认为5000。
5. waitUntil:指定等待时间,默认为networkidle2。

React 实现SEO

React 官网提供了一些工具来帮助你实现SEO,包括:

  • react-helmet:用于管理React应用中的head标签。
  • react-meta-tags:用于管理React应用中的meta标签。
  • react-snapshot:用于实现React应用的静态站点生成。
1. 安装react-helmet:npm install react-helmet --save
2. 在组件中使用react-helmet:
import React from "react";
import { Helmet } from "react-helmet";

class App extends React.Component {
  render() {
    return (
      <div>
        <Helmet>
          <title>My App</title>
          <meta name="description" content="My App description" />
        </Helmet>
        <h1>Hello World</h1>
      </div>
    );
  }
}
3. 在index.js中使用react-helmet:
import ReactDOM from "react-dom";
import { HelmetProvider } from "react-helmet-async";
import App from "./App";

ReactDOM.render(
  <HelmetProvider>
    <App />
  </HelmetProvider>,
  document.getElementById("root")
);

如何配置react-helmet:

1. title:设置页面标题。
2. meta:设置页面的meta标签。
3. link:设置页面的link标签。
4. script:设置页面的script标签。
5. noscript:设置页面的noscript标签。
6. base:设置页面的base标签。
7. style:设置页面的style标签。

如何配置react-meta-tags:

1. 设置title:
import MetaTags from "react-meta-tags";

<MetaTags>
  <title>My App</title>
</MetaTags>

2. 设置meta标签:
<MetaTags>
  <meta name="description" content="My App description" />
</MetaTags>

3. 设置link标签:
<MetaTags>
  <link rel="canonical" href="https://example.com/my-app" />
</MetaTags>

4. 设置script标签:
<MetaTags>
  <script src="https://example.com/my-app.js" />
</MetaTags>

5. 设置noscript标签:
<MetaTags>
  <noscript>
    <meta name="description" content="My App description" />
  </noscript>
</MetaTags>

6. 设置base标签:
<MetaTags>
  <base href="https://example.com/my-app/" />
</MetaTags>

7. 设置style标签:
<MetaTags>
  <style type="text/css">
    body {
      background-color: #f0f0f0;
    }
  </style>
</MetaTags>

如何配置react-snapshot:

1. 安装react-snapshot:npm install react-snapshot --save-dev
2. 在package.json中添加"build": "react-snapshot"命令,执行npm run build命令,即可生成静态站点。
3. 配置react-snapshot:
"react-snapshot": {
  "source": "public",
  "target": "build",
  "routes": [
    "/"
  ]
}
4. 配置public目录:
在public目录下创建index.html文件,并在其中添加如下内容:
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>My App</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
5. 配置package.json:
"homepage": "build",
"scripts": {
  "start": "react-scripts start",
  "build": "react-snapshot",
  "test": "react-scripts test",
  "eject": "react-scripts eject"
}

如何使用react-snapshot:

1. 在public目录下创建index.html文件,并在其中添加如下内容:
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>My App</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
2. 在src目录下创建App.js文件,并在其中添加如下内容:
import React from "react";

function App() {
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
}

export default App;
3. 在package.json中添加"build": "react-snapshot"命令,执行npm run build命令,即可生成静态站点。

页面的性能优化有哪些方法?

  • 减少HTTP请求:减少HTTP请求可以减少页面加载时间,提高页面的加载速度。例如:合并CSS、JavaScript、图片,压缩HTML、CSS、JavaScript,使用CDN等。
  • 减少DOM元素数量:减少DOM元素数量可以减少页面的渲染时间,提高页面的加载速度。例如:减少DOM操作,使用虚拟DOM等。
  • 减少JavaScript执行时间:减少JavaScript执行时间可以减少页面的渲染时间,提高页面的加载速度。例如:使用Web Worker,异步加载等。
  • 优化CSS样式:优化CSS样式可以减少页面的渲染时间,提高页面的加载速度。例如:使用CSS Sprites,CSS雪碧图,CSS动画,CSS Media Query等。
  • 优化图片:优化图片可以减少页面的渲染时间,提高页面的加载速度。例如:压缩图片,使用WebP格式等。
  • 优化服务器响应:优化服务器响应可以减少服务器的负载,提高页面的加载速度。例如:压缩HTTP响应,使用CDN等。
  • 优化服务器配置:优化服务器配置可以减少服务器的负载,提高页面的加载速度。例如:配置Etag,配置Gzip,配置缓存等。
  • 优化数据库查询:优化数据库查询可以减少服务器的负载,提高页面的加载速度。例如:使用缓存,使用索引,使用预加载等。
  • 优化服务器硬件:优化服务器硬件可以减少服务器的负载,提高页面的加载速度。例如:使用SSD硬盘,使用更快的CPU,使用更大的内存等。
  • 优化网络连接:优化网络连接可以减少服务器的负载,提高页面的加载速度。例如:使用CDN,使用更快的网络等。
  • 优化DNS解析:优化DNS解析可以减少服务器的负载,提高页面的加载速度。例如:使用DNS预解析,使用HTTP/2等。
  • 优化浏览器缓存:优化浏览器缓存可以减少服务器的负载,提高页面的加载速度。例如:使用浏览器缓存,使用本地缓存等。
  • 优化浏览器插件:优化浏览器插件可以减少服务器的负载,提高页面的加载速度。例如:禁用Flash,禁用Java等。
  • 优化服务器软件:优化服务器软件可以减少服务器的负载,提高页面的加载速度。例如:使用Nginx、Apache、Treafik等。
  • 优化服务器架构:优化服务器架构可以减少服务器的负载,提高页面的加载速度。例如:使用负载均衡,使用集群等。
  • 压缩JavaScript、CSS、图片:压缩JavaScript、CSS、图片可以减少文件体积,加快页面的加载速度。例如:gzip压缩,brotli压缩等。
  • 优化CSS选择器:优化CSS选择器可以减少页面的渲染时间,提高页面的加载速度。例如:使用ID选择器,避免使用通用选择器等。
  • 优化字体文件:优化字体文件可以减少页面的渲染时间,提高页面的加载速度。例如:使用WOFF、WOFF2格式等。
  • 优化Web字体:优化Web字体可以减少页面的渲染时间,提高页面的加载速度。例如:使用字体压缩,使用字体内嵌等。
  • 优化HTML结构:优化HTML结构可以减少DOM元素数量,减少页面的渲染时间,提高页面的加载速度。例如:使用语义化标签,减少无用标签等。
  • 优化JavaScript事件:优化JavaScript事件可以减少页面的渲染时间,提高页面的加载速度。例如:使用事件委托,避免使用多次绑定事件等。
  • 优化浏览器渲染:优化浏览器渲染可以减少页面的渲染时间,提高页面的加载速度。例如:使用WebGL,CSS3动画,使用硬件加速等。
  • 优化JavaScript代码:优化JavaScript代码可以减少页面的渲染时间,提高页面的加载速度。例如:使用压缩代码,使用缓存等。
  • 使用CDN:使用CDN可以提高页面的加载速度,降低服务器的负载。
  • 缓存:缓存可以减少服务器的负载,提高页面的加载速度。
  • 预加载:预加载可以提高页面的加载速度,降低服务器的负载。
  • 异步加载:异步加载可以提高页面的加载速度,降低服务器的负载。例如:懒加载,按需加载等。
  • 避免重定向:避免重定向可以提高页面的加载速度,降低服务器的负载。例如:使用HTML5 History API,使用HTTP缓存等。
  • 避免空闲连接:避免空闲连接可以减少服务器的负载,提高页面的加载速度。例如:使用keep-alive连接,使用长连接等。
  • 压缩HTML:压缩HTML可以减少页面的加载时间,提高页面的加载速度。例如:gzip压缩,brotli压缩等。
  • 压缩HTTP响应:压缩HTTP响应可以减少页面的加载时间,提高页面的加载速度。例如:gzip压缩,brotli压缩等。
  • 避免使用iframe:避免使用iframe可以减少页面的渲染时间,提高页面的加载速度。例如:使用CSS3动画,使用WebGL等。
  • 避免使用CSS表达式:避免使用CSS表达式可以减少页面的渲染时间,提高页面的加载速度。例如:background-image: url('expression(this.src="https://example.com/image.png?v=" + this.value)');
  • 避免使用CSS导入:避免使用CSS导入可以减少页面的渲染时间,提高页面的加载速度。例如:@import url('https://example.com/style.css');
  • 避免使用JavaScript框架:避免使用JavaScript框架可以减少页面的渲染时间,提高页面的加载速度。例如:jQuery、AngularJS、ReactJS、VueJS等。
  • 避免使用CSS框架:避免使用CSS框架可以减少页面的渲染时间,提高页面的加载速度。例如:Bootstrap、Material UI等。
  • 避免使用CSS预处理器:避免使用CSS预处理器可以减少页面的渲染时间,提高页面的加载速度。例如:Sass、Less、Stylus等。
  • 避免使用JavaScript模板:避免使用JavaScript模板可以减少页面的渲染时间,提高页面的加载速度。例如:Handlebars、Mustache等。

前端localStorage、sessionStorage、cookie使用场景?

  • localStorage、sessionStorage、cookie的作用
1. localStorage:localStorage是HTML5新增的本地存储,可以将数据存储在本地,除非主动删除,否则数据在浏览器关闭后依然存在。
2. sessionStorage:sessionStorage和localStorage类似,也是在浏览器端存储数据,但生命周期与页面会话相同,页面关闭后数据也会被清除。
3. cookie:cookie是服务器发送到用户浏览器并保存在本地的小数据块,它会在同一浏览器上所有同域请求中携带,用于保存用户的相关信息。
  • localStorage、sessionStorage、cookie的区别
1. 生命周期:localStorage和sessionStorage的生命周期长于cookie,除非被清除,否则一直存在。cookie的生命周期与设置的过期时间有关。
2. 存储大小:localStorage和sessionStorage的存储容量更大,可以存储更多数据。cookie的大小限制是4KB。
3. 安全性:localStorage和sessionStorage在客户端,不安全,可能会被窃取、篡改。cookie在客户端,安全,不会被窃取、篡改。
4. 访问权限:localStorage和sessionStorage只能由同源的文档共享,而cookie可以在不同源的文档间共享。
5. 存储位置:localStorage和sessionStorage存储在本地,cookie存储在服务器。
  • 如何使用localStorage、sessionStorage、cookie?
1. localStorage、sessionStorage、cookie的使用方法

localStorage.setItem('key', 'value'); // 设置localStorage
sessionStorage.setItem('key', 'value'); // 设置sessionStorage
document.cookie = 'key=value'; // 设置cookie

2. localStorage、sessionStorage、cookie的读取方法

localStorage.getItem('key'); // 读取localStorage
sessionStorage.getItem('key'); // 读取sessionStorage
document.cookie.split('; ').find(row => row.startsWith('key=')).split('=')[1]; // 读取cookie

3. localStorage、sessionStorage、cookie的删除方法

localStorage.removeItem('key'); // 删除localStorage
sessionStorage.removeItem('key'); // 删除sessionStorage
document.cookie = 'key=;expires=' + new Date(0).toUTCString(); // 删除cookie
  • React中如何使用localStorage、sessionStorage、cookie?
1. 在React组件中使用localStorage、sessionStorage、cookie:

import React, { useState, useEffect } from "react";

function App() {
  const [name, setName] = useState(localStorage.getItem("name") || "");

  useEffect(() => {
    localStorage.setItem("name", name);
  }, [name]);

  return (
    <div>
      <input value={name} onChange={(e) => setName(e.target.value)} />
    </div>
  );
}

2. 在React组件中使用cookie:

import React, { useState, useEffect } from "react";

function App() {
  const [name, setName] = useState(
    document.cookie.split("; ").find((row) => row.startsWith("name="))
     ?.split("=")[1] || ""
  );

  useEffect(() => {
    document.cookie = `name=${name}`;
  }, [name]);

  return (
    <div>
      <input value={name} onChange={(e) => setName(e.target.value)} />
    </div>
  );
}
  • Vue 如何使用localStorage、sessionStorage、cookie?
1. 在Vue组件中使用localStorage、sessionStorage、cookie:

<template>
  <div>
    <input v-model="name" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: localStorage.getItem("name") || "",
    };
  },
  watch: {
    name: {
      handler(newValue) {
        localStorage.setItem("name", newValue);
      },
      deep: true,
    },
  },
};
</script>

2. 在Vue组件中使用cookie:

<template>
  <div>
    <input v-model="name" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: document.cookie.split("; ").find((row) => row.startsWith("name="))
       ?.split("=")[1] || "",
    };
  },
  watch: {
    name: {
      handler(newValue) {
        document.cookie = `name=${newValue}`;
      },
      deep: true,
    },
  },
};
</script>

React 性能优化有哪些方法?

  • React框架中如何对组件按需加载?

React框架中按需加载是指在应用中只加载当前需要的组件,而不是全部加载,从而减少应用的初始加载时间。React框架提供了动态 import() 语法来实现代码分割,按需加载。

const OtherComponent = React.lazy(() => import('./OtherComponent'));
1. 在组件中使用React.lazy()方法来动态导入组件。使用动态 import() 语法实现代码分割,按需加载功能模块。这样可以将应用分块,只在用户需要时加载对应的代码。
2. 懒加载:懒加载优化一般用于从一个路由跳转到另一个路由,或者展示用户操作后才显示的复杂组件(如弹窗模块); 
   a. 结合 Webpack 的动态导入和 React.lazy 方法来实现懒加载。
   b. 在组件中使用Suspense组件来渲染加载中的状态, Suspense组件可以渲染加载中的状态,直到组件加载完成; 结合React.lazy和Suspense组件来实现懒加载。
    <React.Suspense fallback={<div>Loading...</div>}>
      <OtherComponent />
    </React.Suspense>
3. 懒渲染:只在组件进入或即将进入可视区域时才渲染组件。常见的场景包括页面中出现多次的组件、或者需要用户操作后才展示的组件。
   a.使用 react-visibility-observer 监听组件是否出现在可视区域内。
   b. 使用React.memo来对纯函数组件进行优化,避免传递相同的props时触发不必要的渲染。
   c. 使用React.lazy和React.Suspense来实现懒加载,延迟加载组件,减少首屏渲染时间。
   d. 使用IntersectionObserver API来监听组件是否出现在可视区域内,减少不必要的渲染。
4. 代码拆分:代码拆分是指将代码分割成多个文件,从而减少应用的初始加载时间。
   a. 使用Webpack的SplitChunksPlugin插件将公共模块提取到单独的chunk中。
   b. 使用Webpack的AggressiveSplittingPlugin插件将模块分割成多个块,并将块按需加载。
  • React框架中如何对组件进行性能优化?
1.使用shouldComponentUpdate生命周期方法来避免不必要的渲染。通过在shouldComponentUpdate中比较组件的新旧props和state,决定是否进行重新渲染。
2.使用React.memo来对纯函数组件进行优化,避免传递相同的props时触发不必要的渲染。
3.使用React.lazy和React.Suspense来实现按需加载,延迟加载组件,减少首屏渲染时间。
4.使用React.PureComponent来替代普通的组件,减少不必要的渲染。
5.使用reselect库来缓存计算结果,避免重复计算导致的性能损耗。
  • 如何利用React框架中的虚拟DOM进行性能优化?
1.使用key属性为列表中的每个元素提供唯一的标识,这样React可以准确地识别插入、移除和更新的元素,避免不必要的重渲染和DOM操作。
2.批量更新state或props,可以使用React的setState方法的回调函数形式来一次性更新多个属性,减少不必要的渲染和重排操作。
3.利用React的Fragment(空标签<></>)来避免生成多余的DOM节点,减少渲染开销。
4.在列表或长列表中,使用React-virtualized等虚拟滚动库来只渲染可见的元素,提高渲染性能。
  • 如何使用React DevTools进行性能优化?
1.使用React DevTools中的"Performance"选项卡来分析应用程序的性能瓶颈和耗时操作。
2.使用React DevTools中的"Profiler"组件来检测组件渲染所花费的时间,并进行性能优化。
3.使用React DevTools中的"Flamegraph"查看代码运行时的时间分布图,找出可能存在的性能问题,并优化代码逻辑。
4.使用React DevTools中的"Highlight Updates"功能来可视化观察组件的更新和重新渲染过程,找出不必要的渲染和更新操作,进行优化。
  • 如何使用React的错误边界进行错误处理?
React 16.x版本中引入了错误边界(Error Boundaries)机制,可以捕获组件树中的错误,并渲染出错误界面。

错误边界是一个特殊的组件,它可以捕获其子组件树中的错误,并渲染出错误界面,而不是崩溃整个应用。

错误边界的使用方法:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    // 记录错误日志
    console.log(error, info);
    // 更新状态
    this.setState({ hasError: true });
  }

  render() {
    if (this.state.hasError) {
      // 显示错误界面
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

// 使用错误边界包裹需要捕获错误的组件
<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>
  • React 打包gz性能优化?
1.使用webpack的compression-webpack-plugin插件压缩gzip文件。
2.使用webpack的SplitChunksPlugin插件将公共模块提取到单独的chunk中。
3.使用webpack的BundleAnalyzerPlugin插件分析打包后的模块依赖关系。
const CompressionPlugin = require("compression-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
module.exports = {
  plugins: [
    new CompressionPlugin(),
    new BundleAnalyzerPlugin(),
  ],
};
4.使用HtmlWebpackPlugin 找到 plugins 配置项,可以将gzip配置加在plugins的第一项
new CompressionPlugin({
  filename: '[path][base].gz',
  algorithm: 'gzip', // 算法       
  test: new RegExp('\\.(js|css)$'), // 压缩 js 与 css
  threshold: 10240, // 只处理比这个值大的资源。按字节计算
  minRatio: 0.8 // 只有压缩率比这个值小的资源才会被处理
}),
  • React 打包体积优化?
1.使用webpack的Tree Shaking功能,只打包用到的模块。
2.使用webpack的externals功能,将不常用的模块打包到CDN上。
3.使用webpack的DllPlugin插件,将公共模块提取到单独的chunk中,并使用DllReferencePlugin引用。
4.使用webpack的LimitChunkCountPlugin插件,限制chunk的数量。
5.使用webpack的AggressiveMergingPlugin插件,减少模块合并的次数。
6.使用webpack的UglifyJsPlugin插件,压缩代码。
  • React 路由性能优化?
1.使用React-Router-Dom的useParams、useLocation等hooks来获取路由参数。
2.使用React-Router-Dom的useHistory、useLocation等hooks来获取路由历史记录。
3.使用React-Router-Dom的useRouteMatch等hooks来匹配路由。
4.使用React-Router-Dom的NavLink组件来渲染路由链接。
5.使用React-Router-Dom的Switch组件来渲染路由匹配结果。
6.使用React-Router-Dom的MemoryRouter、HashRouter等组件来渲染路由。
7.使用React-Router-Dom的withRouter组件来获取路由信息。
8.使用React-Router-Dom的Prompt组件来处理路由跳转确认。
9.使用React-Router-Dom的useSearchParams组件来处理查询参数。
  • React 状态管理性能优化?
1.使用React-Redux的 useSelector、useDispatch等hooks来获取状态和更新状态、避免不必要的渲染、缓存计算结果、传递相同的props、传递函数、传递大对象、传递可变对象、传递过多的props、传递过多的state、传递过多的依赖。
2.使用React-Redux的 connect、Provider等组件来实现状态管理。
3.使用React-Redux的 useSelector、useDispatch等hooks来避免不必要的事件绑定、事件冒泡、事件捕获、事件委托。
  • React 异步编程性能优化?
1.使用React的Suspense组件来实现异步组件的懒加载。
2.使用React的useCallback、useMemo等hooks来避免不必要的渲染、缓存计算结果、传递相同的props、传递函数、传递大对象、传递可变对象、传递过多的props、传递过多的state、传递过多的依赖。
3.使用React的 useCallback、useMemo等hooks来避免不必要的事件绑定、事件冒泡、事件捕获、事件委托。
4.使用React的useRef、useImperativeHandle等hooks来避免不必要的渲染。

Service Worker性能优化?

Service workers 本质上充当Web应用程序与浏览器之间的代理服务器,也可以在网络可用时作为浏览器和网络间的代理。它们旨在(除其他之外)使得能够创建有效的离线体验,拦截网络请求并基于网络是否可用以及更新的资源是否驻留在服务器上来采取适当的动作。他们还允许访问推送通知和后台同步API。

1.使用React的Service Worker来缓存静态资源,提高应用的响应速度。
2.sw将页面的文件存储在客户端,下次打开页面可以不向服务器发出资源请求,极大的加快页面加载速度。
2.sw运行在页面后台,使用了sw的页面可以利用sw来拦截页面发出的请求,同时配合CacheAPI可以将请求缓存到客户本地,提高应用的响应速度。
3.离线打开页面的同时可以在sw发出请求,更新本地的资源文件
4.sw可以监听页面的激活状态,当页面处于激活状态时,可以更新页面的资源文件,提高应用的响应速度。
5.sw的生命周期:sw的生命周期分为安装、激活、fetch、message、sync、push、notificationclick、pushsubscriptionchange、sync、periodicsync等事件。
  - install:sw安装成功后,会触发install事件,此时可以进行资源的预缓存,将静态资源缓存到sw的缓存中,提高页面的响应速度。
  - activate:sw激活成功后,会触发activate事件,此时可以将缓存的资源更新到最新版本。
  - fetch:当页面发起请求时,会触发fetch事件,此时可以从缓存中获取资源,提高页面的响应速度。
  - message:当页面发起消息时,会触发message事件,此时可以接收到消息。
  - sync:当页面发起同步请求时,会触发sync事件,此时可以同步数据。
  - push:当页面发起推送消息时,会触发push事件,此时可以接收到推送消息。
  - notificationclick:当用户点击通知时,会触发notificationclick事件,此时可以处理通知。
  - pushsubscriptionchange:当订阅发生变化时,会触发pushsubscriptionchange事件,此时可以更新订阅。
  - sync:当页面发起同步请求时,会触发sync事件,此时可以同步数据。
  - periodicsync:当页面发起定期同步请求时,会触发periodicsync事件,此时可以同步定期数据。

缺点:
1.sw无法监听页面的激活状态,无法更新页面的资源文件,无法实现离线打开页面的同时可以在sw发出请求,更新本地的资源文件。
2.sw的缓存机制有限,缓存的资源有限,缓存的有效期有限。
3.由于打开页面不再向服务器发出页面请求,因此当服务器上的页面有新版本的时候客户端无法及时升级
4.sw存在一定的兼容性问题,不同浏览器的兼容性不同。
5.sw文件至少要与入口页面文件在同一目录下,否则无法正常工作。如果入口页面文件与sw文件不在同一目录下,则需要配置webpack的publicPath属性。
  • 如何使用webpack-sw-plugin插件配置Service Worker?
1、安装:npm install webpack-sw-plugin --save-dev

2、配置webpack.config.js文件:
    const WebpackSWPlugin = require('webpack-sw-plugin');
    module.exports = {
      entry: {
        app: './src/index.js',
        sw: './src/sw.js'
      },
      plugins: [
        new WebpackSWPlugin({
          cacheId: 'cache-id',
          filename: 'service-worker.js',
          minify: true,
          clientsClaim: true,
          skipWaiting: true,
          runtimeCaching: [
            {
              urlPattern: '/',
              handler: 'NetworkFirst',
              options: {
                cacheName: 'cache-name',
                networkTimeoutSeconds: 20,
                expiration: {
                  maxEntries: 10,
                  maxAgeSeconds: 30
                },
                cacheableResponse: {
                  statuses: [0, 200]
                }
              }
            }
          ]
        })
      ]
    } 

3、编写sw.js文件:

    // 监听install事件
    self.addEventListener('install', event => {
      event.waitUntil(
        caches.open('cache-name').then(cache => {
          return cache.addAll([
            '/',
            '/index.html',
            '/index.js',
            '/style.css'
          ]);
        })
      );
    });

    // 监听fetch事件
    self.addEventListener('fetch', event => {
      event.respondWith(
        caches.match(event.request).then(response => {
          if (response) {
            return response;
          }
          return fetch(event.request);
        })
      );
    });

    // 监听activate事件
    self.addEventListener('activate', event => {
      event.waitUntil(
        caches.keys().then(cacheNames => {
          return Promise.all(
            cacheNames.map(cacheName => {
              if (cacheName !== 'cache-name') {
                return caches.delete(cacheName);
              }
            })
          );
        })
      );
    });

4、入口注册sw文件:

  import './sw.js';
  // 判断是否支持sw
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
      navigator.serviceWorker.register('/sw.js')
       .then(registration => {
          console.log('SW registered: ', registration);
        })
       .catch(registrationError => {
          console.log('SW registration failed: ', registrationError);
        });
    });
  }

前端如何抓包?

  • 什么是抓包?

抓包(英语:packet sniffer)是指通过网络分析工具,实时监控网络数据包,获取网络数据包的传输过程,从而分析、记录、保存或转发这些数据包。

  • 如何抓包?
    第一步:安装抓包工具,如Fiddler、Wireshark、Charles。
    第二步:启动抓包工具,并选择需要抓取的网络接口。
    第三步:配置抓包规则,如过滤条件、数据包分析等。
    第四步:开始抓包。
    第五步:分析抓包结果。
    
  • 如何分析抓包结果?
    - 第一步:查看抓包结果,确认是否存在安全隐患。
    - 第二步:分析数据包的传输过程,确认数据包的来源、目的、内容、大小、时间等信息。
    - 第三步:分析数据包的协议,确认数据包的协议类型、版本、加密方式等信息。
    - 第四步:分析数据包的传输内容,确认数据包的传输内容是否存在安全隐患。
    - 第五步:分析数据包的传输方式,确认数据包的传输方式是否存在安全隐患。
    
  • 抓包工具的选择建议?
    1. 对于初级用户,建议使用Wireshark,它是开源的、功能强大的抓包工具,可以抓取HTTP、HTTPS、FTP、SMTP、POP3、IMAP、RTSP、RTMP、SSH、Telnet等协议的数据包。
    2. 对于高级用户,建议使用Fiddler,它是一款功能强大的抓包工具,可以抓取HTTP、HTTPS、WebSocket、FTP、SMTP、POP3、IMAP、RTSP、RTMP、SSH、Telnet等协议的数据包,并且可以自定义规则。
    3. 对于专业用户,建议使用Charles,它是一款功能强大的抓包工具,可以抓取HTTP、HTTPS、WebSocket、FTP、SMTP、POP3、IMAP、RTSP、RTMP、SSH、Telnet等协议的数据包,并且可以自定义规则。
    4. 对于抓包分析人员,建议使用Wireshark,它是开源的、功能强大的抓包工具,可以抓取HTTP、HTTPS、FTP、SMTP、POP3、IMAP、RTSP、RTMP、SSH、Telnet等协议的数据包,并且可以自定义规则。
    

前端安全相关问题

前端安全攻击有哪些?

前端安全攻击一般分为以下几类:

  • 跨站脚本攻击(XSS):跨站脚本攻击(XSS)是指攻击者通过恶意攻击JavaScript代码,插入恶意脚本,窃取用户信息,篡改页面内容,从而盗取用户隐私信息或执行恶意操作。如:恶意攻击者将恶意代码注入到网页中,当用户访问该网页时,恶意代码将被执行,从而盗取用户信息、篡改网页内容、执行恶意操作等。
  • 跨站请求伪造(CSRF):跨站请求伪造(CSRF)是一种攻击方式,攻击者诱导受害者进入第三方网站,然后在第三方网站中,向被攻击网站发送跨站请求。利用受害者在浏览器里保存的痕迹,绕过网站的防御机制,冒充用户对其进行操作,达到利用受害者在网站上存储的私密信息的目的。
  • 点击劫持:点击劫持(Clickjacking)是一种攻击方式,攻击者诱导受害者点击一个链接或按钮,但实际上并没有点击,而是通过其他方式诱导用户点击,比如通过恶意的iframe嵌入攻击者的网页,或者通过恶意的图片重定向攻击者的网页。当用户点击该链接或按钮时,实际上是被攻击者网页劫持了,从而盗取用户信息、篡改网页内容、执行恶意操作等。
  • 代码注入攻击:代码注入攻击(Code Injection Attack)是指攻击者通过恶意攻击JavaScript代码,插入恶意脚本,窃取用户信息,篡改页面内容,从而盗取用户隐私信息或执行��意操作。如:恶意攻击者将恶意代码注入到网页中,当用户访问该网页时,恶意代码将被执行,从而盗取用户信息、篡改网页内容、执行恶意操作等。
  • 安全漏洞:安全漏洞是指程序中存在的漏洞,攻击者利用这些漏洞可以对网站进行攻击,如SQL注入、XSS跨站脚本攻击、CSRF跨站请求伪造、点击劫持、代码注入攻击等。
  • 安全配置错误:安全配置错误是指程序中存在的配置错误,如未启用HTTPS、未设置密码复杂度、未设置安全HTTP标头等。
  • 网络钓鱼攻击:网络钓鱼攻击是指攻击者通过恶意攻击,诱导用户点击链接,将用户引导到钓鱼网站,从而获取用户个人信息,或进行其他恶意操作。如:恶意攻击者通过诱导用户点击链接,将用户引导到钓鱼网站,然后在钓鱼网站上收集用户个人信息,或进行其他恶意操作。
  • 垃圾邮件攻击:垃圾邮件攻击是指攻击者通过发送垃圾邮件,诱导用户点击链接,从而获取用户个人信息,或进行其他恶意操作。如:恶意攻击者通过发送垃圾邮件,诱导用户点击链接,将用户引导到钓鱼网站,然后在钓鱼网站上收集用户个人信息,或进行其他恶意操作。
  • 垃圾短信攻击:垃圾短信攻击是指攻击者通过发送垃圾短信,诱导用户点击链接,从而获取用户个人信息,或进行其他恶意操作。如:恶意攻击者通过发送垃圾短信,诱导用户点击链接,将用户引导到钓鱼网站,然后在钓鱼网站上收集用户个人信息,或进行其他恶意操作。
  • 垃圾链接攻击:垃圾链接攻击是指攻击者通过诱导用户点击链接,将用户引导到钓鱼网站,从而获取用户个人信息,或进行其他恶意操作。如:恶意攻击者通过诱导用户点击链接,将用户引导到钓鱼网站,然后在钓鱼网站上收集用户个人信息,或进行其他恶意操作。
  • 垃圾评论攻击:垃圾评论攻击是指攻击者通过发布垃圾评论,诱导用户点击链接,从而获取用户个人信息,或进行其他恶意操作。如:恶意攻击者通过发布垃圾评论,诱导用户点击链接,将用户引导到钓鱼网站,然后在钓鱼网站上收集用户个人信息,或进行其他恶意操作。
  • 垃圾网站攻击:垃圾网站攻击是指攻击者通过诱导用户点击链接,将用户引导到钓鱼网站,从而获取用户个人信息,或进行其他恶意操作。如:恶意攻击者通过诱导用户点击链接,将用户引导到钓鱼网站,然后在钓鱼网站上收集用户个人信息,或进行其他恶意操作。
  • 垃圾软件攻击:垃圾软件攻击是指攻击者通过诱导用户点击链接,将用户引导到钓鱼网站,从而获取用户个人信息,或进行其他恶意操作。如:恶意攻击者通过诱导用户点击链接,将用户引导到钓鱼网站,然后在钓鱼网站上收集用户个人信息,或进行其他恶意操作。
  • 病毒攻击:病毒攻击是指攻击者通过恶意攻击,将病毒植入用户计算机,从而控制用户的计算机,或进行其他恶意操作。如:恶意攻击者通过恶意攻击,将病毒植入用户计算机,控制用户的计算机,或进行其他恶意操作。
  • 其他攻击方式:其他攻击方式是指网站存在其他攻击方式,如SQL注入、命令执行、文件上传漏洞等。

前端页面的安全有哪些方法?

前端安全防护一般分为以下几类:

  • 输入内容的验证:输入内容的过滤是指对用户输入的数据进行过滤,防止恶意攻击,保护网站的安全。例如:使用正则表达式对输入内容进行过滤,限制输入长度、类型、格式等。
  • 验证码的实现:验证码是一种常用的防止恶意攻击的手段,验证码的实现可以有效防止攻击者通过自动化程序或其他方式绕过验证码,提交恶意数据。例如:使用验证码来保护注册、登录等功能。
  • 安全的身份认证:安全的身份认证是指通过用户名和密码等方式,确认用户的身份,以保护网站的安全。例如:使用HTTPS协议加密传输数据,使用JWT、OAuth2等方式进行身份认证。
  • 输入内容的限制:输入内容的限制是指对用户输入的数据进行限制,限制其长度、类型、格式等,以提高网站的安全性。例如:使用maxlength属性限制输入内容的长度,使用onchange事件限制输入内容的类型。
  • 安全防护措施:安全防护措施是指程序中存在的防护措施,如输入验证、输出编码、错误信息隐藏、日志记录、访问控制等。
  • 安全的传输协议:安全的传输协议是指使用安全的传输协议,如HTTPS、SSH等,以提高网站的安全性。
  • 安全的加密算法:安全的加密算法是指使用安全的加密算法,如AES、RSA等,以提高网站的安全性。
  • 安全的加密传输:安全的加密传输是指在传输过程中对数据进行加密,以防止数据被窃取、篡改、伪造等。例如:使用HTTPS协议加密传输数据。
  • 安全的存储:安全的存储是指在存储数据时对数据进行加密,以防止数据被窃取、篡改、泄露等。例如:使用HTTPS协议加密传输数据,使用数据库加密等。
  • 安全的开发过程:安全的开发过程是指在开发过程中,对代码进行安全审计,并在代码中加入必要的安全防护措施,以提高网站的安全性。例如:使用代码扫描工具进行代码安全审计。
  • 安全的运维过程:安全的运维过程是指在运维过程中,对服务器进行安全配置,并在运维文档中加入必要的安全防护措施,以提高网站的安全性。例如:使用安全的操作系统、安全的服务器软件、安全的网络配置等。

前端安全测试有哪些方法?

安全测试是指对网站进行安全测试,以提高网站的安全性。安全测试一般分为以下几类:

  • 静态安全测试:静态安全测试是指对网站的静态资源(如HTML、CSS、JavaScript等)进行安全测试。例如:使用W3C HTML Validator、W3C CSS Validator等工具。
  • 手动测试:手动测试是指在不同浏览器、操作系统、屏幕分辨率等环境下,测试网站的安全性。例如:使用浏览器的开发者工具、模拟手机、模拟平板等。
  • 自动化测试:自动化测试是指使用自动化工具,对网站进行安全性测试。例如,可以使用 Selenium、WebDriverIO、Nightwatch 等工具。
  • 安全性工具:安全性工具是指使用第三方工具,对网站进行安全性测试。例如,可以使用 AppScan、Burp Suite、Nessus、OWASP ZAP、Arachni、WebInspect 等工具。
  • 安全性审计:安全审计测试是指对网站进行安全审计,以评估网站的安全性。例如,可以使用 AppScan、Burp Suite、Nessus、OWASP ZAP、Arachni、WebInspect 等工具。
  • 安全性扫描:安全性扫描是指对网站进行安全性测试,并对测试结果进行分析,以提高网站的安全性。例如,可以使用 AppScan、Burp Suite、Nessus、OWASP ZAP、Arachni、WebInspect 等工具。
  • 安全性报告:安全性报告是指对网站进行安全性测试,并生成安全性报告,以提高网站的安全性。例如,可以使用 AppScan、Burp Suite、Nessus、OWASP ZAP、Arachni、WebInspect 等工具。

其他问题

如何查看前端错误日志?

前端错误日志一般保存在浏览器的开发者工具的 Console 面板中,具体查看方式请自行搜索。

如何处理跨域问题?

跨域问题是指浏览器的同源策略导致的,即不同域名下的页面无法进行交互。解决跨域问题一般需要结合前端代码、浏览器开发者工具 Console 面板、服务器日志等信息进行分析,并进行相应的跨域配置。

前端页面的兼容性有哪些方法?

  • 兼容性的定义:兼容性是指网站在不同浏览器、操作系统、屏幕分辨率等环境下的表现。
  • 兼容性的实现:兼容性的实现可以分为以下几步:
1. 选择合适的开发语言:选择合适的开发语言可以提高网站的开发效率,并减少代码量。例如:使用TypeScript、JavaScript、HTML、CSS等。
2. 选择合适的浏览器:选择合适的浏览器可以提高网站的兼容性,并减少浏览器兼容性问题。例如:使用最新版本的Chrome、Firefox、Safari等。
3. 选择合适的CSS框架:选择合适的CSS框架可以提高网站的视觉效果,并减少CSS兼容性问题。
4. 选择合适的JavaScript框架:选择合适的JavaScript框架可以提高网站的功能性,并减少JavaScript兼容性问题。例如:使用React、Vue、Angular等。
5. 选择合适的浏览器渲染引擎:选择合适的浏览器渲染引擎可以提高网站的渲染性能,并减少渲染兼容性问题。例如:使用Webkit、Blink、Gecko等。
6. 选择合适的字体:选择合适的字体可以提高网站的可读性,并减少字体兼容性问题。例如:使用WOFF、WOFF2、TTF等。
7. 选择合适的图片格式:选择合适的图片格式可以提高网站的加载速度,并减少图片兼容性问题。例如:使用JPEG、PNG、SVG等。
8. 选择合适的浏览器插件:选择合适的浏览器插件可以提高网站的安全性,并减少插件兼容性问题。例如:使用Adblock、Privacy Badger等。
9. 选择合适的服务器:选择合适的服务器可以提高网站的安全性,并减少服务器兼容性问题。例如:使用Nginx、Apache、Treafik等。
10. 选择合适的安全策略:选择合适的安全策略可以提高网站的安全性,并减少安全策略兼容性问题。例如:使用CSP、HSTS、XSS Protection等。

前端页面的兼容性测试有哪些方法?

1. 手动测试:手动测试是指在不同浏览器、操作系统、屏幕分辨率等环境下,测试网站的兼容性。例如:使用浏览器的开发者工具、模拟手机、模拟平板等。
2. 自动化测试:自动化测试是指使用自动化工具,对网站进行兼容性测试。例如,可以使用 Selenium、WebDriverIO、Nightwatch 等工具。
3. 兼容性工具:兼容性工具是指使用第三方工具,对网站进行兼容性测试。例如,可以使用 BrowserStack、SauceLabs 等工具。

参考资料