学习整理慕课网cc老师的 前端的性能优化课程

《一常用图片优化方法》

关于加载优化之图片优化技巧 详细可参考该文章https://juejin.im/post/5d64c47e6fb9a06b0a2783ff?utm_source=gold_browser_extension

1,图片与css: 使用css效果,css动画。替代一些图片或者是js动画,js动画没有css来的简单,css动画还可以通过animationend,translationend事件来监听动画结束,但是js不可以。css效果可以提供与分辨率,缩放无关的清晰度效果,占用空间也更小。
2, 无法避免的图片,如何选择?
jpg全名jpeg,以24位颜色存储单个位图,容易失真,适合颜色丰富的图片
png大,适合活动图片,需要清晰的显示色彩丰富的图片
gif唯一的较通用的动画图
svg可以缩放矢量图,体积小
未来apng和webp
3,图片加载效果 :一种是先模糊后清晰,一种是很清晰,但是逐行加载,原理是图片压缩算法不同,前者是小波算法,后者是离散余弦变换,浏览器只是根据图片压缩算法来选择渲染算法,压缩算法存在文件头部,我们不能 通过改变图片后缀名影响加载方式。
4,小的icon,使用sprites替代
在线制作: http://alloyteam.github.io/gopng
http://fis.baidu.com
http://gruntjs.com
5,响应式动态图片加载(SDK)

1需要一个默认图片,
2需要屏幕分辨率信息给服务器
3服务给我们更优质的图片
6,未来方法
新元素
在这里插入图片描述
《二常用视频优化方法》
video标签/ flash播放
目前方案,flash和h5 video结合,组成完整方案,比如:
flowplayer功能简洁,使用方便
https://flowplayer.org/player
videojs功能强大,使用复杂
https://videojs.com

浏览器会默认将多媒体资源放置到页面的最后加载,这就需要我们处理资源前置,对于视频直播网站,用户更需要的进入就能直观看视频,而不是去互动弹幕聊天等其他功能。
解决方案:用加载样式表的方式引入媒体资源,这样浏览器就不会把资源当成媒体资源而后置加载。
下一个目标优化:利用浏览器的内存,提高加载速度。

《三常用缓存方式》
cookies/sessionstroage/localstroage/userData/openDatabase等业内常用的储存方式。
技术选型:什么问题?通用方案?方案能解决问题?我们自己的方案,需要其他的方案来融合?自己造轮子?
1,sessionstroage:临时存储中心,小,不能跨页面,关闭页签会丢失(同页面打开同标签也不能拿到)
注意sessionstroage.getItem(‘keys’)和sessionstroage.keys获取值方式不一样,我们需要对null和undefined都做判断。
2,localstroage:长期存储只是对于同一个浏览器,换言之,不同浏览器是读不到在其他浏览器的缓存的,同一浏览器关闭不影响,非手动不清除会一直存在,存储有限制,ie9,ie10不支持
3,cookies:兼容性最好的本地存储,常见用于保存登录态, 大小限制,每次发送请求,请求头都会携带cookie过去。
4,userData:ie的私有存储中心,单文件限制128kb,一个域名下限制1024kb,在受限制站点分别是64kb和640kb
5,openDatabase:浏览器的完整的数据库,
创建,增删改查
实例演示数据库操作的api




Title

<h1>opendatabse数据库操作</h1>

<button id="btn-create">创建user数据表</button>
<button id="btn-insert">插入数据</button>
<button id="btn-query">查询数据</button>
<button id="btn-update">修改数据</button>
<button id="btn-delete">删除数据</button>
<button id="btn-drop">删除user数据表</button>

