前端面试题-浏览器相关

news2024/12/21 16:45:48

1 cookie和localSrorage、session、indexDB 的区别

在这里插入图片描述

从上表可以看到, cookie 已经不建议⽤于存储。如果没有⼤量数据存储需求的话,可以使⽤ localStorage 和 sessionStorage 
。对于不怎么改变的数据尽量使⽤ localStorage 存储,否则可以⽤ sessionStorage 存储。

对于 cookie ,我们还需要注意安全性

在这里插入图片描述

2 怎么判断⻚⾯是否加载完成?

  • Load 事件触发代表⻚⾯中的 DOM , CSS , JS ,图⽚已经全部加载完毕。
  • DOMContentLoaded 事件触发代表初始的 HTML 被完全加载和解析,不需要等待CSS , JS ,图⽚加载

3 如何解决跨域

 因为浏览器出于安全考虑,有同源策略。也就是说,如果协议、域名或者端⼝有⼀个不同就是跨域, Ajax 请求会失败。

我们可以通过以下⼏种常⽤⽅法解决跨域的问题

JSONP
JSONP 的原理很简单,就是利⽤ <script> 标签没有跨域限制的漏洞。通过<script> 标签指向⼀个需要访问的地址并提供⼀个回调
函数来接收数据当需要通讯时
<script src="http://domain/api?param1=a&param2=b&callback=jsonp"></script>
<script>
function jsonp(data) {
console.log(data)
}
</script>
 JSONP 使⽤简单且兼容性不错,但是只限于 get 请求
  • 在开发中可能会遇到多个 JSONP 请求的回调函数名是相同的,这时候就需要⾃⼰封装⼀个 JSONP ,以下是简单实现
function jsonp(url, jsonpCallback, success) {
let script = document.createElement("script");
script.src = url;
script.async = true;
script.type = "text/javascript";
window[jsonpCallback] = function(data) {
success && success(data);
};
document.body.appendChild(script);
}
jsonp(
"http://xxx",
"callback",
function(value) {
console.log(value);
}
);
CORS
  • ORS 需要浏览器和后端同时⽀持。 IE 8 和 9 需要通过 XDomainRequest 来实现。
  • 浏览器会⾃动进⾏ CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了CORS ,就实现了跨域。
  • 服务端设置 Access-Control-Allow-Origin 就可以开启 CORS 。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有⽹站都可以访问资源。
document.domain
  • 该⽅式只能⽤于⼆级域名相同的情况下,⽐如 a.test.com 和 b.test.com 适⽤于该⽅式。
  • 只需要给⻚⾯添加 document.domain = ‘test.com’ 表示⼆级域名都相同就可以实现跨域
postMessage
这种⽅式通常⽤于获取嵌⼊⻚⾯中的第三⽅⻚⾯数据。⼀个⻚⾯发送消息,另⼀个⻚⾯判断来源并接收消息
// 发送消息端
window.parent.postMessage('message', 'http://test.com');
// 接收消息端
var mc = new MessageChannel();
mc.addEventListener('message', (event) => {
var origin = event.origin || event.originalEvent.origin;
if (origin === 'http://test.com') {
console.log('验证通过')
}
});

4 什么是事件代理

如果⼀个节点中的⼦节点是动态⽣成的,那么⼦节点需要注册事件的话应该注册在⽗节点上
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
let ul = document.querySelector('#ul')
ul.addEventListener('click', (event) => {
console.log(event.target);
})
</script>
  • 事件代理的⽅式相对于直接给⽬标注册事件来说,有以下优点
    • 节省内存
    • 不需要给⼦节点注销事件

5 Service worker

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

⽬前该技术通常⽤来做缓存⽂件,提⾼⾸屏速度,可以试着来实现这个功能

// index.js
if (navigator.serviceWorker) {
navigator.serviceWorker
.register("sw.js")
.then(function(registration) {
console.log("service worker 注册成功");
})
.catch(function(err) {
console.log("servcie worker 注册失败");
});
}
// sw.js
// 监听 `install` 事件,回调中缓存所需⽂件
self.addEventListener("install", e => {
e.waitUntil(
caches.open("my-cache").then(function(cache) {
return cache.addAll(["./index.html", "./index.js"]);
})
);
});
// 拦截所有请求事件
// 如果缓存中已经有请求的数据就直接⽤缓存,否则去请求数据
self.addEventListener("fetch", e => {
e.respondWith(
caches.match(e.request).then(function(response) {
if (response) {
return response;
}
console.log("fetch source");
})
);
});
打开⻚⾯,可以在开发者⼯具中的 Application 看到 Service Worker 已经启动了

