[{"data":1,"prerenderedAt":1190},["ShallowReactive",2],{"doc-\u002Fdocs\u002Finterview-browser-network":3,"docs-all":1089},{"id":4,"title":5,"body":6,"category":1071,"date":1072,"description":1073,"draft":1074,"extension":1075,"meta":1076,"navigation":1077,"path":1078,"seo":1079,"source":1080,"stem":1081,"tags":1082,"__hash__":1088},"docs\u002Fdocs\u002Finterview-browser-network.md","浏览器与网络考点",{"type":7,"value":8,"toc":1031},"minimark",[9,14,18,21,37,40,43,53,56,66,72,76,86,89,108,126,164,171,177,181,184,195,198,205,208,211,214,217,221,224,227,232,235,238,241,244,251,262,265,271,274,277,281,296,300,303,313,328,331,392,404,407,421,435,438,441,444,448,473,476,489,495,501,512,523,529,532,535,539,542,549,576,579,709,715,719,738,744,767,771,774,777,823,830,842,846,853,873,876,879,885,909,912,915,918,921,924,954,961,964,991,1009,1012,1017,1021,1028],[10,11,13],"h2",{"id":12},"输入-url-到页面加载的全过程","输入 URL 到页面加载的全过程",[15,16,17],"p",{},"这是面试最高频的一道题，完整链路如下。",[15,19,20],{},"浏览器先通过 DNS 解析把域名转换为 IP 地址，然后与服务器进行三次握手建立 TCP 连接。连接建立后发送 HTTP 请求，服务器处理请求并返回响应（其间可能有永久重定向，浏览器需跟踪重定向地址）。浏览器拿到响应后解析 HTML、CSS、JS 并渲染页面，最后四次挥手断开连接。",[15,22,23,27,28,32,33,36],{},[24,25,26],"strong",{},"三次握手","的过程：客户端主动发起请求，发送 SYN 并将自身状态置为 SYN-SENT，携带 ",[29,30,31],"code",{},"seq=x","；服务端收到后返回 ",[29,34,35],{},"seq=y","，状态变为 SYN-RCVD；客户端收到返回值后进入 ESTABLISHED 状态，连接完成。",[10,38,39],{"id":39},"浏览器渲染流程",[15,41,42],{},"浏览器渲染页面时依次做这几件事：加载 HTML 和 CSS 源码，把 HTML 转换为 DOM、CSS 转换为 CSSOM，将两者构建成渲染树，对渲染树执行回流计算元素位置，最后绘制页面。",[15,44,45,48,49,52],{},[24,46,47],{},"渲染树","从根元素开始检查哪些元素可见及其样式，会忽略 ",[29,50,51],{},"display: none"," 的不可见元素。",[10,54,55],{"id":55},"回流与重绘",[15,57,58,61,62,65],{},[24,59,60],{},"回流","（reflow，也叫重排）是指页面结构或元素尺寸发生变化时，浏览器需要重新计算元素的大小和位置并重新渲染。",[24,63,64],{},"重绘","（repaint）是指元素外观（如字体颜色、背景色）改变时浏览器重新绘制。",[15,67,68,71],{},[24,69,70],{},"回流一定会引起重绘，重绘不一定引起回流。"," 回流是非常昂贵的操作，次数过多会显著拖慢页面性能。",[73,74,75],"h3",{"id":75},"哪些操作会触发",[15,77,78,79,81,82,85],{},"任何改变渲染树构建信息的操作都会导致回流或重绘：添加、删除、更新 DOM 节点；用 ",[29,80,51],{}," 隐藏节点会同时触发回流和重绘；用 ",[29,83,84],{},"visibility: hidden"," 隐藏只触发重绘，因为没有几何变化；移动元素或添加动画；添加样式表、调整样式属性；用户行为如调整窗口大小、改变字号、滚动页面。",[73,87,88],{"id":88},"如何避免",[15,90,91,92,95,96,99,100,103,104,107],{},"集中修改样式，不要一条一条地改 DOM 样式，可以通过切换 ",[29,93,94],{},"class"," 或使用 ",[29,97,98],{},"style.cssText"," 批量操作。不要把 DOM 节点的属性值放在循环里当变量。为动画元素使用 ",[29,101,102],{},"position: fixed"," 或 ",[29,105,106],{},"absolute","，修改它们的 CSS 不会引起整体回流。不使用 table 布局，因为很小的改动就可能造成整个 table 重新布局。",[15,109,110,111,114,115,117,118,121,122,125],{},"动画开启 GPU 加速，",[29,112,113],{},"transform"," 使用 3D 变化。将元素提升为合成层——合成层的位图交由 GPU 合成比 CPU 快，需要 repaint 时只影响自身不波及其他层，且 ",[29,116,113],{}," 和 ",[29,119,120],{},"opacity"," 效果不会触发 layout 和 paint。提升合成层的最佳方式是 ",[29,123,124],{},"will-change","：",[127,128,133],"pre",{"className":129,"code":130,"language":131,"meta":132,"style":132},"language-css shiki shiki-themes github-light github-dark","#target {\n  will-change: transform;\n}\n","css","",[29,134,135,148,158],{"__ignoreMap":132},[136,137,140,144],"span",{"class":138,"line":139},"line",1,[136,141,143],{"class":142},"sScJk","#target",[136,145,147],{"class":146},"sVt8B"," {\n",[136,149,151,155],{"class":138,"line":150},2,[136,152,154],{"class":153},"sj4cs","  will-change",[136,156,157],{"class":146},": transform;\n",[136,159,161],{"class":138,"line":160},3,[136,162,163],{"class":146},"}\n",[15,165,166,167,170],{},"另外可以缓存 DOM 查询结果，减少 DOM 深度和数量，批量操作时先拼接字符串再用 ",[29,168,169],{},"innerHTML"," 一次性更新，配合防抖节流限制高频触发，并及时清理定时器与事件监听。",[172,173,174],"blockquote",{},[15,175,176],{},"在 Vue、React 这类现代框架中，这些优化大多已由框架处理，开发时唯一需要注意的是尽量减少直接操作 DOM。",[10,178,180],{"id":179},"http-协议","HTTP 协议",[73,182,183],{"id":183},"主要特点",[15,185,186,187,190,191,194],{},"简单快捷、灵活、",[24,188,189],{},"无连接","（连接一次就断开，不保持连接）、",[24,192,193],{},"无状态","（第一次请求结束后断开，第二次请求时服务端不记得之前的状态）。",[73,196,197],{"id":197},"报文结构",[15,199,200,201,204],{},"请求报文由请求行、请求头、空行、请求体四部分组成。请求行包括请求方法、URL、HTTP 协议及版本；请求头是一堆键值对；",[24,202,203],{},"空行","的作用是告诉服务器后面的内容是请求体；请求体是数据部分。",[15,206,207],{},"响应报文由状态行、响应头、空行、响应体组成。状态行包括 HTTP 协议及版本、状态码及状态描述。",[73,209,210],{"id":210},"请求方法",[15,212,213],{},"HTTP 1.0 定义了 GET、POST、HEAD 三种方法，HTTP 1.1 新增了 OPTIONS、PUT、PATCH、DELETE、TRACE、CONNECT 六种。",[15,215,216],{},"常用方法的语义：GET 获取资源，POST 传输资源，PUT 更新资源，DELETE 删除资源，HEAD 获取报文首部。",[73,218,220],{"id":219},"get-与-post-的区别","GET 与 POST 的区别",[15,222,223],{},"GET 把参数拼在 URL 中传递，数据量小且不安全，参数会保留在浏览器历史记录中，会被浏览器主动缓存，浏览器回退时不会重新请求。",[15,225,226],{},"POST 把参数放在请求体中，携带数据量大，相对安全，不会被主动缓存，回退时会重新请求。",[15,228,229],{},[24,230,231],{},"提交敏感数据（如登录密码）或上传文件时必须用 POST。",[73,233,234],{"id":234},"状态码",[15,236,237],{},"按首位数字分五类：1xx 表示服务器已收到请求需要请求者继续操作；2xx 成功；3xx 重定向，需要进一步操作；4xx 客户端错误；5xx 服务器错误。",[15,239,240],{},"常见的具体状态码：200 请求成功，301 页面已永久转移到新 URL，400 客户端请求语法错误，401 请求未经授权，403 页面访问被禁止，404 资源不存在，500 服务器错误，503 服务器宕机请求未完成。",[73,242,243],{"id":243},"持久连接",[15,245,246,247,250],{},"HTTP 1.0 时代靠",[24,248,249],{},"轮询","——客户端每隔很短时间就发起请求查看是否有新消息，对服务器和客户端都造成大量性能浪费。",[15,252,253,254,257,258,261],{},"HTTP 1.1 通过 ",[29,255,256],{},"Connection: keep-alive"," 实现",[24,259,260],{},"长连接","，客户端只请求一次，服务器保持连接。默认仍是请求一次响应一次，开启管线化后可以把请求打包一次性发送、一次性响应。",[10,263,264],{"id":264},"同源策略与跨域",[15,266,267,270],{},[24,268,269],{},"同源","要求协议、域名、端口号完全相同，任何一部分不同就是跨域。",[15,272,273],{},"同源策略限制一个源的文档操作另一个源的资源，具体体现在：无法获取对方的 Cookie、LocalStorage 和 IndexedDB；无法获取和操作 DOM；不能发送 Ajax 请求。",[15,275,276],{},"前后端通信的三种方式中，Ajax 不支持跨域，WebSocket 不受同源策略限制天然支持跨域，CORS 则同时支持同源和跨域 Ajax。",[73,278,280],{"id":279},"发送-ajax-请求的步骤","发送 Ajax 请求的步骤",[15,282,283,284,287,288,291,292,295],{},"创建 ",[29,285,286],{},"XMLHttpRequest"," 对象，用 ",[29,289,290],{},"open(method, url, async)"," 设置请求参数，发送请求，注册 ",[29,293,294],{},"onreadystatechange"," 事件，最后获取返回数据。",[10,297,299],{"id":298},"dom-事件","DOM 事件",[73,301,302],{"id":302},"事件流三阶段",[15,304,305,306,309,310,312],{},"事件传递依次经过捕获阶段（从 ",[29,307,308],{},"window"," 向目标元素传递）、目标阶段、冒泡阶段（从目标元素向 ",[29,311,308],{}," 传递）。",[15,314,315,316,319,320,323,324,327],{},"捕获的流程是 ",[29,317,318],{},"window → document → html → body → 目标元素","。获取 body 节点用 ",[29,321,322],{},"document.body","，获取 html 节点用 ",[29,325,326],{},"document.documentElement","。",[73,329,330],{"id":330},"事件绑定写法",[127,332,336],{"className":333,"code":334,"language":335,"meta":132,"style":132},"language-js shiki shiki-themes github-light github-dark","element.onclick = function () {}                              \u002F\u002F DOM0\nelement.addEventListener('click', function () {}, false)      \u002F\u002F DOM2\n","js",[29,337,338,360],{"__ignoreMap":132},[136,339,340,343,346,350,353,356],{"class":138,"line":139},[136,341,342],{"class":146},"element.",[136,344,345],{"class":142},"onclick",[136,347,349],{"class":348},"szBVR"," =",[136,351,352],{"class":348}," function",[136,354,355],{"class":146}," () {}                              ",[136,357,359],{"class":358},"sJ8bj","\u002F\u002F DOM0\n",[136,361,362,364,367,370,374,377,380,383,386,389],{"class":138,"line":150},[136,363,342],{"class":146},[136,365,366],{"class":142},"addEventListener",[136,368,369],{"class":146},"(",[136,371,373],{"class":372},"sZZnC","'click'",[136,375,376],{"class":146},", ",[136,378,379],{"class":348},"function",[136,381,382],{"class":146}," () {}, ",[136,384,385],{"class":153},"false",[136,387,388],{"class":146},")      ",[136,390,391],{"class":358},"\u002F\u002F DOM2\n",[15,393,394,395,398,399,401,402,327],{},"第三个参数 ",[29,396,397],{},"true"," 表示在捕获阶段触发，",[29,400,385],{}," 表示在冒泡阶段触发，默认 ",[29,403,385],{},[73,405,406],{"id":406},"事件控制",[15,408,409,410,413,414,417,418,327],{},"阻止默认行为用 ",[29,411,412],{},"event.preventDefault()","，阻止冒泡用 ",[29,415,416],{},"event.stopPropagation()","，阻止同元素上其他监听器执行用 ",[29,419,420],{},"event.stopImmediatePropagation()",[15,422,423,426,427,430,431,434],{},[24,424,425],{},"事件委托","中要区分两个属性：",[29,428,429],{},"event.currentTarget"," 是当前绑定事件的元素（父元素），",[29,432,433],{},"event.target"," 是实际被点击的元素（子元素）。",[10,436,437],{"id":437},"浏览器内核",[15,439,440],{},"IE 用 Trident 内核（三叉戟），Chrome 现在用 Blink（早期是 Webkit），Firefox 用 Gecko（壁虎），Safari 用 Webkit，Opera 最初是自研的 Presto，后改用 Webkit，现在也是 Blink。",[15,442,443],{},"内核分渲染引擎和 JS 引擎两部分。Webkit 是苹果公司的，Blink 是 Webkit 的分支。",[10,445,447],{"id":446},"bom-对象","BOM 对象",[15,449,450,452,453,456,457,460,461,464,465,468,469,472],{},[29,451,308],{}," 是 JS 最顶层对象，其他 BOM 对象都是它的属性。",[29,454,455],{},"document"," 是文档对象，",[29,458,459],{},"location"," 保存当前 URL 信息，",[29,462,463],{},"navigator"," 是浏览器本身信息，",[29,466,467],{},"screen"," 是客户端屏幕信息，",[29,470,471],{},"history"," 是访问历史。",[10,474,475],{"id":475},"客户端存储对比",[15,477,478,481,482,481,485,488],{},[29,479,480],{},"cookie","、",[29,483,484],{},"sessionStorage",[29,486,487],{},"localStorage"," 的差异主要在四个维度。",[15,490,491,494],{},[24,492,493],{},"是否随请求发送","：cookie 始终在同源 HTTP 请求中携带（即使不需要），在浏览器和服务器间来回传递；webStorage 不会。",[15,496,497,500],{},[24,498,499],{},"存储大小","：cookie 不超过 4KB，因此只适合存会话标识这类很小的数据；webStorage 可达 5MB 或更大。",[15,502,503,125,506,508,509,511],{},[24,504,505],{},"有效期",[29,507,484],{}," 仅在当前浏览器窗口关闭前有效；",[29,510,487],{}," 始终有效，窗口或浏览器关闭也保留，适合持久数据；cookie 在设置的过期时间之前有效，与窗口关闭无关。",[15,513,514,125,517,519,520,522],{},[24,515,516],{},"作用域",[29,518,484],{}," 不在不同窗口间共享，即使是同一个页面；",[29,521,487],{}," 和 cookie 在所有同源窗口中共享。",[15,524,525,526,327],{},"另外 cookie 与 session 的区别在于：cookie 保存在浏览器端，session 保存在服务器端；cookie 单个不超过 4KB，session 大小无限制；cookie 只能保存字符串，session 可以保存任意类型对象；",[24,527,528],{},"session 的安全性高于 cookie",[10,530,531],{"id":531},"网站攻击方式",[15,533,534],{},"常见的有 XSS（跨站脚本攻击）和 CSRF（跨站请求伪造）。",[73,536,538],{"id":537},"csrf-原理","CSRF 原理",[15,540,541],{},"攻击者诱导受害者进入第三方网站，在该网站中向被攻击网站发送跨站请求，利用受害者已获取的登录凭证绕过后台验证，冒充用户执行操作。",[15,543,544,545,548],{},"自动发起 GET 请求的形式，把支付接口藏在 ",[29,546,547],{},"img"," 标签里，浏览器加载图片时自动发起带登录信息的跨域请求：",[127,550,554],{"className":551,"code":552,"language":553,"meta":132,"style":132},"language-html shiki shiki-themes github-light github-dark","\u003Cimg src=\"http:\u002F\u002Fxxx.com\u002Fpay?amount=100000&for=hacker\">\n","html",[29,555,556],{"__ignoreMap":132},[136,557,558,561,564,567,570,573],{"class":138,"line":139},[136,559,560],{"class":146},"\u003C",[136,562,547],{"class":563},"s9eBZ",[136,565,566],{"class":142}," src",[136,568,569],{"class":146},"=",[136,571,572],{"class":372},"\"http:\u002F\u002Fxxx.com\u002Fpay?amount=100000&for=hacker\"",[136,574,575],{"class":146},">\n",[15,577,578],{},"自动发起 POST 请求的形式，用表单自动提交模拟用户操作：",[127,580,582],{"className":551,"code":581,"language":553,"meta":132,"style":132},"\u003Cform action=\"http:\u002F\u002Fa.com\u002Fpay\" method=\"POST\">\n  \u003Cinput type=\"hidden\" name=\"amount\" value=\"10000\" \u002F>\n  \u003Cinput type=\"hidden\" name=\"for\" value=\"hacker\" \u002F>\n\u003C\u002Fform>\n\u003Cscript>document.forms[0].submit()\u003C\u002Fscript>\n",[29,583,584,609,644,672,682],{"__ignoreMap":132},[136,585,586,588,591,594,596,599,602,604,607],{"class":138,"line":139},[136,587,560],{"class":146},[136,589,590],{"class":563},"form",[136,592,593],{"class":142}," action",[136,595,569],{"class":146},[136,597,598],{"class":372},"\"http:\u002F\u002Fa.com\u002Fpay\"",[136,600,601],{"class":142}," method",[136,603,569],{"class":146},[136,605,606],{"class":372},"\"POST\"",[136,608,575],{"class":146},[136,610,611,614,617,620,622,625,628,630,633,636,638,641],{"class":138,"line":150},[136,612,613],{"class":146},"  \u003C",[136,615,616],{"class":563},"input",[136,618,619],{"class":142}," type",[136,621,569],{"class":146},[136,623,624],{"class":372},"\"hidden\"",[136,626,627],{"class":142}," name",[136,629,569],{"class":146},[136,631,632],{"class":372},"\"amount\"",[136,634,635],{"class":142}," value",[136,637,569],{"class":146},[136,639,640],{"class":372},"\"10000\"",[136,642,643],{"class":146}," \u002F>\n",[136,645,646,648,650,652,654,656,658,660,663,665,667,670],{"class":138,"line":160},[136,647,613],{"class":146},[136,649,616],{"class":563},[136,651,619],{"class":142},[136,653,569],{"class":146},[136,655,624],{"class":372},[136,657,627],{"class":142},[136,659,569],{"class":146},[136,661,662],{"class":372},"\"for\"",[136,664,635],{"class":142},[136,666,569],{"class":146},[136,668,669],{"class":372},"\"hacker\"",[136,671,643],{"class":146},[136,673,675,678,680],{"class":138,"line":674},4,[136,676,677],{"class":146},"\u003C\u002F",[136,679,590],{"class":563},[136,681,575],{"class":146},[136,683,685,687,690,693,696,699,702,705,707],{"class":138,"line":684},5,[136,686,560],{"class":146},[136,688,689],{"class":563},"script",[136,691,692],{"class":146},">document.forms[",[136,694,695],{"class":153},"0",[136,697,698],{"class":146},"].",[136,700,701],{"class":142},"submit",[136,703,704],{"class":146},"()\u003C\u002F",[136,706,689],{"class":563},[136,708,575],{"class":146},[15,710,711,714],{},[24,712,713],{},"CSRF 成立需要三个条件同时满足","：目标站点存在 CSRF 漏洞；用户登录过目标站点且浏览器保持登录状态；用户打开了第三方站点。",[73,716,718],{"id":717},"csrf-防护","CSRF 防护",[15,720,721,724,725,728,729,732,733,735,736,327],{},[24,722,723],{},"利用同源策略","直接禁止外域请求。HTTP 异步请求会携带两个标记来源的 Header：",[29,726,727],{},"Referer"," 记录来源地址（含 URL 路径），",[29,730,731],{},"Origin"," 记录域名信息（不含路径）。服务器先判断 ",[29,734,731],{},"，若请求头中没有则根据实际情况判断是否使用 ",[29,737,727],{},[15,739,740,743],{},[24,741,742],{},"Token 验证","。用户登录后服务器生成 Token 返回，浏览器发起请求时带上，服务端校验。",[15,745,746,327,749,752,753,756,757,481,759,762,763,766],{},[24,747,748],{},"利用 Cookie 的 SameSite 属性",[29,750,751],{},"Strict"," 完全禁止第三方拿到 Cookie；",[29,754,755],{},"Lax"," 相对宽松，跨站点时第三方链接打开或 GET 表单提交会携带 Cookie，但 POST 请求、",[29,758,547],{},[29,760,761],{},"iframe"," 加载的 URL 不会；",[29,764,765],{},"None"," 任何情况下都发送。",[10,768,770],{"id":769},"bfc","BFC",[15,772,773],{},"BFC 是 Block Formatting Context（块级格式化上下文），它决定了元素如何对其内容定位，是一个完全独立的布局空间，内部子元素不会影响外部布局。",[15,775,776],{},"触发 BFC 的 CSS 属性：",[127,778,780],{"className":129,"code":779,"language":131,"meta":132,"style":132},"overflow: hidden;\ndisplay: inline-block;\ndisplay: flex;\ndisplay: table-cell;\nposition: absolute;\nposition: fixed;\n",[29,781,782,787,798,803,812,817],{"__ignoreMap":132},[136,783,784],{"class":138,"line":139},[136,785,786],{"class":146},"overflow: hidden;\n",[136,788,789,792,795],{"class":138,"line":150},[136,790,791],{"class":146},"display: ",[136,793,794],{"class":563},"inline-block",[136,796,797],{"class":146},";\n",[136,799,800],{"class":138,"line":160},[136,801,802],{"class":146},"display: flex;\n",[136,804,805,807,810],{"class":138,"line":674},[136,806,791],{"class":146},[136,808,809],{"class":563},"table-cell",[136,811,797],{"class":146},[136,813,814],{"class":138,"line":684},[136,815,816],{"class":146},"position: absolute;\n",[136,818,820],{"class":138,"line":819},6,[136,821,822],{"class":146},"position: fixed;\n",[15,824,825,826,829],{},"BFC 的规则是块级元素在垂直方向依次排列；容器内的元素不影响外部；垂直距离由 ",[29,827,828],{},"margin"," 决定，同一 BFC 内相邻元素的外边距会重叠；计算 BFC 高度时浮动元素也参与计算。",[15,831,832,125,835,838,839,841],{},[24,833,834],{},"BFC 主要解决两个问题",[29,836,837],{},"float"," 脱离文档流导致的高度塌陷，以及 ",[29,840,828],{}," 边距重叠。",[10,843,845],{"id":844},"viewport-视口","Viewport 视口",[15,847,848,849,852],{},"PC 端的 viewport 就等于浏览器窗口，通过 ",[29,850,851],{},"document.documentElement.clientWidth"," 获取。",[15,854,855,856,859,860,852,862,865,866,869,870,852],{},"移动端要区分三种视口。",[24,857,858],{},"布局视口","远大于设备屏幕（为了让 PC 端设计的网站能完整显示），因此会出现滚动条，用 ",[29,861,851],{},[24,863,864],{},"视觉视口","指浏览器可视区域的宽度。",[24,867,868],{},"理想视口","是布局视口的理想尺寸，只有当布局视口等于设备屏幕尺寸时才是理想视口，用 ",[29,871,872],{},"window.screen.width",[10,874,875],{"id":875},"性能优化",[73,877,878],{"id":878},"减少请求数量",[15,880,881,882,327],{},"文件合并、公共库合并、不同页面单独合并；用字体图标代替图片，小图以 Base64 内嵌到 HTML，优先用 SVG；减少重定向；使用缓存；不使用 ",[29,883,884],{},"CSS @import",[15,886,887,888,117,891,894,895,898,899,901,902,904,905,908],{},"避免空的 ",[29,889,890],{},"src",[29,892,893],{},"href","——",[29,896,897],{},"a"," 标签设置空 ",[29,900,893],{}," 会重定向到当前页面地址，",[29,903,590],{}," 设置空 ",[29,906,907],{},"action"," 会提交表单到当前页面。",[73,910,911],{"id":911},"减小资源体积",[15,913,914],{},"HTML 压缩去掉空格制表符换行符；CSS 压缩删除无效代码并做语义合并；JS 压缩混淆，删除无效字符和注释、缩减代码语义，同时降低可读性起到代码保护作用。",[15,916,917],{},"安卓下可用 WebP 格式图片，压缩算法更优体积更小。开启 gzip 编码可显著改善传输性能。",[73,919,920],{"id":920},"优化网络连接",[15,922,923],{},"使用 CDN 就近获取资源。使用 DNS 预解析提前解析后续可能用到的域名，把结果缓存到系统缓存中：",[127,925,927],{"className":551,"code":926,"language":553,"meta":132,"style":132},"\u003Clink rel=\"dns-prefetch\" href=\"https:\u002F\u002Fwww.google.com\">\n",[29,928,929],{"__ignoreMap":132},[136,930,931,933,936,939,941,944,947,949,952],{"class":138,"line":139},[136,932,560],{"class":146},[136,934,935],{"class":563},"link",[136,937,938],{"class":142}," rel",[136,940,569],{"class":146},[136,942,943],{"class":372},"\"dns-prefetch\"",[136,945,946],{"class":142}," href",[136,948,569],{"class":146},[136,950,951],{"class":372},"\"https:\u002F\u002Fwww.google.com\"",[136,953,575],{"class":146},[15,955,956,957,960],{},"用 ",[29,958,959],{},"keep-alive"," 建立持久连接；HTTP 2 中开启管道化连接，每条连接并发传输多个资源。",[73,962,963],{"id":963},"优化资源加载",[15,965,966,967,970,971,974,975,978,979,981,982,984,985,117,988,990],{},"CSS 文件放在 ",[29,968,969],{},"head"," 中，先外链后本页；JS 文件放在 ",[29,972,973],{},"body"," 底部；处理页面布局的 JS（如 ",[29,976,977],{},"flexible.js","）放在 ",[29,980,969],{}," 中；",[29,983,973],{}," 中间尽量不写 ",[29,986,987],{},"style",[29,989,689],{}," 标签。",[15,992,993,996,997,1000,1001,1004,1005,1008],{},[29,994,995],{},"defer"," 异步加载并在 HTML 解析完成后执行，",[29,998,999],{},"async"," 异步加载且加载完立即执行。",[29,1002,1003],{},"preload"," 让浏览器提前加载指定资源加速本页面，",[29,1006,1007],{},"prefetch"," 加载下一页面可能用到的资源加速后续导航。",[15,1010,1011],{},"配合资源懒加载（满足条件时才加载）和预加载（提前加载用户所需资源）平衡首屏速度与体验。",[172,1013,1014],{},[15,1015,1016],{},"Cookie 会随每个同域请求发送到服务器，影响加载速度，应尽量减少不必要的 Cookie。",[10,1018,1020],{"id":1019},"cdn","CDN",[15,1022,1023,1024,1027],{},"构建在现有网络基础之上的智能虚拟网络，依靠部署在各地的服务器",[24,1025,1026],{},"使用户就近获取所需内容","，降低网络拥塞，提高访问速度和命中率。",[987,1029,1030],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":132,"searchDepth":160,"depth":160,"links":1032},[1033,1034,1035,1039,1047,1050,1055,1056,1057,1058,1062,1063,1064,1070],{"id":12,"depth":150,"text":13},{"id":39,"depth":150,"text":39},{"id":55,"depth":150,"text":55,"children":1036},[1037,1038],{"id":75,"depth":160,"text":75},{"id":88,"depth":160,"text":88},{"id":179,"depth":150,"text":180,"children":1040},[1041,1042,1043,1044,1045,1046],{"id":183,"depth":160,"text":183},{"id":197,"depth":160,"text":197},{"id":210,"depth":160,"text":210},{"id":219,"depth":160,"text":220},{"id":234,"depth":160,"text":234},{"id":243,"depth":160,"text":243},{"id":264,"depth":150,"text":264,"children":1048},[1049],{"id":279,"depth":160,"text":280},{"id":298,"depth":150,"text":299,"children":1051},[1052,1053,1054],{"id":302,"depth":160,"text":302},{"id":330,"depth":160,"text":330},{"id":406,"depth":160,"text":406},{"id":437,"depth":150,"text":437},{"id":446,"depth":150,"text":447},{"id":475,"depth":150,"text":475},{"id":531,"depth":150,"text":531,"children":1059},[1060,1061],{"id":537,"depth":160,"text":538},{"id":717,"depth":160,"text":718},{"id":769,"depth":150,"text":770},{"id":844,"depth":150,"text":845},{"id":875,"depth":150,"text":875,"children":1065},[1066,1067,1068,1069],{"id":878,"depth":160,"text":878},{"id":911,"depth":160,"text":911},{"id":920,"depth":160,"text":920},{"id":963,"depth":160,"text":963},{"id":1019,"depth":150,"text":1020},"interview","2024-11-03","从输入 URL 到页面呈现的完整链路，涵盖渲染流程、回流重绘、HTTP 报文与状态码、跨域同源策略与常见攻击方式。",false,"md",{},true,"\u002Fdocs\u002Finterview-browser-network",{"title":5,"description":1073},null,"docs\u002Finterview-browser-network",[1083,1084,1085,1086,1087],"browser","http","network","performance","notes","xEmoZabFk_K9ee1oXWDEXTVUcDBPsEfHvm8NAAqLFxc",[1090,1101,1110,1116,1125,1131,1133,1138,1146,1151,1158,1164,1171,1178,1184],{"path":1091,"title":1092,"description":1093,"date":1094,"category":1095,"tags":1096},"\u002Fdocs\u002Ffrontend-coding-standards","前端团队编码规范","HTML \u002F CSS \u002F JavaScript 三端统一的团队编码约定，含缩进、命名、语法与禁用项，可直接作为 Code Review 依据。","2025-12-17","standards",[553,131,1097,1098,1099,1100],"javascript","es6","best-practice","guide",{"path":1102,"title":1103,"description":1104,"date":1105,"category":1106,"tags":1107},"\u002Fdocs\u002Fwindows-mklink","Windows mklink 符号链接用法","mklink 各参数区别与实用场景：目录联接、符号链接与硬链接的选择。","2024-12-18","toolchain",[1108,1109],"windows","cheatsheet",{"path":1111,"title":1112,"description":1113,"date":1114,"category":1106,"tags":1115},"\u002Fdocs\u002Frandom-color-utils","JS 随机颜色生成方法","几种生成随机 RGB \u002F HEX 颜色的实现方式与各自适用场景。","2024-12-11",[1097,1109],{"path":1117,"title":1118,"description":1119,"date":1120,"category":1121,"tags":1122},"\u002Fdocs\u002Fcanvas-vs-svg","Canvas 与 SVG 绘图方案选型","对比 Canvas 与 SVG 两种绘图方案的优缺点与适用场景，给出选型判断依据。","2024-12-09","visualization",[1123,1124,1086,1099],"canvas","svg",{"path":1126,"title":1127,"description":1128,"date":1072,"category":1106,"tags":1129},"\u002Fdocs\u002Ffree-commercial-fonts","免费可商用字体整理","整理思源黑体、思源宋体等可商用中文字体，规避字体版权风险。",[1130,131,1087],"font",{"path":1078,"title":5,"description":1073,"date":1072,"category":1071,"tags":1132},[1083,1084,1085,1086,1087],{"path":1134,"title":1135,"description":1136,"date":1072,"category":1071,"tags":1137},"\u002Fdocs\u002Finterview-css-layout","CSS 与布局考点","em 与 rem 的区别、移动端三种适配方案对比、viewport 标准设置与 REM 布局的媒体查询实现。",[131,553,1099,1087],{"path":1139,"title":1140,"description":1141,"date":1072,"category":1071,"tags":1142},"\u002Fdocs\u002Finterview-framework-tooling","框架与工程化考点","React diff 与 setState 机制、Redux 核心组成、Vue 常考清单，以及 Webpack、Vite、Git 的面试要点。",[1143,1097,1144,1145,1087],"vue","webpack","vite",{"path":1147,"title":1148,"description":1149,"date":1072,"category":1071,"tags":1150},"\u002Fdocs\u002Finterview-javascript-core","JavaScript 核心考点","数据类型、this 绑定、闭包、原型链、异步与数组方法，前端面试中 JS 部分的高频考点与代码示例。",[1097,1098,1087],{"path":1152,"title":1153,"description":1154,"date":1072,"category":1155,"tags":1156},"\u002Fdocs\u002Fjs-module-systems","JavaScript 模块化方案","梳理 CommonJS、AMD、ES Module 等模块化方案的差异与使用方式。","fundamentals",[1097,1157,1098,1087],"module-system",{"path":1159,"title":1160,"description":1161,"date":1072,"category":1155,"tags":1162},"\u002Fdocs\u002Fwebsocket-basics","WebSocket 基础","WebSocket 全双工通信协议的事件、方法与基本用法整理。",[1163,1085,1097,1087],"websocket",{"path":1165,"title":1166,"description":1167,"date":1168,"category":1121,"tags":1169},"\u002Fdocs\u002Fgojs-getting-started","GoJS 入门实战","从引入方式、画布初始化到节点模板与数据绑定，一份可直接上手的 GoJS 流程图开发笔记。","2024-08-22",[1170,1097,1087],"gojs",{"path":1172,"title":1173,"description":1174,"date":1175,"category":1121,"tags":1176},"\u002Fdocs\u002Fecharts-options-notes","ECharts 配置项速查","整理 ECharts 常用 option 配置：数据格式、坐标轴、图例与交互项的实际用法。","2024-08-09",[1177,1097,1109],"echarts",{"path":1179,"title":1180,"description":1181,"date":1182,"category":1155,"tags":1183},"\u002Fdocs\u002Fhttp-status-codes","HTTP 响应状态码详解","按 1xx 到 5xx 分类梳理 HTTP 状态码的含义与典型使用场景。","2024-06-27",[1084,1085,1109],{"path":1185,"title":1186,"description":1187,"date":1188,"category":1155,"tags":1189},"\u002Fdocs\u002Fhtml-basics","HTML 基础笔记","HTML 语法规范、常用标签、表格与表单元素速查。","2022-06-10",[553,1087,1109],1788337378840]