面试题 - 项目经验

232 阅读5分钟

最近找工作整理了一些面试题,分享给大家一起来学习。如有问题,欢迎指正。

前端面试题系列文章:

单点登录SSO

在多个应用系统中,用户只需要登录一次,即可访问所有相互信任的应用系统

  • 使用redis使session共享 image.png

    1. 登录后将用户信息生成唯一sessionID,记录在Redis数据库中,并将sessionID存放在顶级域名cookie中返回客户端
    2. 用户访问系统,发送请求携带cookie,服务器对获取顶级域名cookie的sessionID与比Redis中的sessionID对比校验

    因使用cookie的限制,子系统域名必须有相同的顶级域名

  • JWT(Json Web Token)

    jwt = header(头部)+ payload(载荷)+ signature(签名)

    • header(头部): 声明类型,这里是JWT; 声明加密的算法,通常直接使用 HMAC SHA256;

    • payload(载荷) 用户信息和过期时间

    • signature(签名) signature = 签名算法(base64(header).base(payload).秘钥)

    image.png

    1. 用户登录成功后,服务器根据用户信息生成jwt(包含用户信息,加密算法,过期时间等)返回给客户端,客户端将jwt存在localStorage中
    2. 系统发送请求时,会将JWT放入HTTP Header中的Authoriztion中,服务器验证验证jwt的有效性(是否过期,签名是否正确等)

权限控制

  • 权限控制系统配置菜单-按钮权限
  • 权限控制系统分配菜单-按钮权限给用户
  • 用户登录后获取菜单按钮权限列表,根据权限列表判断加载出当前用户的菜单列表。
  • 打开菜单页面,获取当前菜单的按钮权限判断按钮展示

大量数据列表渲染

  • 分片渲染
  • 虚拟列表
  • 懒加载-滚动到底部加载

项目性能优化

代码优化

  • 按需加载: 首屏优化,第三方组件库依赖过大,会给首屏加载带来很大的压力,一般解决方式是按需求引入组件

  • 懒加载

    • 路由懒加载

    • 虚拟列表

      大量数据时,列表只加载可视区域内需要的列表项,当滚动发生时,动态通过计算获得可视区域内的列表项,并将非可视区域内存在的列表项删除。

    • 图片资源懒加载

      对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载。

      项目中使用 Vue 的 vue-lazyload 插件

      <img v-lazy="/static/img/1.png">
      
  • 异步加载js文件(async,defer)

  • 资源预加载

    • preload 页面加载的过程中,在浏览器开始主体渲染之前加载
    • prefetch 页面加载完成后,利用空闲时间提前加载

打包优化

  • 使用contenthash对打包文件命名
  • externals排除第三方库,使用cdn加载第三方模块
  • splitChunks分包拆包
  • 生产环境关闭sourceMap

用户体验

  • 骨架屏

首屏加载优化总结及整理

  • webpack打包优化

    • 将第三方包使用cdn引入(externals),减少打包文件体积,利用浏览器缓存,优化加载速度
    • 然后进行拆包分包splitChunk,按需加载chunk文件
    • 使用contentHash对文件进行命名,利用浏览器缓存,优化加载速度
  • 第三方组件库进行按需导入

    借助 babel-plugin-component ,然后可以只引入需要的组件,以达到减小项目体积的目的

    // .babelrc
    {
      "presets": [["es2015", { "modules": false }]],
      "plugins": [
        [
          "component",
          {
            "libraryName": "element-ui",
            "styleLibraryName": "theme-chalk"
          }
        ]
      ]
    }
    
    //文件vue 组件按需引入
    import Vue from 'vue'
    import { Button } from 'element-ui' 
    Vue.use(Button)
    
    
  • 路由懒加载

    ()=> import('./a.vue')
    
  • 图片懒加载

    内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载

    项目中使用 Vue 的 vue-lazyload 插件

    <img v-lazy="/static/img/1.png">
    
  • 使用骨架屏

页面白屏的原因和解决方式

  1. JavaScript 异常 js文件加载解析会阻塞dom的构建,js运行异常会导致页面空白

  2. 低版本ie浏览器不支持项目里用到的es6语法,会导致页面白屏

    解决: 使用babel-polyfill转换为es5语法

assets 文件夹和static文件夹区别

  1. assets中的资源会被webpack处理,打包后会在dist中合并成一个文件;static中的资源不会被webpack处理,打包后直接复制到dist(默认是dist/static)下

遇到的难题如何解决?

  1. 因设备老旧问题,大数据表格卡顿问题, 解决方式:使用虚拟滚动
  2. 因设备老旧问题,应用加载页面会出现3-4秒的空白 解决方式:打包优化,使用骨架屏
    1. 使用webpack-bundle-analyzer插件生成项目代码依赖图,查看文件依赖关系来定位问题
    2. 从入口文件开始查看确定是不是包太大导致,发现入口文件太大了,
      • 将第三方包使用cdn引入(externals),减少打包文件体积,利用浏览器缓存,优化加载速度
      • 然后进行拆包分包splitChunk,按需加载chunk文件
      • 使用contentHash对文件进行命名,利用浏览器缓存,优化加载速度
    3. 使用骨架屏优化加载体验