6 浏览器缓存

缓存对于前端性能优化来说是个很重要的点,良好的缓存策略可以降低资源的重复加载提⾼⽹⻚的整体加载速度。
  • 通常浏览器缓存策略分为两种:强缓存和协商缓存。

强缓存

实现强缓存可以通过两种响应头实现: Expires 和 Cache-Control 。强缓存表示在缓存期间不需要请求, state code 为 200
Expires: Wed, 22 Oct 2018 08:41:00 GMT
Expires 是 HTTP / 1.0 的产物,表示资源会在 Wed , 22 Oct 2022 08:41:00 GMT 后过期,需要再次请求。并且 Expires 受
限于本地时间,如果修改了本地时间,可能会造成缓存失效。
  • Cache-control: max-age=30
  • Cache-Control 出现于 HTTP / 1.1 ,优先级⾼于 Expires 。该属性表示资源会在30 秒后过期,需要再次请求。

协商缓存

  • 如果缓存过期了,我们就可以使⽤协商缓存来解决问题。协商缓存需要请求,如果缓存有效会返回 304 。
  • 协商缓存需要客户端和服务端共同实现,和强缓存⼀样,也有两种实现⽅式

Last-Modified 和 If-Modified-Since

  • Last-Modified 表示本地⽂件最后修改⽇期, If-Modified-Since 会将 Last-Modified 的值发送给服务器,询问服务器在该⽇期后资源是否有更新,有更新的话就会将新的资源发送回来。
  • 但是如果在本地打开缓存⽂件,就会造成 Last-Modified 被修改,所以在 HTTP / 1.1出现了 ETag

ETag 和 If-None-Match

ETag 类似于⽂件指纹, If-None-Match 会将当前 ETag 发送给服务器,询问该资源 ETag 是否变动,有变动的话就将新的资源发
送回来。并且ETag 优先级⽐ Last-Modified ⾼

选择合适的缓存策略

对于⼤部分的场景都可以使⽤强缓存配合协商缓存解决,但是在⼀些特殊的地⽅可能需要选择特殊的缓存策略
  • 对于某些不需要缓存的资源,可以使⽤ Cache-control: no-store ,表示该资源不需要缓存
  • 对于频繁变动的资源,可以使⽤ Cache-Control: no-cache 并配合 ETag 使⽤,表示该资源已被缓存,但是每次都会发送请求询问资源是否更新。
  • 对于代码⽂件来说,通常使⽤ Cache-Control: max-age=31536000 并配合策略缓存使⽤,然后对⽂件进⾏指纹处理,⼀旦⽂件名变动就会⽴刻下载新的⽂件

7 浏览器性能问题

重绘(Repaint)和回流(Reflow)

  • 重绘和回流是渲染步骤中的⼀⼩节,但是这两个步骤对于性能影响很⼤。
  • 重绘是当节点需要更改外观⽽不会影响布局的,⽐如改变 color 就叫称为重绘
  • 回流是布局或者⼏何属性需要改变就称为回流。
  • 回流必定会发⽣重绘,重绘不⼀定会引发回流。回流所需的成本⽐重绘⾼的多,改变深层次的节点很可能导致⽗节点的⼀系列回流。

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

  • 改变 window ⼤⼩
  • 改变字体
  • 添加或删除样式
  • ⽂字改变
  • 定位或者浮动
  • 盒模型

很多⼈不知道的是,重绘和回流其实和 Event loop 有关。

  • 当 Event loop 执⾏完 Microtasks 后,会判断 document 是否需要更新。- 因为浏览器是 60Hz 的刷新率,每 16ms 才会更新⼀次。
  • 然后判断是否有 resize 或者 scroll ,有的话会去触发事件,所以 resize 和scroll 事件也是⾄少 16ms 才会触发⼀次,并且⾃带节流功能。
  • 判断是否触发了 media query
  • 更新动画并且发送事件
  • 判断是否有全屏操作事件
  • 执⾏ requestAnimationFrame 回调
  • 执⾏ IntersectionObserver 回调,该⽅法⽤于判断元素是否可⻅,可以⽤于懒加载上,但是兼容性不好
  • 更新界⾯
  • 以上就是⼀帧中可能会做的事情。如果在⼀帧中有空闲时间,就会去执⾏requestIdleCallback 回调。

