- 前端优化的手段
- js css压缩合并
- css在上,js在下(defer,async)
- 图片压缩、CSS-sprit或者将小图使用base64内嵌
- 将静态内容推向CDN, 首页css inline
- 懒加载
- 避免操作DOM,避免重绘
- 去除不必要的cookies,静态资源部署在无cookie的域名或二级域名(domain设置前面去掉 . )
- script标签defer和async区别
- 相同点:
都不阻塞DOM渲染,对inline script无效,不能调用document.write,都有回调 - 不同点:
defer出现于html4,async出现于h5
async在下载结束后立即执行,在window.onload前执行(可能乱序);defer在DOM解析完毕后执行,在document. DOMContentLoaded前(不乱序)。
- 什么时候使用base64
- base64的好处是不产生额外请求;可以被gzip压缩;没有跨域问题,无需考虑缓存。
- base64的弊端如是会造成HTML或CSS体积明显增加,明显影响网页的打开速度。如果用外链图片的话,图片可以在页面渲染完成后继续加载,不会造成阻塞(但base64是会缓存的);base64有IE兼容性问题,IE 8以下不支持data url。
- Webpack打包时可以设置图片小于多少时base64,默认是1k。
-
html的渲染过程
- 几个节点:
domInteractive dom树构建完成
domContentLoaded CSSdom构建完成且defer的脚本也执行完毕(很多js框架监听此事件来开始执行,所以通过测量这它的start到end可以知道框架的执行时间。这步结束后render树构建完成,进入呈现阶段(包括布局和绘制)。
domComplete HTML中所有资源(包括图片)加载完毕,浏览器页面上loading停止。
load 最后一步,用于触发业务逻辑。
- render tree构建及之后的渲染过程
-
render tree包括DOM和CSSDOM
- 根据DOM和样式表生成CSSDOM的过程称附着过程(webkit内核),主要将CSS样式应用到节点上。
-
render tree节点即为与其相对应的DOM节点的CSS框,框的类型与DOM节点的display属性有关,block元素生成block框(BFC),inline元素生成inline框(IFC)。每个render tree节点都有与之相对应的DOM节点,但DOM节点不一定有与之相对应的呈现树节点,比如display: none的DOM节点,而且节点在render tree中的位置与他们在DOM tree中的位置不一定相同,比如float与绝对定位元素。
- 布局(layout)过程,将内存中的render tree根据窗口实际大小等信息计算其实际的值。是一个递归过程,遍历各个子节点。
- 绘制(paint)过程,将上一步的各个节点在屏幕上绘制出来(特性的顺序为背景颜色、背景图片、边框、子呈现树节点、轮廓)。
- 如何实现懒加载(跟预加载的区别)
- 首先,不要将图片地址放到src属性中,而是放到其它属性(data-original)中。
- 页面加载完成后,根据scrollTop判断图片是否在用户的视野内,如果在,则将data-original属性中的值取出存放到src属性中。
- 在滚动事件中重复判断图片是否进入视野,如果进入,则将data-original属性中的值取出存放到src属性中。
- H5中新增了lazyload(等非lazyload资源下载完成后再下载)和postpone(等资源被使用时再下载)特性。
- 预加载是提前加载图片等较大的资源。常用的是new Image(),通过设置其src来实现预载(可使用onload方法添加回调)。加载图片到本地后网页中同样src的图片就会使用缓存。
- 重绘(repaints)和回流(reflow)
当render tree中的部分因为元素的规模尺寸,布局,隐藏等改变而需要重新构建称为回流。回流一定会造成重绘,为优化性能,浏览器一般会维护一个渲染队列来批量更新,只触发一次回流。
造成回流的行为
- 调整窗口大小
- fixed的元素在窗口拖动时(reflow自己)
- 计算 offsetWidth、offsetHeight 等属性(会flush渲染队列)
- 脚本操作 DOM
- 改变字体(自己及后面元素)
- 内容变化,比如用户在input框中输入文字(自己)
- 激活 CSS 伪类,比如 :hover
- 增加或者移除样式表
- 修改class的样式内容
- 设置 style 属性的值
如何优化
- 有动画的元素设为absolute或者fixed,这样不会影响其他dom
- 避免使用table
- 不要多次请求offsetWidth, offsetHeight等属性,如需要可以缓存。
- 避免使用多层内联样式,用一个外部样式
- 多次回流的元素设置transform: translate3d(0px, 0px, 0px);开启gpu加速
- 动态样式直接改变className,不要改style或class内容