前端性能优化

作者: alanwhy | 来源:发表于2019-04-28 20:20 被阅读19次

涉及层面

  • 网络层面
  • 构建层面
  • 浏览器渲染层面
  • 服务端层面

资源合并与压缩

http请求的过程及潜在的性能优化点

浏览器的一个请求从发送到返回都经历了什么


image.png
  • dns是否可以通过缓存减少dns查询时间
  • 网络请求的过程走最近的网络环境
  • 相同的静态资源是否可以缓存
  • 能否减少http请求大小
  • 能否减少http请求数量
  • 服务端渲染

html压缩

HTML代码压缩就是压缩这些在文本文件中有意义,但是在HTML中不显示的字符,包括空格,制表符,换行符等,还有一些其他意义的字符,如HTML注释也可以被压缩

  • 使用在线网站进行压缩(走构建工具多,公司级在线网站手动压缩小)
  • node.js提供了html-minifier工具
  • 后端模板引擎渲染压缩

css及js压缩

  • 使用在线网站进行压缩
  • 使用html-minifier对html中的css进行压缩
  • 使用clean-css对css进行压缩
  • 使用html-minifier对html中的js进行压缩
  • 使用uglifyjs2对js进行压缩

不合并文件可能存在的问题

image.png
  • 使用在线网站进行合并
  • 构建阶段,使用nodejs进行文件合并

图片相关优化

不同的格式图片常用的业务场景

  • jpg有损压缩,压缩率高,不支持透明。大部分不需要透明图片的业务场景
  • png支持透明,浏览器兼容性好。大部分需要透明图片的业务场景
  • webp压缩程度更好,在ios webview中有兼容性问题。android全部(解码速度和压缩率高于jpg和png,但是ios safari还没支持)
  • svg矢量图,代码内嵌,相对较小,图片样式相对简单的场景(尽量使用,绘制能力有限,图片简单用的比较多)。图片样式相对简单的业务场景

图片压缩的几种情况

  • 针对真实图片情况,舍弃一些相对无关紧要的色彩信息
  • CSS雪碧图:把你的网站用到的一些图片整合到一张单独的图片中
  • Image-inline:将图片的内容嵌到html中(减少网站的HTTP请求)
  • 使用矢量图
  • 在android下使用webp

css和js的装载与执行

HTML页面加载渲染的过程


image.png
  • 顺序执行,并发加载
    • 词法分析:从上到下依次解析
      • 通过HTML生成Token对象(当前节点的所有子节点生成后,才会通过next token获取到当前节点的兄弟节点),最终生成Dom Tree
    • 并发加载:资源请求是并发请求的
    • 并发上限
      • 浏览器中可以支持并发请求,不同浏览器所支持的并发数量不同(以域名划分),以Chrome为例,并发上限为6个
  • 是否阻塞
    • css阻塞
      • css 在head中通过link引入会阻塞页面的渲染
        • 如果我们把css代码放在head中去引入的话,那么我们整个页面的渲染实际上就会等待head中css加载并生成css树,最终和DOM整合生成RanderTree之后才会进行渲染
        • 为了浏览器的渲染,能让页面显示的时候视觉上更好。
          优化点: 把CDN资源分布在多个域名下

懒加载与预加载

懒加载

  • 图片进入可视区域之后请求图片资源
  • 对于电商等图片很多,页面很长的业务场景适用
  • 减少无效资源的加载
  • 并发加载的资源过多会阻塞js的加载,影响网站的正常使用

先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src)。当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果。

var viewheight = document.documentElement.clientHeight   //可视区域高度

function lazyload(){
    var eles = document.querySelectorAll('img[data-original][lazyload]')

    Array.prototype.forEach.call(eles,function(item,index){
        var rect;
        if(item.dataset.original === '') return;
        rect = item.getBoundingClientRect(); //返回元素的大小及其相对于视口的

        if(rect.bottom >= 0 && rect.top < viewheight){
            !function(){
                var img = new Image();
                img.src = item.dataset.url;
                img.onload = function(){
                    item.src = img.src
                }
                item.removeAttribute('data-original');
                item.removeAttribute('lazyload');
            }()
        }
    })
}

预加载

  • 图片等静态资源在使用之前的提前请求
  • 资源使用到时能从缓存中加载,提升用户体验
  • 页面展示的依赖关系维护
第一种方式:直接请求下来
<img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b216cbfa18" style="display: none"/>
<img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b21b70c8d2" style="display: none"/>
<img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b216e17e26" style="display: none"/>
<img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b217b3ae59" style="display: none"/>
第二种方式:image对象
var image = new Image();
image.src = "www.pic26.com/dafdafd/safdas.jpg";
第三种方式:xmlhttprequest
var xmlhttprequest = new XMLHttpRequest();

xmlhttprequest.onreadystatechange = callback;

xmlhttprequest.onprogress = progressCallback;

xmlhttprequest.open("GET","http:www.xxx.com",true);

xmlhttprequest.send();

function callback(){
    if(xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200){
        var responseText = xmlhttprequest.responseText;
    }else{
        console.log("Request was unsuccessful:" + xmlhttprequest.status);
    }
}