减少重绘和回流

使⽤ translate 替代 top
<div class="test"></div>
<style>
.test {
position: absolute;
top: 10px;
width: 100px;
height: 100px;
background: red;
}
</style>
<script>
setTimeout(() => {
// 引起回流
document.querySelector('.test').style.top = '100px'
}, 1000)
</script>
  • 使⽤ visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局)

  • 把 DOM 离线后修改,⽐如:先把 DOM 给 display:none (有⼀次 Reflow ),然后你修改 100 次,然后再把它显示出来

  • 不要把 DOM 结点的属性值放在⼀个循环⾥当成循环⾥的变量

for(let i = 0; i < 1000; i++) {
// 获取 offsetTop 会导致回流,因为需要去获取正确的值
console.log(document.querySelector('.test').style.offsetTop)
}
  • 不要使⽤ table 布局,可能很⼩的⼀个⼩改动会造成整个 table 的重新布局 动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使⽤requestAnimationFrame
  • CSS 选择符从右往左匹配查找,避免 DOM 深度过深
  • 将频繁运⾏的动画变为图层,图层能够阻⽌该节点回流影响别的元素。⽐如对于 video标签,浏览器会⾃动将该节点变为图层。

CDN

静态资源尽量使⽤ CDN 加载,由于浏览器对于单个域名有并发请求上限,可以考虑使⽤多个 CDN 域名。对于 CDN 加载静态资源需要注意 CDN 域名要与主站不同,否则每次请求都会带上主站的 Cookie

使⽤ Webpack 优化项⽬

  • 对于 Webpack4 ,打包项⽬使⽤ production 模式,这样会⾃动开启代码压缩
  • 使⽤ ES6 模块来开启 tree shaking ,这个技术可以移除没有使⽤的代码
  • 优化图⽚,对于⼩图可以使⽤ base64 的⽅式写⼊⽂件中
  • 按照路由拆分代码,实现按需加载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/788565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java项目之人事管理系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的人事管理系统。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java 框架&…

【力扣每日一题】2023.7.24 宝石与石头

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给我们一个字符串表示宝石的类型&#xff0c;再给我们一个字符串表示我们已经拥有的石头&#xff0c;问我们在石头中能找到多少宝…

一文助你快速提高嵌入式软件的代码质量【下】

一文助你快速提高嵌入式软件的代码质量 文章目录 一文助你快速提高嵌入式软件的代码质量&#x1f468;‍&#x1f3eb;前言1️⃣写直观的代码2️⃣写无懈可击的代码3️⃣正确处理错误4️⃣正确处理null指针5️⃣防止过度工程&#x1f647;文末小结 &#x1f468;‍&#x1f3eb…

Python 快速简单搭建HTTP本地服务器,内网通过浏览器访问

1 下载python https://www.python.org/downloads/ 2 安装python&#xff0c;安装时候选择把path加入电脑环境变量 3 由于python内建了简单http服务包&#xff0c;因此对于python来说&#xff0c;只需输入一行命令&#xff0c;就能轻松打开http服务。当然&#xff0c;要运行网页…

