多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 运行环境(浏览器) 1. 浏览器可以通过访问链接来得到 页面的内容 2. 通过绘制和渲染,显示出页面的最终的样子 3. 过程中的问题? ### 知识点 1. 页面加载过程 2. 性能优化 3. 安全性 #### 页面加载 1. 从输入url到得到html的详细过程 2. window.onload和DOMContentLoaded的区别 #### 知识点 1. 加载资源的形式 2. 加载一个资源的过程 3. 浏览器渲染页面的过程 ##### 加载资源的形式 * 输入url(或跳转页面)加载html * 输入链接 * 加载html中的静态资源 * script css 媒体资源(img video) #### 加载一个资源的过程 1. 浏览器根据DNS服务器得到域名的IP地址 * baidu.com ==> ip地址 (ip地址相当于服务器) 2. 向这个ip的机器发送http请求 3. 服务器收到,处理并返回http请求 4. 浏览器得到返回内容 #### 浏览器渲染页面的过程 1. 根据HTML结构生成DOM Tree(dom树是什么?) 2. 根据css生成 CSSOM(将css静态代码进行结构化处理 object model) 3. 将DOM和CSSOM整合RenderTree!!(渲染树) 区别:(dom树只是一个树形结构,没有规定每个dom节点的样式是什么,dom树和cssom结合起来,生成渲染树,渲染树在结构上和dom树是一致的树形结构,但是每个节点中样式(长宽高...)都在渲染树里,)(dom树是html代码的结构化,没有样式)(render树会有样式,cssom规定了它的样式) (浏览器渲染页面时,要知道页面的结构是什么,也要知道样式的结构是什么) 4. 根据RenderTree开始渲染和展示 5. 遇到`<script>`时,会执行并**阻塞渲染**(单线程,因为js有权利改变dom结构,和html渲染冲突,因此要阻塞渲染) ##### 示例 1. 加载html代码 2. 分析,head不用渲染,但head中有css,先加载css文件(渲染是顺序执行),加载出来后解析(cssom),浏览器已经知道遇到div要怎样怎样,css已经解析完了,再渲染div的时候,在已知样式的情况下,**对div一次性渲染**。head中的css会先加载解析,此时浏览器已经知道规则,再渲染dom结构时,对拿到的div节点生成dom结构时,已经知道了cssom结构,一下子生成渲染树,渲染出来 3. 思考:为何把css放在head中? 规定:把css放在head中(body出来之前,把css拿到),加载完css,浏览器直接知道规则,渲染body时,已经把规则考虑进去渲染, 如果放在body下面或里面:渲染body后再渲染css,样式先会默认渲染,再重新渲染,(电脑配置,网络情况,页面规模,会影响体验),用户体验和性能都很差(能一次干的事要两次干) 4. script放在body中,div之间:遇到script停止渲染,加载执行script,阻塞浏览器的渲染(script有权利操作dom(改变结构或内容),浏览器不得不阻塞停止渲染),script如果改后面的div,会出错 5. 为何要把script放在body最下面(即将结束的位置)(性能优化问题) * 不会阻塞页面渲染(body内前面的内容),没有执行script,先把html结构渲染出来,不会阻塞页面(性能为题) * 把script放在最下面,script能拿到所有的标签(放上面script拿不到下面标签) 6. 插入图片 * 加载html内容 * 开始渲染,图片是异步请求,并不会阻碍dom树的渲染,但img标签可用 #### window.onload和DOMContentLoaded ~~~ window.addEventListener('load',function({ // 页面的全部资源加载完成才会执行,包括页面,视频等异步加载 })) document.addEventListener('DOMContentLoaded',function(){ // DOM渲染完即可执行,此时图片、视频可能没有加载完 }) ~~~ #### 解答 1. 从输入到得到html的详细过程 * 浏览器根据DNS服务器得到域名的IP地址 * 向这个Ip的技巧发送http请求 * 服务器收到、处理并返回http请求 * 浏览器得到返回内容 2. window.onload和DOMContentLoaded(尽量用第二种) * 页面的全部资源加载完才会执行,包括图片、视频等 * DOM渲染完即可执行,此时图片、视频还没加载完 zepto/jquery如何判断页面加载完,它们用的是(DOMContentLoaded) ### 性能优化 * 综合性问题 * 没有标准答案,很多 * 只关注核心点,针对面试 #### 原则 1. 多使用内存、缓存(内存存储,不是硬盘)或者其他方法 2. 减少 cpu 计算、减少网络 #### 哪里入手 * 加载页面和静态资源(加载更快) * 页面渲染 #### 加载资源优化 1. 静态资源的压缩合并(三个js文件,可以合并成一个,耗费一个请求)(压缩) 2. 静态资源缓存(资源名字不变,本地会有缓存,浏览器策略,第二次加载不会重新加载,文件名发生变化会重新请求)(减少请求) 3. 使用CDN让资源加载更快(大网站,有自己的,小网站用网上的)(为什么?CDN是不同区域的网络优化,北京访问地址,会就近找到CND进行加载)(距离远走的路由器比较多) 4. 使用SSR后端渲染,数据直接输出到HTML中(以前ssr:server site render,jsp,php,asp) #### 渲染优化 1. css放前面,js放后面 2. 懒加载(图片懒加载、下拉加载更多)(什么时候用,什么时候加载) 3. 减少DOM查询,对DOM查询做缓存 4. 减少DOM操作,多个操作尽量合并在一起执行 (DOM操作是非常非常昂贵的) 5. **事件节流**() 6. 尽早执行操作(如DOMContentLoaded) #### 示例讲解 1. 资源合并 CommonJS合并(模块化) ~~~ // 发送三个请求 <script src="a.js"></script> <script src="b.js"></script> <script src="c.js"></script> // 发生一个请求 <script src="abc.js"></script> ~~~ 2. 缓存 * 通过连接名称控制缓存 * `<script src="abc_1.js"></script>`(名字不变,不会重新下载) * 只有内容改变的时候,链接名称才会改变 * `<script src="abc_2.js"></script>` 3. CDN **bootcss** 4. 使用SSR后端渲染(vue,react) * 现在vue react提出了这样的概念 * 其实jsp php asp都属于后端渲染 * 动态页面(数据直接输出到页面中,没必要ajax请求数据) 5. 懒加载 原理:其实src是赋值很小的preview的图片,真正的图片地址是放在data属性之后的,用的时候把data属性拿过来替换原理的src,会加快渲染速度 ~~~ <img id="img1" src="preview.png" data-realsrc = "abc.png" /> <script> var img1 = document.getElementById("img1"); img1.src = img1.getAttribute("data-realsrc"); </script> ~~~ 6. 缓存DOM查询 ~~~ // 未缓存dom查询(每次循环都进行一次dom查询) var i; for(var i=0; i<document.getElementByTagName('p').length;i++){ // todo } // 缓存了DOM查询 var pList = document.getElementsByTagName('p'); var i; for(var i=0; i<pList .length;i++){ // todo } ~~~ 7. 合并DOM插入 ~~~ var lisNode = document.getElementById("list"); //要插入10个list标签 var frag = document.createDocumentFragment(); var x,li; for(x=0; x<10; x++){ li = document.createElement('li'); li.innerHTML = "list item"+x; frag.appendChild(li); } listNode.appendChild(frag); ~~~ **document.createDocumentFragment();**//临时片段,它的appendChild不会触发dom操作 10次dom插入变成1次 8. 事件节流(减少cpu计算) 快速操作的时候,不要执行事件,什么时候执行什么时候操作,会提高性能 keyup触发事件操作,不要每次都触发,可以有个时间间隔 停下来(超过100ms以上)时触发change操作 ~~~ var textarea = document.getElementById('text'); var timeoutId; textarea.addEventListener('keyup', function(){ if(timeoutId){ clearTimeout(timeoutId) } timeoutId = setTimeout(function(){ // 触发change事件 }, 100) }) ~~~ 9. 尽早操作 DOMContentLoaded(0.1s) load(2s) ### 安全性 -XSS(优先级比较低) 综合性问题:场景的前端安全问题有哪些 1. XSS跨站请求攻击 2. XSRF跨站请求伪造 后端来防,前端配合 #### XSS * 新浪博客写文章,同时偷偷插入一段`<script>` * 攻击代码中,获取cookie,发送自己的服务器(查看文章时,代码执行,获取cookie,一般会有账户信息,发送到自己的服务器) * 发布博客,有人查看博客内容 * 会把查看者的cookie发送到攻击者的服务器(拿到很多人的账号) 原理:输入脚本,脚本中有攻击代码,获取信息发送到自己的服务器 解决: 1. 前端替换关键字,例如替换 < 为` &lt;` >为 `&gt;`不是很好,因为会影响性能,js执行效率比较低,前端只有浏览器,后端有强大的服务器 2. 后端替换(依赖于服务器的能力) #### XSRF * 登录一个购物网站,正在浏览商品 * 该网站付费接口是xxx.com/pay?id=100但是没有任何验证 * 然后你收到一个邮件,隐藏着`<img src=xxx.com/pay?id=100 />`请求悄悄付费,你的钱已经没有了 * 你查看邮件的时候,就悄悄付费了 解决方案 1. 增加验证流程,如输入指纹,密码,短信验证码(前端做接口,后端做功能)