function progressCallback(){
    e = e || event;
    if(e.lengthComputable){
        console.log("Received"+e.loaded+"of"+e.total+"bytes")
    }
}  

重绘与回流

回流

  • 当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就成为回流(reflow)
  • 当页面布局和几何属性改变时,就需要回流

重绘

  • 当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不影响布局,比如background-color。

回流必将引起重绘,但是重绘不一定会引起回流

新建DOM的过程

  • 获取DOM后分割为多个图层
  • 对每个图层的节点计算样式结果(Recalculate style 样式重计算)
  • 为每个节点生成图形和位置(Layout 回流和重布局)
  • 将每个节点绘制填充到图层位图中(Paint Setup和Paint 重绘)
  • 图层作为纹理上传至gpu
  • 符合多个图层到页面上生成最终屏幕图像(Composite Layers 图层重组)

优化方式:

  • 尽量避免使用触发回流、重绘的CSS属性
  • 将重绘、回流的影响范围限制在单独的图层(layers)之内
  • 图层合成过程中消耗很大页面性能,这时候需要平衡考虑重绘回流的性能消耗

浏览器存储

cookies

cookie的生成方式:

  • http-->response header-->set-cookie
  • js中可以通过document.cookie可以读写cookie

cookie的限制:

  • 作为浏览器存储,大小4kb左右
  • 需要设置过期时间 expire

localStorage

  • HTML5设计出来专门用于浏览器存储的
  • 大小为5M左右
  • 仅在客户端使用,不和服务端进行通信
  • 接口封装较好
  • 浏览器本地缓存方案

sessionstorage

  • 会话级别的浏览器存储
  • 大小为5M左右
  • 仅在客户端使用,不和服务器端进行通信
  • 接口封装较好
  • 对于表单信息的维护

indexedDB

  • IndexedDB是一种低级API,用于客户端存储大量结构化数据。该API使用索引来实现对该数据的高性能搜索。
  • 为应用创建离线版本
 function openDB(name, callback) {
            //建立打开indexdb  indexedDB.open
            var request = window.indexedDB.open(name)
            request.onerror = function(e) {
                console.log('on indexedDB error')
            }
            request.onsuccess = function(e) {
                    myDB.db = e.target.result
                    callback && callback()
                }
                //from no database to first version,first version to second version...
            request.onupgradeneeded = function() {
                console.log('created')
                var store = request.result.createObjectStore('books', {
                    keyPath: 'isbn'
                })
                console.log(store)
                var titleIndex = store.createIndex('by_title', 'title', {
                    unique: true
                })
                var authorIndex = store.createIndex('by_author', 'author')

                store.put({
                    title: 'quarry memories',
                    author: 'fred',
                    isbn: 123456
                })
                store.put({
                    title: 'dafd memories',
                    author: 'frdfaded',
                    isbn: 12345
                })
                store.put({
                    title: 'dafd medafdadmories',
                    author: 'frdfdsafdafded',
                    isbn: 12345434
                })
            }
        }
        var myDB = {
            name: 'tesDB',
            version: '2.0.1',
            db: null
        }

        function addData(db, storeName) {

        }

        openDB(myDB.name, function() {
            // myDB.db = e.target.result
            // window.indexedDB.deleteDatabase(myDB.name)
        });

        //删除indexedDB

缓存

期望大规模数据能自动化缓存,而不是手动进行缓存,需要浏览器端和服务器端协商一种缓存机制

  • Cache-Control所控制的缓存策略
  • last-modified 和 etage以及整个服务端浏览器端的缓存流程
  • 基于node实践以上缓存方式
image.png
image.png

服务端性能优化

服务端用的node.js因为和前端用的同一种语言,可以利用服务端运算能力来进行相关的运算而减少前端的运算


image.png

原文链接:web前端性能优化总结

相关文章

  • 前端性能优化(中)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(上)...

  • 前端性能优化(下)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(中)...

  • 前端性能优化(上)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 为什么要进行前端性能...

  • 前端面试必问及加分点---性能优化篇

    如何进行网站性能优化 你有用过哪些前端性能优化的方法? 谈谈性能优化问题 代码层面的优化 前端性能优化最佳实践

  • 前端性能优化

    对于前端的性能优化,主要有分为加载优化和性能优化。在Google官方文档中,给出了性能优化有哪些好处。前端优化的最...

  • 常用的后端性能优化六种方式:缓存化+服务化+异步化等

    性能优化专题 前端性能优化 数据库性能优化 jvm和多线程优化 架构层面优化 缓存性能优化 常用的后端性能优化六大...

  • 关于前端性能优化问题详解

    关于前端性能优化问题详解 出处:http://segmentfault.com/blogs 前端性能优化指南 AJ...

  • 前端性能优化

    前端性能优化 下面是我认知的前端性能优化的策略,本书主要着手 JavaScript 优化展开阐述。 JavaScr...

  • 2019-10-22

    2018 前端性能优化清单

  • 2020-04-11

    前端工程化相关 前端动画相关 优化前端性能

网友评论

    本文标题:前端性能优化

    本文链接:https://www.haomeiwen.com/subject/waeqnqtx.html