• 【知识总结】金九银十offer拿到手软的前端面试题——Web篇


    1、前端性能优化

    性能评级工具:PageSpeed

    css

    • 多个css合并,尽量减少http请求
    • 将css文件放在页面最上方
    • remove空的css规则
    • 避免使用css表达式
    • 选择器优化嵌套,尽量避免层级太深
    • 充分利用css继承属性,避免写太多重复的代码
    • 提取公共的css样式,减少代码量
    • 属性值为0时,不添加单位
    • 属性值为小于1的小数时,省略小数点前面的0
    • 使用CSS Sprites将多张图片拼接成一张图片,通过CSS background 属性来访问图片内容

    js

    • 节流、防抖
    • 长列表滚动到可视区域进行动态加载
    • 图片懒加载
    • 使用必包时,在函数结尾删除不需要的局部变量
    • Dom优化操作:
      - 批量添加dom可先createElement创建添加节点,最后一次性加入dom
      - 批量绑定事件,使用事件委托绑定父节点实现,利用了事件的冒泡特性
      - 如果可以使用innerHtml代替appendChild
      - 在Dom操作时添加样式尽量增加calss属性,而不是通过style添加样式,以减少重排

    网络

    • 减少http请求数量
    • 利用浏览器缓存,公共依赖包单独打包文件在一起,避免重复请求
    • 减少cookie大小,尽量用localStorage代替
    • CDN托管静态资源
    • 开启Gzip压缩

    2、浏览器内核

    主要组成:渲染引擎(layout engineerRendering Engine)和JS引擎

    • 渲染引擎:负责获取网页的HTML、XML、图像等,整理讯息,以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器内核的不同对网页的语法解析也不同,所以渲染的效果不同
    • JS引擎:解析和执行JavaScript来实现网页的动态效果

    最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于是指渲染引擎。

    常见的浏览器内核

    • Trident内核:IE、MaxThon、TT、The World、360、搜狗浏览器等
    • Gecko内核:Netscape6及以上版本
    • Presto内核:Opera7及以上
    • Webkit内核:Safari、Chrome

    3、cookies、sessionStorage、localStorage 和 indexDB 的区别

    • cookie是网站为了标示用户身份而储存在用户本地的数据
    • 是否在http请求只能够携带:
      - cookie数据始终是在同源的http请求中携带,跨域需要设置withCredentials = true
      - sesssionStorage、localStorage不会自动把数据存到服务器,而是存在本地
    • 存储大小:
      - cookie:不超过4k
      - sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可达5M甚至更大,因不同浏览器而异
    • 有效时长:
      - cookie在设置的cookie过期时间之前都有效,即使窗口或浏览器关闭
      - localStorage硬盘存储时间持久,浏览器关闭后数据不丢失,除非主动删数据
      - sessionStorage存在内存中,数据在当前浏览器窗口关闭后自动删除

    在这里插入图片描述
    对于cooke,还需主要安全性⚠️:

    • value:如果要保护登录状态,应将该值加密,不能用明文作为用户标识
    • http-only:不能通过js访问cookie,防止XSS攻击
    • secure:只能在协议为https的请求中携带
    • same-site:规定浏览器不能跨域请求中携带cookie,减少CSRF攻击

    4、从输入URL到浏览器显示页面过程中都发生了什么

    1)浏览器中输入url:http or https

    2)通过DNS解析域名的实际ip地址

    • 发送至DNS服务器并获取域名对应的web服务器中对应的ip
    • DNS解析先去浏览器缓存中寻找是否有这个网址对应的ip -> 没有,则去操作系统的DNS缓存中寻找 -> 没有,则去查找路由器的DNS缓存 -> 没有,则去ISP的DNS缓存中个寻找(即浏览器 -> 系统 -> 路由器 -> ISP)

    3)检查浏览器是否有缓存

    • 通过Cache-ControlExpires来检查是否命中强缓存,命中则取本地磁盘的html
    • 如果没有命中强缓存,则会向服务器发出请求,服务器通过Etag和Last-modify来与服务器
      确认返回的响应是否被更改(协商缓存),若无更改则返状态码304 Not Modified,浏览器取本地缓存
    • 若强缓存和协商缓存都没有命中,则返回请求结果

    4)与服务端建立TCP链接

    TCP三次握手建立连接:

    • 客户端通过SYN报文段连接请求,确认服务端是否开启端口准备连接。状态设置为SYN_SEND
    • 服务端如果有开着的端口,并接受连接,就会返回一个SYN+ACK报文回给客户端,状态这只为SYN_RECV
    • 客户端收到服务端的AYN+ACK,向服务端发送ACK报文表示确认,此时客户端和服务端都设置为ESTABLISHED状态,连接建立,可以开始传输数据

    5)浏览器发送请求获取页面html

    • 浏览器向web服务器的ip地址发送相应的http get请求页面html

    6)服务端响应html

    • 这里的服务器可能是server or cdn

    7)浏览器解析html

    • 浏览器下载html数据,将html文档解析成一个个标签,这些标签组成了树状结构
    • 如果解析到style标签则开始解析css,如果解析到了link标签则先异步下载,完成后解析css
    • 如果遇到script标签,判断是行内写法则直接解析执行,如果是src引用则同步下载脚步文件,下载完后立即执行,这里下载过程是阻塞的,其他流程都会等下载完成后执行。

    8)浏览器渲染html

    主要过程是解析html文档组成标签节点树,解析css形成规则样式树,标签节点树和规则样式树共同组成渲染树,浏览器最终显示渲染树展示页面。

    5、对AMD、CMD的理解

    • CommonJS是服务端模块的规范,Nodejs采用了这个规范。CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范是非同步加载模块,允许指定回调函数。
    • AMD推荐的风格通过返回一个对象作为模块对象,CommonJS的风格则是对module.exportsexports的属性赋值来达到暴露模块对象的目的。

    es6模块 CommonJS、AMD、CMD

    • 在CommonJS规范中,每个js文件就是一个独立的模块上下文,在这个上下文中默认创建的属性都是私有的,对其他文件是不可见的。
    • CommonJS是同步加载的,在浏览器中会出现堵塞现场,不建议使用
    • AMD异步加载,需要定义回调define方式
    • es6一个模块就是一个独立文件,该文件内部的所有变量,外部无法获取。如果你需要外部能够读取模块的某个变量,就必须使用export关键字输出该变量es6还可以导出类,方法,自动使用严格模式。

    6、浏览器缓存

    浏览器缓存分为强缓存和协商缓存, 当客户端请求某个资源时,获取缓存的流程如下:

    • 先根据这些资源的http header判断是否强缓存,如果命中,直接从本地获取缓存资源,不会发出请求到服务器
    • 若没有命中强缓存,客户端会发生请求到服务器,服务器通过另一些request header验证这个资源是否命中协商缓存,称为http再验证,如果命中,服务器将请求返回,但不返回资源,而是告诉用户直接从缓存中获取,客户端收到返回后就会从缓存中获取资源
    • 两者的共同之处在于,如果命中缓存, 服务器都不会返回资源;区别是强缓存不会发请求到服务器,但协商缓存会
    • 当协商缓存也没命中时,服务器就会将资源发送回客户端
    • 当 ctrl+f5 强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存
    • 当 f5刷新网页时,跳过强缓存,但是会检查协商缓存

    强缓存

    • Expires:过期时间
    • Cache-contorl: max-age 缓存资源的最大生命周期(单位秒)

    协商缓存

    • Last-Modify:最后更新时间
    • If-Modified-Since:比较两个时间来判断资源在两次请求期间是否有过修改,如果没有修改,则命中协商缓存
    • Etag:资源内容唯一标识
    • If-None-Match:服务器通过比较请求头部的If-None-Match与当前资源的ETag是否一致来判断资源是否在两次请求之间有过修改,如果没有修改,则命中协商缓存

    7、重绘和回流

    重绘和回流会在我们设置节点样式时频繁出现,同时也会很大程度上影响性能。

    • 重绘:当节点需要更改外观而不会影响布局的,比如改变 color 就叫称为重绘
    • 回流:布局或者几何属性需要改变就称为回流

    注意⚠️:回流必造成重绘,重绘不一定造成回流。回流所需的成本比重绘高的多,改变父节点里的子节点很可能会导致父节点的一系列回流。

    以下几个动作可能会导致性能问题:

    • 改变window大小
    • 改变字体
    • 添加、删除样式
    • 文字改变
    • 定位or浮动
    • 盒模型

    重绘和回流其实也和 Eventloop 有关:

    • 当Eventloop执行完Microtasks后,会判断document是否需要更新,因为浏览器60HZ刷新频率,每16.6ms才会更新一次
    • 然后判断是否有resize、scroll事件,有的话会去触发事件,所以resize、scroll事件也是每16.6ms触发一次,并自带节流功能
    • 判断是否触发了media query
    • 更新动画并发送事件
    • 判断是否有全屏操作事件
    • 执行 requestAnimationFrame回调
    • 执行 IntersectionObserver 回调,该方法用于判断元素是否可见,可以用于懒加载上,但是兼容性不好更新界面
    • 以上就是一帧中可能会做的事情。如果在一帧中有空闲时间,就会去执行 requestIdleCallback回调

    如何减少重绘和回流:

    • 使用transform代替top
    • 使用visibility代替display: none ,前者重排后者回流
    • 不要把节点的属性值放在一个循环里当成循环的变量
    • 不要使用table布局,可能一个小改动都会造成table重新布局
    • 动画实现的速度越快,回流次数越多,也可以选择使用requestAnimationFrame
    • css选择符从右往左匹配,避免节点层级过多
    • 避免使用css表达式,因为每次调用都会重新计算值
    • 尽量使用css缩写,border代替border-border-width
    • 需要创建多个DOM节点时,使用DocumentFragment创建完后一次性的加入document

    8、首屏加载优化方案

    • Vue-Router路由懒加载(利用webpack的代码切割)
    • CDN加速,将通用的库vendor进行抽离
    • Nginx的Gzip压缩
    • Vue异步组件
    • 服务端SSR渲染
    • UI库可按需加载
    • Webpack开启gzip压缩
    • 如果首屏为登录页,可以做成多入口
    • 图片懒加载减少占用网络带宽
    • 利用好script标签的async和defer这两个属性。功能独立且不要求马上执行的js文件,可以加入async属性。如果是优先级低且没有依赖的js,可以加入defer属性。
  • 相关阅读:
    AIGC ChatGPT4对Gbase数据库进行总结
    笔试强训Day10
    js基础笔记学习279初步完成贪吃蛇运动2
    自动化测试 | 多个自动化测试用例?多个自动化测试数据怎么管理?资深测试总结
    Spring Boot与Netty:构建高性能的网络应用
    AM@闭区间上连续函数的性质定理@一致连续性
    Redis速学
    TCP协议详解
    到底什么是类脑计算?
    JUC并发编程 wait notify详解
  • 原文地址:https://blog.csdn.net/weixin_42224055/article/details/126170710