<script type="text/javascript">

    let findId = id => document.getElementById(id);

    //模拟一条user数据
    let user = {
        username: "vv",
        password: "123456",
        info: "程序员"
    };

    /**
     * 创建数据库 或者此数据库已经存在 那么就是打开数据库
     * name: 数据库名称
     * version: 版本号
     * displayName: 对数据库的描述
     * estimatedSize: 设置数据的大小
     * creationCallback: 回调函数(可省略)
     */
    let db = openDatabase("MySql", "1.0", "我的数据库描述", 1024 * 1024);
    let result = db ? "数据库创建成功" : "数据库创建失败";
    console.log(result);


    const USER_TABLE_SQL = "create table if not exists userTable (id integer primary key autoincrement,username varchar(12)," +
        "password varchar(16),info text)";

    //创建数据表
    function createTable() {
        db.transaction(tx => {
            tx.executeSql(USER_TABLE_SQL, [],
                (tx, result) => {
                    alert('创建user表成功:' + result);
                }, (tx, error) => {
                    alert('创建user表失败:' + error.message);
                })
        })
    }

    const INSERT_USER_SQL = "insert into userTable (username, password,info) values(?,?,?)";

    //插入数据
    function insertData(user) {
        db.transaction(tx => {
            tx.executeSql(INSERT_USER_SQL,
                [user.username, user.password, user.info],
                (tx, result) => {
                    alert('添加数据成功:');
                }, (tx, error) => {
                    alert('添加数据失败:' + error.message);
                })
        })
    }

    const QUERY_USER_SQL = "select * from userTable";

    //查询数据
    function queryData() {
        db.transaction(tx => {
            tx.executeSql(QUERY_USER_SQL, [],
                (tx, result) => {
                    console.log(result);
                },
                (tx, error) => {
                    console.log('查询失败: ' + error.message)
                })
        })
    }

    const UPDATE_USER_SQL = "update userTable set password = ? where username = ?";

    //修改数据
    function updateData(user) {
        db.transaction(tx => {
            tx.executeSql(UPDATE_USER_SQL, [user.password, user.username],
                (tx, result) => {
                    alert("修改数据成功")
                }, (tx, error) => {
                    alert("修改数据失败:" + error.message)
                })
        })
    }

    const DELETE_USER_SQL = "delete from userTable where username = ?";

    //删除数据
    function deleteData(user) {
        db.transaction(tx => {
            tx.executeSql(DELETE_USER_SQL, [user.username],
                (transaction, resultSet) => {
                    alert("删除数据成功")
                }, (transaction, error) => {
                    alert("删除数据失败:" + error.message)
                })
        });
    }

    const DROP_USER_SQL = "drop table userTable";

    //删除数据表
    function dropTable() {
        db.transaction(tx => {
            tx.executeSql(DROP_USER_SQL, [],
                (transaction, resultSet) => {
                    alert("删除数据表成功")
                }, (transaction, error) => {
                    alert("删除数据表失败:" + error.message)
                })
        })
    }

    /**
     * 点击事件 增删查改
     */
    let btnCreate = findId("btn-create");
    let btnInsert = findId("btn-insert");
    let btnQuery = findId("btn-query");
    let btnUpdate = findId("btn-update");
    let btnDelete = findId("btn-delete");
    let btnDrop = findId("btn-drop");
    btnCreate.onclick = () => createTable();
    btnInsert.onclick = () => insertData(user);
    btnQuery.onclick = () => queryData();
    btnUpdate.onclick = () => {
        user.password = "111666666"; //修改密码
        updateData(user);
    };
    btnDelete.onclick = () => deleteData(user);
    btnDrop.onclick = () => dropTable();

</script>
</body>
</html>

————————————————
版权声明:本文为CSDN博主「LQ-刘强」的原创文章
原文链接:https://blog.csdn.net/qq_33429583/article/details/79674597

《四做一个通用的缓存sdk》
封装一个本地缓存通用的tools出来。
目标:提取用户第一时间看到的,提取页面第一时间执行的
1,初始化数据的js,或者依赖的类库
2,用户进入页面需要看到的页面的结构
3,拉去新资源,存储新资源,根据版本迭代,置换过期资源。
功能:
1,网络交互,xhr ; 2,本地存储,localSDK; 3,缓存展示,浏览器dom解析器
在这里插入图片描述