C++之栈和堆申请内存(一百六十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

【复习16-18天】【我们一起60天准备考研算法面试(大全)-第二十四天 24/60】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

【复习42-44题】【每天40分钟,我们一起用50天刷完 (剑指Offer)】第三十四天 34/50

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

消息队列(一)-- RabbitMQ入门(1)

初识 RabbitMQ 核心思想&#xff1a;接收并转发消息。可以把它想象成一个邮局。 producer&#xff1a;生产者 queue&#xff1a;队列 consumer&#xff1a;消费者什么是消息队列 MQ&#xff08;Message Queue&#xff09;&#xff1a;本质是队列&#xff0c;FIFO先入先出&…

数字IC必学之《SKILL语法用户手册》建议收藏!

熟悉我的同学都知道&#xff0c;一直以来&#xff0c;我都会为大家分享IC各个岗位的学习资料。前端、后端、验证、版图等等&#xff0c;为大家分享了很多。当然也有一些IC入行需要学习的一些语言资料。去年在各个平台更新了一篇关于SKILL的资料&#xff1a; 《Skill入门教程》…

常用API学习07(Java)

Date 在jdk1.8之前,java中的日期和时间是一类的&#xff0c;从1.8之后对日期和时间体系重新做了规划&#xff0c;划分出一个新的包 - java.time包&#xff0c;这个包中包含了日期、时间、时区、日历、单位。 Date&#xff0c;是java中最老的日期和时间类&#xff0c;后续退出…

(原创)Flutter与Native通信的方式:EventChannel和BasicMessageChannel

前言 上一篇博客主要介绍了MethodChannel的使用方式 Flutter与Native通信的方式&#xff1a;MethodChannel 这篇博客接着讲另外两种通信方式 EventChannel和BasicMessageChannel EventChannel用于从native向flutter发送通知事件&#xff0c;例如flutter通过其监听Android的重…

视频文件批量添加字幕内容需要如何快速操作

有时候我们在剪辑视频的过程中&#xff0c;想要给视频素材添加上一些文字说明&#xff0c;需要如何操作呢&#xff1f;为了提高剪辑效率&#xff0c;今天小编来分享教学&#xff0c;教你如何才能批量地给视频素材添加滚动字幕&#xff0c;一起来看看具体的方法介绍吧。 我们先打…

【C++】-模板进阶(让你更好的使用模板创建无限可能)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

删除主表 子表外键没有索引的性能优化

整个表147M&#xff0c;执行时一个CPU耗尽&#xff0c; buffer gets 超过1个G&#xff0c; 启用并行也没有用 今天开发的同事问有个表上的数据为什么删不掉&#xff1f;我看了一下&#xff0c;也就不到100000条数据&#xff0c;表上有外键&#xff0c;等了5分钟hang在那里&…

固态硬盘种类

有三个层次&#xff0c;同一个词可能有多层意思&#xff0c;要注意区分。 一、接口 也叫插槽&#xff0c;插口。就是连接设备的地方。 能够插固态硬盘的插槽有&#xff1a;sata插槽&#xff0c;pcie插槽&#xff0c;m.2插槽&#xff0c;u.2插槽 &#xff08;一&#xff09;sat…

模拟量输出FC S_RTI(信捷C语言源代码)

模拟量输出FC SCL源代码请查看下面博客: PLC模拟量输出 模拟量转换FC S_RTI_博途模拟量转换指令_RXXW_Dor的博客-CSDN博客1、本文主要展示西门子博途模拟量输出转换的几种方法, 方法1:先展示下自编FC:计算公式如下:intput intput Real ISH Real //工程量上限 ISL Real //工…

Java中的equals方法详解:比较方法

1、equals方法的背景 在Java中&#xff0c;equals方法是Object类的一个方法&#xff0c;用于比较两个对象是否相等。 Java中有两种比较对象的方法&#xff1a;运算符和equals方法。 运算符用于比较两个对象的引用&#xff0c;如果它们指向的是同一个对象&#xff0c;则返回t…

继承-菱形继承

继承 继承是类设计层次的复用 继承方式与访问限定符 限定了啥&#xff1f; 1.根据表中我们可以看到 基类的私有成员在子类不可见&#xff0c;但还是被继承了下来 2.根据继承方式和成员在基类的访问限定符小的那个来决定了子类访问基类成员的访问方式 例如如果是public继承&a…

甄云库存管理解决方案 ,助力企业库存高效运转起来

导语 近年来&#xff0c;在降低成本、提高工作效率和满足用户需求等多重压力下&#xff0c;许多企业也开始重视非生产物资的库存管理&#xff0c;如办公设备、劳保用品、电子设备、维修工具、实验耗材。这些物资往往品类繁多、采购频率较高&#xff0c;占用了企业大量的管理时…

quartus工具篇——PLL IP核的使用

quartus工具篇——PLL IP核的使用 1、PLL简介 PLL(Phase-Locked Loop,相位锁环)是FPGA中非常重要的时钟管理单元,其主要功能包括: 频率合成 - PLL可以生成比输入时钟频率高的时钟信号。频率分频 - PLL也可以输出分频后的较低频率时钟。减小时钟抖动 - PLL可以过滤输入时钟中…