页面性能优化

    技术2022-07-12  56

    在chrome浏览器,对于同一域名,最多支持6个请求的并发,其他请求会推入到队列中等待或停滞不前,直到6个请求之一完成后,队列中新的请求才会放出。

    可以看到,六个绿色条并发请求,四个灰色条等待请求,最下面三个绿色条3.4s后才触发请求

    html、css、js 代码压缩公共文件(js/css)合并、请求合并浏览器缓存(强缓存、弱缓存)CDN(Content Delivery Network,内容分发网络)加速。通过将静态资源(例如javascript,css,图片等等)缓存到离用户很近的相同网络运营商的CDN节点上,不但能提升用户的访问速度,还能节省服务器的带宽消耗,降低负载(因此,一个地区内只要有一个用户先加载资源,在 CDN 中建立了缓存,该地区的其他后续用户都能因此而受益)loading 动画页面骨架屏减少操作 dom 方法优化图片加载懒加载和预加载

    减少操作 dom 方法

    插入大量dom元素时,可以使用innerHTML替代逐个构建元素处理列表子元素的事件时,可以使用事件委托

    优化图片的加载

    1. 图片懒加载,优先加载浏览器可视区域的图片

    先将img标签的src链接设为同一张图片(比如空白图片),然后给img标签设置自定义属性(比如data-src),然后将真正的图片地址存储在data-src中,当JS监听到该图片元素进入可视窗口时,将自定义属性中的地址存储到src属性中。达到懒加载的效果。 这样做能防止页面一次性向服务器发送大量请求,导致服务器响应页面卡顿崩溃等。

    <style> .container { max-width: 800px; margin: 0 auto; } .container:after { content: ""; display: block; clear: both; } .container img { width: 50%; height: 260px; float: left; } </style> <body> <div class="container"> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img4.imgtn.bdimg.com/it/u=951914923,777131061&fm=26&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=637435809,3242058940&fm=26&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=3990342075,2367006974&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=1813891576,1754763093&fm=26&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img4.imgtn.bdimg.com/it/u=2539922263,2810970709&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img4.imgtn.bdimg.com/it/u=1878067600,3935137756&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img3.imgtn.bdimg.com/it/u=85690711,3884201894&fm=26&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=3844233833,3942617167&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img0.imgtn.bdimg.com/it/u=1846695025,2515725663&fm=26&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img3.imgtn.bdimg.com/it/u=346230831,1833217134&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img5.imgtn.bdimg.com/it/u=3478148120,2683867435&fm=26&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img5.imgtn.bdimg.com/it/u=2298824648,1812234339&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=4201594846,4178139206&fm=26&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=484389598,819397330&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=3729466012,914166979&fm=26&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=354463615,3836278171&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img5.imgtn.bdimg.com/it/u=1831250492,3489827059&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=779005622,2247570143&fm=200&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=1968229118,3512711019&fm=26&gp=0.jpg" /> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img2.imgtn.bdimg.com/it/u=1088428253,1150170159&fm=200&gp=0.jpg" /> </div> </body> </html> <body> <script> // 一开始没有滚动的时候,出现在视窗中的图片也会加载 start(); // 当页面开始滚动的时候,遍历图片,如果图片出现在视窗中,就加载图片 var clock; //函数节流 $(window).on("scroll", function () { if (clock) { clearTimeout(clock); } clock = setTimeout(function () { start(); }, 200); }); function start() { $(".container img") .not("[data-isLoading]") .each(function () { if (isShow($(this))) { loadImg($(this)); } }); } // 判断图片是否出现在视窗的函数 function isShow($node) { return $node.offset().top <= $(window).height() + $(window).scrollTop(); } // 加载图片的函数,就是把自定义属性data-src 存储的真正的图片地址,赋值给src function loadImg($img) { $img.attr("src", $img.attr("data-src")); // 已经加载的图片,我给它设置一个属性,值为1,作为标识 // 弄这个的初衷是因为,每次滚动的时候,所有的图片都会遍历一遍,这样有点浪费,所以做个标识,滚动的时候只遍历哪些还没有加载的图片 $img.attr("data-isLoading", 1); } </script>

    2. 小图片或图标,可用SVG、Iconfont、Base64等技术,多个图标也可以制作成雪碧图(CssSprites)

    3. 加载时预先加载一张特别小的通用略缩图,正式图片加载完成后替换略缩图

    4. 服务端根据业务需要可以对图片进行压缩 (不影响用户体验的情况下)

    5. 为项目添加骨架屏

    操作方式

    6. Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。

    图片的 base64 编码就是可以将一幅图片的二进制编码成一串字符串,使用该字符串代替图像地址可以减少http请求,base64可以随着html的下载同时下载适用于小图片和简单图片

    预加载

    纯 css 实现预加载 不在浏览器可视范围内加载图片,直接 css 加载, 但图片会随文档一起加载,此时可能会降低文档的加载速度纯 js 实现预加载 js 脚本提前加载图片 src 或使用 image 对象提前加载图片css 和 js 实现预加载 如 img 标签最初设置为 display: none,要加载的时候显示 或者滚动条到达可视范围内,js 为目标 div 加上这个已经加载好的 css 属性ajax 预加载 提前 ajax 请求获取数据 场景有个 tab 标签页,当鼠标放到某个 tab,立刻 ajax 加载该 tab 的数据 当点击这个 tab 标签页的时候,就可以立刻加载出来,再将数据缓存起来或加入全局变量,下一次使用直接从缓存读取

    节点

    element.parentNode 返回元素的父节点

    element.childNodes 返回元素的一个子节点的数组

    element.nodeName 返回元素的标记名(大写),用的时候转换小写(element.nodeName.toLowerCase())

    event.target:返回触发此事件的元素(事件的目标节点)

    详看:https://www.cnblogs.com/ainyi/p/8794159.html

    HTML DOM 元素对象:http://www.runoob.com/jsref/dom-obj-all.html

    HTML DOM 事件对象:http://www.runoob.com/jsref/dom-obj-event.html

    工作中对于广告编辑页的优化

    首先,也是最有效的方法,请说服boss不要在一个页面放太多的广告代码,这样很影响效果和用户体验。

    其次,在做了上述工作以后,可以再做一些进一步的优化。根据我的经验,可以有以下几个方面

    对于直接嵌入第三方js脚本的,可以直接把对方脚本下载到本地服务器,这样减少了因为第三方脚本响应过慢而影响载入体验。

    如果有的脚本广告方要求必须使用他们的脚本地址,你可以使用延迟加载的方法。在document.ready后使用jquery的getScript或者使用LABjs来动态加载js。

    对于直接嵌入第三方图片和链接的广告,你可以使用现在已经很成熟的lazyload方案。

    用iframe管理广告。这是目前看来比较合理的。

    其他优化

    公共接口合并,减少 http 请求,后端做缓存promise all 解决根据请求顺序顺序获取的问题(当前接口的数据展示需要依赖上一个接口数据的情景)旧版本是 若有依赖关系的接口,是等待上一个接口请求完毕,才发送当前接口请求数据预加载(第四个模块的数据默认收起,点击展开的时候预先加载。不用等待)公用数据下沉到领域模型,多个模块复用的数据,不用再次请求接口 实现页面 MVC 结构 可看这里数据处理单独抽出来放在 service 层,(vuex mutation)数据处理(数据量很大的时使用数据字典,可以使用 obj.key 得到想要的数据,需要的数据 key 值与数据字段作关系映射)组件化、ESLint 代码规范,便于维护旧版本是 循环使用 if 等于需要的 key 来获取数据for 循环的使用,数组循环使用 for of,对象使用 for in路由方面,使用路由懒加载一开始页面需要加载多条请求,在 axios 统一请求拦截加上loading,和接口请求计数器+1,统一响应拦截计数器-1,当等于零就关闭 loading渠道组件和多选省市级三级联动组件的优化(重写 Element 的穿梭框组件)具体看 关于 Element 组件的穿梭框的重构
    Processed: 0.022, SQL: 9