window.Xhrfactory = function () {
        this.init.apply(this, arguments);
    };
    // 网络xhr
    window.Xhrfactory.prototype = {
        init: function () {
            this.xhr = this.create();
        },
        create: function () {
            var xhr = null;
            if (window.XMLHttpRequest) {
                xhr = new XMLHttpRequest();
            } else if (window.ActiveXobject) {
                xhr = new ActiveXObject('Msml2.Xmlhttp');
            } else {
                xhr = new ActiveXObject('Microsoft.Xmlhttp');
            }
            return xhr;
        },
        readystate: function (callback) {
            this.xhr.onreadystatechange = function () {
                if (this.readyState === 4 && this.status === 200) {
                    callback(this.responseText);
                }
            }
        },
        para: function (data) {
            var datastr = '';
            if (data && Object.prototype.toString.call(data) === '[object Object]') {
                for (var key in data) {
                    datastr += (key + '=' + data[key] + '&');
                }
                if (datastr) datastr = datastr.slice(0, -1);
            }
        },
        get: function (url, data, callback) {
            this.readystate(callback);
            var newurl = url;
            var datastr = this.para(data);
            newurl = url + '?' + datastr;
            this.xhr.open('get', newurl, true);
            this.xhr.send(null);
        }
    }
   //由后台控制缓存
   var localStorageSign = 'on';
   //版本控制
   var resourceVersion = '1221211212121';
    // 本地sdk
    window.mLocalSdk = {
        resourceJavascriptList =[
            { scriptId: '1', url: "lib.js", type: 'javascript' },
            { scriptId: '2', url: "common.js", type: 'javascript' },
            { scriptId: '3', url: "index.js", type: 'javascript' }
        ],
        needUpdate: (function () {
            return localStorage.getItem('resourceVersion') === resourceVersion;
        })(),
        isIE: (function () {
            var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串  
            var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器  
            var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器  
            var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
            if (isIE || isEdge || isIE11) {
                return true;
            } else {
                return false;
            }
        })(),
        checkHedge: function () {
            var localStroageLength = localStorage.length;
            var localStorageSize = 0;
            for (var i = 0; i < localStorageSize; i++) {
                var key = localStorage.key(i);
                localStorageSize += localStorage.getItem(key).length;
            }
            return localStorageSize;
        },
        startup: function () {
            var self = this;
            if (localStorageSign === 'on' && this.isIE && window.localStorage) {
                if (this.needUpdate) {
                    return (function () {
                        for (var i = 0; i < self.resourceJavascriptList.length; i++) {
                            //获取本地缓存列表,输入到html
                            var scriptId = self.resourceJavascriptList[i]['scriptId'];
                            //把我们的列表中的js渲染到页面, 读取本地文件
                            window.mDomUtils.addJavascriptByInline(scriptId);
                        }
                    })();
                } else {
                    //把网络获取的js渲染html
                    return (function () {
                        // save 请求到的js
                        self.saveSdk();
                        for (var i = 0; i < self.resourceJavascriptList.length; i++) {
                            //获取本地缓存列表,输入到html
                            var scriptId = self.resourceJavascriptList[i]['scriptId'];
                            //把我们的列表中的js渲染到页面, 读取本地文件
                            window.mDomUtils.addJavascriptByInline(scriptId);
                        }
                    })();
                }
            } else {
                //把网络获取的js渲染html
                // 原始方法加载js
                return (function () {
                    for (var i = 0; i < self.resourceJavascriptList.length; i++) {
                        //获取本地缓存列表,输入到html
                        var scriptId = self.resourceJavascriptList[i]['scriptId'];
                        //把我们的列表中的js渲染到页面, 读取本地文件
                        window.mDomUtils.addJavascriptByLink(scriptId, url);
                    }
                })();
            }
        },
        //写入本地localstorage
        saveSdk: function () {
            try {
                localStorage.setItem('resourceVersion', resourceVersion)
            } catch (oException) {
                if (oException.name === 'QuotaExceededError') {
                    localStorage.clear();
                    localStorage.setItem('resourceVersion', resourceVersion);
                }
            }
            for (var i = 0; i < this.resourceJavascriptList.length; i++) {
                let self = this;
                (function(i){
                    var scriptId = self.resourceJavascriptList[i]['scriptId'];
                    var xhr = new Xhrfactory();
                    xhr.get(self.resourceJavascriptList[i]['url'], null, function (data) {
                        try {
                            localStorage.setItem(scriptId, data);
                        } catch (oException) {
                            if (oException.name === 'QuotaExceededError') {
                                localStorage.clear();
                                localStorage.setItem(scriptId, data);
                            }
                        }
                    });
                })(i);
                // addhtml 加载到页面中
            }
        }
    };

    window.mDomUtils = {
        // 内联添加script
        addJavascriptByInline: function (scriptId) {
            var script = document.createElement('script');
            script.setAttribute('type', 'text/javascript');
            script.id = scriptId;
            var heads = document.getElementsByTagName('head');
            if (heads.length) {
                heads[0].appendChild(script);
            } else {
                document.documentElement.appendChild(script);
            }
            script.innerHTML = localStorage.getItem(scriptId);
        },
        // 外链添加script
        addJavascriptByLink: function (scriptId, url) {
            var script = document.createElement('script');
            script.setAttribute('type', 'text/javascript');
            script.setAttribute('src', url);
            script.id = scriptId;
            var heads = document.getElementsByTagName('head');
            if (heads.length) {
                heads[0].appendChild(script);
            } else {
                document.documentElement.appendChild(script);
            }
        },
        addCssByLink: function (url) {
            var link = document.createElement('link');
            link.setAttribute('rel', 'stylesheet');
            link.setAttribute('type', 'text/css');
            link.setAttribute('href', url);

            if(link.stylesheet) {
                // ie
                link.stylesheet.cssText = cssString;
            }else{
                // w3c
                var cssText = doc.createTextNode(cssString);
                link.appendChild(cssText);
            }


            var heads = document.getElementsByTagName('head');
            if (heads.length) {
                heads[0].appendChild(link);
            } else {
                document.documentElement.appendChild(link);
            }
        }
    };
    //展示缓存



    //单文件9000多字符限制sdk

《五高性能dom》
这里主要涉及造成性能优化dom时候,主要碰到的重绘和回流问题,介绍他们的原因和解决方案,最后实际代码来验证。

为什么写高性能dom?
在这里插入图片描述
站点的网络消耗,dom初始化(浏览器),dom结构及操作(人为),js执行(浏览器),js逻辑(人为)

关于reflow和repaint,避免回流和重绘。
在这里插入图片描述
改变字体,修改样式表,内容改变比如input,激活css伪类,操作dom,offsetwidth,offsetheight, style值修改

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值