精华内容
下载资源
问答
  • web前端优化方案

    2018-07-14 16:30:20
    根据yslow建议,个人总结处理的一些web前端优化方案。
  • 前端优化总结

    2021-03-23 14:17:12
    前段时间简单的研究了下前端优化相关的知识,本文算是一个阶段性的总结,或者当做一个优化的参考List。前言前端是庞大的,包括HTML、CSS、Javascript、Image、Flash等等各种各样的资源。前端优化是复杂的,针对...
  • 前端优化的几种方法

    2019-01-11 10:24:33
    前端优化的几种方法,里面包含了前端主流的几种优化方法
  • 最近,康盛的DX版本基本确定,至少短期内不会大变了,因此,我对晋城吧的整站进行了前端优化,把自己 所做的操作记录下来,一是有个记录,防止忘掉,二是和网上的朋友们共享下自己的心得。 前端优化 推荐工具 火狐...
  • 面试篇:前端优化整理

    千次阅读 2020-07-23 21:51:22
    前端优化这种高概率出现的面试题,能背下来最好~技术小白的卤煮表示已经n多次听到大佬们面试会问到。。。。。。 作为一名前端开发工程师,前端优化其实最多的还是资源上的优化,逻辑上的优化不多,因为前端所涉及的...

    故事背景
    前端优化这种高概率出现的面试题,能背下来最好~技术小白的卤煮表示已经n多次听到大佬们面试会问到。。。。。。
    作为一名前端开发工程师,前端逻辑上的优化可行性并不大,因为前端所涉及的逻辑相对于后台来说少之又少(这里不排除有些童鞋写的那些惨不忍睹的代码)。那下面就梳理一下前端优化的手段~

    上才艺!!!

    代码优化:

    1.减少重定向的使用(很影响初屏加载的时间)
    2.避免空src的img标签(浏览器其实会有一些额外的请求发生,版本高一点的这点优化了)
    3.减少iframe数量(同等数量空的div和iframe,iframe的耗时会比div的高1~2个数量级)
    4.减少http请求(卤煮第一次面试就被问到页面请求最多的时候是几个接口???)
    5.善用浏览器缓存机制(客户端缓存cookie、localStroage、sessionStrorage)
    

    资源优化方面:

    1.使用CDN加载资源([戳这里](https://www.cnblogs.com/changlon/p/10165053.html))
    2.压缩HTML、CSS、javascript文件(webpack方向答)
    3.图片整合(尤其页面切图很多时,不要小看图片的占用资源,一张图抵你几百行代码,需要UI配合~)
    

    目前卤煮小白能想到的只有这么多,总感觉没答出来面试官想听的呢?欢迎各位大佬补充!!!!!!
    再老练一点,慢慢积累吧~

    展开全文
  • 无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢,这篇文章主要介绍了浅谈雅虎前端优化的35条军规,感兴趣的小伙伴们可以参考一下
  • 浅谈高并发-前端优化

    千次阅读 2019-09-24 10:08:22
    雅虎前端优化的35条军规 回到业务 回到业务上,本次业务是助力免单。设计图没有几张,担心涉及商业信息就不放图了,因为要求是多页面,我将业务分成三个页面: 首页,查看活动信息页 查看自己活动进程页...

    前言

    最近接到个任务,业务场景是需要处理高并发。

    原谅我第一时间想到的居然是前段时间阮一峰的博客系统遭到了DDoS攻击,因为在我的理解中,它们的原理是想通的,都是服务器在一定时间内无法处理所有的并行任务,导致部分请求异常,甚至会像阮一峰的博客一样崩溃。

    之前不太有接触过高并发的机会,所以并没有什么实际经验,倒是之前做的项目中有秒杀功能的实现做过一定的处理,当时的处理就是多利用缓存进行优化和减少一些没必要的后端请求,但是因为是创业公司,所以并没有多少过多的流量,即便是秒杀,所以也没有进行更进一步的优化了,业务需求不需要,自己也没有过多去思考这个问题了。

    其实刚开始我还是有些想法,利用HTTP头部,强缓存(cache-control)、协商缓存(last-modified和Etag)、开启HTTP2,尤其是HTTP2应该能将性能提升不少吧,但是这些方案大多都需要后端支持,那么前端能做什么呢,倒是还真没好好思考和总结一下。

    理解

    架构搭建之前首先要把需求理解透彻,所以去谷歌搜索了一波,首先看几个名词:

    • QPS:每秒钟请求或者查询的数量,在互联网领域,指每秒响应请求数(指HTTP请求)
    • 吞吐量:单位时间内处理的请求数量(通常由QPS与并发数决定)
    • 响应时间:从请求发出到收到响应花费的时间,例如系统处理一个HTTP请求需要100ms,这个100ms就是系统的响应时间
    • PV:综合浏览量(Page View),即页面浏览量或者点击量,一个访客在24小时内访问的页面数量,同一个人浏览你的网站同一页面,只记作一次PV
    • UV:独立访问(UniQue Visitor),即一定时间范围内相同访客多次访问网站,只计算为1个独立访客
    • 带宽:计算带宽大小需关注两个指标,峰值流量和页面的平均大小

    再看几张图:

    正常访问:

    高并发:

    客户端精简与拦截:

    那么怎么浅显的解释下高并发呢?把服务器比作水箱,水箱与外界连接换水有三根水管,正常情况下都能正常进行换水,但是突然一段时间大量的水需要流通,水管的压力就承受不了了。再简单点:洪涝灾害、早晚高峰、中午12点的大学食堂,大概都是这个原理吧。这些现实问题怎么解决的呢,高并发是不是也可以借鉴一下呢?

    1. 洪涝灾害:修固堤岸(增强服务器性能)
    2. 早晚高峰:多选择其他路线(分流,和分配服务器线路),不是一定需要就避开早晚高峰(减少客户端请求)
    3. 中午12点的大学食堂:学校多开几个食堂(静态资源与后端api分到不同服务器)

    回到高并发的问题上,我认为解决方案主要有这些:

    1. 静态资源合并压缩
    2. 减少或合并HTTP请求(需权衡,不能为了减少而减少)
    3. 使用CDN,分散服务器压力
    4. 利用缓存过滤请求

    后来发现如果要把优化做到很好,雅虎35条军规中很多条对解决高并发也都是有效的。

    回到业务

    回到业务上,本次业务是助力免单。设计图没有几张,担心涉及商业信息就不放图了,因为要求是多页面,我将业务分成三个页面:

    1. 首页,查看活动信息页
    2. 查看自己活动进程页,包括活动结束,开始活动,活动进行中和助力失败几个状态
    3. 帮助他人助力页,包括帮他助力和自己也要助力两个状态

    解决方案

    利用缓存存放数据

    简单分析了一下,需要的数据有:

    {
    	// 这个活动的id,防止多个助力活动同时发起,本地存储混乱的问题
    	id:'xxxxxxxxxx',
    	// 结束时间,这个时间一般是固定的,也可以放到本地存储,不需要多次请求,过了时间可以clear这个
    	endTime:'xxxxxxxx',
    	// 需要助力的人数
    	needFriendsNumber:3,
    	// 直接购买的价格
    	directBuyPrice: 9.9,
    	// 自己的信息,在帮助别人和发起助力时需要自己的信息
    	userInfo:{
    		id:'xxxxxxxxx',
    		avatar:'xxxxxxxxx'
    	},
    	// 帮助过我的人列表,显示帮助我的页面需要用,根据需求看,这个列表人数不会太多,也可以放到本地存储
    	helpMeList:[{
    		id:'xxxxxxxxx',
    		avatar:'xxxxxxx'
    	},{
    		id:'xxxxxxxxx',
    		avatar:'xxxxxxx'
    	}
    	...
    	],
    	// 帮助别人的列表,可以放到本地存储中,在进入给别人助力时不用再发起请求,帮助过别人后加到数组中
    	helpOtherList:[{
    		id:'xxxxxxxxx',
    		avatar:'xxxxxxx'
    	},{
    		id:'xxxxxxxxx',
    		avatar:'xxxxxxx'
    	}
    	...
    	]
    }
    

    嗯,貌似都可以借助本地存储实现减少请求的目的,5M的localStrong应该也够用。这样算来除了助力他人和第一次获取基本信息还有获取助力名单,貌似也不需要其他的额外的请求了。精简请求这个方面目前就是这样了,因为还没有完全写完,所以还有没考虑到的就要到写实际业务的时候碰到再处理了。

    资源压缩

    压缩资源的话webpack在build的时候已经做过了。

    静态资源上传cdn

    然后就是静态资源上传到七牛cdn,具体实现思路是在npm run build之后,执行额外的upload.js,服务器部署的时候只需要部署三个html文件就可以了。 package中:

    "build": "node build/build.js && npm run upload",
    
    const qiniu = require('qiniu')
    const fs = require('fs')
    const path = require('path')
    var rm = require('rimraf')
    var config = require('../config')
    const cdnConfig = require('../config/app.config').cdn
    
    const {
      ak, sk, bucket
    } = cdnConfig
    
    const mac = new qiniu.auth.digest.Mac(ak, sk)
    
    const qiniuConfig = new qiniu.conf.Config()
    qiniuConfig.zone = qiniu.zone.Zone_z2
    
    const doUpload = (key, file) => {
      const options = {
        scope: bucket   ':'   key
      }
      const formUploader = new qiniu.form_up.FormUploader(qiniuConfig)
      const putExtra = new qiniu.form_up.PutExtra()
      const putPolicy = new qiniu.rs.PutPolicy(options)
      const uploadToken = putPolicy.uploadToken(mac)
      return new Promise((resolve, reject) => {
        formUploader.putFile(uploadToken, key, file, putExtra, (err, body, info) => {
          if (err) {
            return reject(err)
          }
          if (info.statusCode === 200) {
            resolve(body)
          } else {
            reject(body)
          }
        })
      })
    }
    
    const publicPath = path.join(__dirname, '../dist')
    
    // publicPath/resource/client/...
    const uploadAll = (dir, prefix) => {
      const files = fs.readdirSync(dir)
      files.forEach(file => {
        const filePath = path.join(dir, file)
        const key = prefix ? `${prefix}/${file}` : file
        if (fs.lstatSync(filePath).isDirectory()) {
          return uploadAll(filePath, key)
        }
        doUpload(key, filePath)
          .then(resp => {
            rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
              if (err) throw err
            })
            console.log(resp)
          })
          .catch(err => console.error(err))
      })
    }
    
    uploadAll(publicPath)
    

    抛开与网站服务器的Http请求,第一次打开首页:

    之后:

    原理大概是这样,效果也还是不错,自己的服务器只需要执行必要的接口任务就行了,不需要负责静态资源的传输

    避免高频刷新页面

    做了一个限定,5秒内刷新页面只获取一次列表数据,避免高频刷新带给服务器的压力

    async init() {
          try {
            const store = JSON.parse(util.getStore('hopoActiveInfo'))
            // 避免高频刷新增加服务器压力
            if (store && (new Date() - new Date(store.getTime)) < 5000) {
              this.basicInfo = store
            } else {
              this.basicInfo = await getActiveInfo()
              this.basicInfo.getTime = new Date()
            }
    
            util.setStore(this.basicInfo, 'hopoActiveInfo')
            this.btn.noPeopleAndStart.detail[0].text = `${
              this.basicInfo.directBuyPrice
            } 元直接购买`
            this.computedStatus()
          } catch (error) {
            console.log(error)
          }
        },
    

    设置响应头cache-control和last-modified

    对于所有的数据和接口设置响应头,利用express模拟,如果两次请求间隔小于5秒,直接返回304,不需要服务器进行处理

    app.all('*', function(req, res, next){
      res.set('Cache-Control','public,max-age=5')
      if ((new Date().getTime() - req.headers['if-modified-since'] )< 5000) {
        // 检查时间戳
        res.statusCode = 304
        res.end()
      }
      else {
        var time =(new Date()).getTime().toString()
        res.set('Last-Modified', time)
      }
      next()
    })
    

    最后总结一下,采取了的措施有:

    1. 利用缓存,精简请求
    2. 合并压缩
    3. 静态资源上传cdn
    4. 避免高频刷新页面获取数据
    5. 设置响应头cache-control和last-modified

    最主要的措施大概也只有这几个,做到的优化很少,差的也还很远,任重而道远,继续努力吧。

    参考:

    展开全文
  • 曾经研究web前端优化时在网上多处看到这样一条建议,大意是: 不要使用 css @import, 因为用这种方式加载css相当于把css放在了html底部。 关于这一点,我一直很疑惑: 为什么用@import就等于把css放在了页面底部?...
  • 前端优化方案

    千次阅读 2019-04-08 09:11:15
    1 优化css 1.1 避免使用CSS表达式 用CSS表达式动态设置CSS属性,是一种强大又危险的方式。从IE5开始支持,但从IE8起就不推荐使用了。例如,可以用CSS表达式把背景颜色设置成按小时交替的 尽量减少标签选择器的使用...

    1 优化css

    1.1 避免使用CSS表达式

    用CSS表达式动态设置CSS属性,是一种强大又危险的方式。从IE5开始支持,但从IE8起就不推荐使用了。例如,可以用CSS表达式把背景颜色设置成按小时交替的

    • 尽量减少标签选择器的使用
    • 尽可能少使用id选择器,多使用样式选择器(通用性强)
    • 减少选择器前缀,例如.headerBox .nav .left a{} 选择器是从右向左查询的
    • 避免使用css表达式
    background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
    复制代码

    1.2 减少页面中的冗余代码

    尽可能提高方法的重复使用率:“低耦合高内聚”

    1.3 选择舍弃@import

    前面提到了一个最佳实践:为了实现逐步渲染,CSS应该放在顶部。 在IE中用@import与在底部用<link>效果一样,所以最好不要用它。

    1.4 避免使用滤镜

    IE专有的AlphaImageLoader滤镜可以用来修复IE7之前的版本中半透明PNG图片的问题。在图片加载过程中,这个滤镜会阻塞渲染,卡住浏览器,还会增加内存消耗而且是被应用到每个元素的,而不是每个图片,所以会存在一大堆问题。
    最好的方法是干脆不要用AlphaImageLoader,而优雅地降级到用在IE中支持性很好的PNG8图片来代替。如果非要用AlphaImageLoader,应该用下划线hack:_filter来避免影响IE7及更高版本的用户。

    1.5 把样式表放在顶部

    把样式表放到文档的HEAD部分能让页面看起来加载地更快。这是因为把样式表放在head里能让页面逐步渲染。
      关注性能的前端工程师想让页面逐步渲染。也就是说,我们想让浏览器尽快显示已有内容,这在页面上有一大堆内容或者用户网速很慢时显得尤为重要。给用户显示反馈(比如进度指标)的重要性已经被广泛研究过,并且被记录下来了。在我们的例子中,HTML页面就是进度指标!当浏览器逐渐加载页面头部,导航条,顶部logo等等内容的时候,这些都被正在等待页面加载的用户当作反馈,能够提高整体用户体验。

    1.6 压缩 css

    • 使用在线网站进行压缩
    • 使用html-minifier 对html 中的css 进行压缩
    • 使用clean-css 对css进行压缩
    • webpack,gulp打包工具

    2 优化图片

    2.1 图片格式

    尝试把GIF格式转换成PNG格式,看看是否节省空间。在所有的PNG图片上运行pngcrush(或者其它PNG优化工具)

    2.2 优化CSS Sprite

    采用css雪碧图(css sprit/css 图片精灵)技术,吧一些小图合并在一张大图上面,使用的时候,通过北京图片定位,定位到具体的某一张小图上

    • 在Sprite图片中横向排列一般都比纵向排列的最终文件小
    • 组合Sprite图片中的相似颜色可以保持低色数,最理想的是256色以下PNG8格式
    • “对移动端友好”,不要在Sprite图片中留下太大的空隙。虽然不会在很大程度上影响图片文件的大小,但这样做可以节省用户代理把图片解压成像素映射时消耗的内存。100×100的图片是1万个像素,而1000×1000的图片就是100万个像素了。
    .pubBg{
    	background:url('../img/sprit.png') no-repeat;
      background-size:x y; // 和原图的大小保持一致
    }
    
    .box{
    	background-position:x y; // 通过背景定位,定位到具体的位置,展示不同的图片极客
    }
    复制代码

    页面中没法送一次http请求,都需要完成请求+响应这个完整的http事务,会消耗一些时间,也可能会导致http链接通道的堵塞,为了提高页面的加载速度和运行的性能,我们应该减少http的请求次数和减少请求内容的大小。

    2.3 图像映射

    可以把多张图片合并成单张图片,总大小是一样的,但减少了请求数并加速了页面加载。图片映射只有在图像在页面中连续的时候才有用,比如导航条。给image map设置坐标的过程既无聊又容易出错,用image map来做导航也不容易,所以不推荐用这种方式。

    2.4 行内图片(Base64编码)

    用data: URL模式来把图片嵌入页面。这样会增加HTML文件的大小,把行内图片放在(缓存的)样式表中是个好办法,而且成功避免了页面变“重”。但目前主流浏览器并不能很好地支持行内图片。
    减少页面的HTTP请求数是个起点,这是提升站点首次访问速度的重要指导原则。

    2.5 不要用HTML缩放图片

    不要因为在HTML中可以设置宽高而使用本不需要的大图。如果需要

    <img width="100" height="100" src="mycat.jpg" alt="My Cat" />
    复制代码

    那么图片本身(mycat.jpg)应该是100x100px的,而不是去缩小500x500px的图片。

    2.6 用小的可缓存的favicon.ico(P.S. 收藏夹图标)

    favicon.ico是放在服务器根目录的图片,它会带来一堆麻烦,因为即便你不管它,浏览器也会自动请求它,所以最好不要给一个404 Not Found响应。而且只要在同一个服务器上,每次请求它时都会发送cookie,此外这个图片还会干扰下载顺序,例如在IE中,当你在onload中请求额外组件时,将会先下载favicon。
    所以为了缓解favicon.ico的缺点,应该确保:

    • 足够小,最好在1K以下
    • 设置合适的有效期HTTP头(以后如果想换的话就不能重命名了),把有效期设置为几个月后一般比较安全,可以通过检查当前favicon.ico的最后修改日期来确保变更能让浏览器知道。

    2.7 压缩image

    • 使用雪花图
    • 使用矢量图
    • 使用base64转换
    • 使用网站压缩  
    • 合理使用格式图片
      • jpg有损压缩,压缩率搞,不支持透明
      • png支持透明,浏览器兼容好
      • webp压缩程度更好,在ios webview有兼容性问题
      • svg矢量图,代码内嵌,相对于较小,图片样式相对简单的场景

    在使用webp的过程中,会产生一些浏览器兼容问题

    function checkWebp() {
    
        try{
    
            return (document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0);
    
           }catch(err) {
    
            return false;
    
           }
    
    }
    
    
    
    $(document).ready(function() {
    
            var webp_good = checkWebp();
    
            if(webp_good == false) {
    
                $('img').each(function() {
    
                var src = $(this).attr('src');
    
                if(typeof src != 'undefined') {
    
                    src = src.replace('/format,webp', '/format,jpg'); //将webp格式转换成jpg格式
    
                    $(this).attr('src', src);
    
                }
    
                var original = $(this).attr('original');        //针对用了懒加载的情况
    
                if(typeof original != 'undefined') {
    
                    original = original.replace('/format,webp', '/format,jpg'); //将webp格式转换成jpg格式
    
                    $(this).attr('original', original);
    
                }
    
            })
    
        }
    
    })
    复制代码

    2.8 图片懒加载

    采用图片懒加载技术,在页面开始加载时候,不请求真实的图片地址,而是默认图占位,当页面加载完成后,在根据相关的条件依次加载真实的图片(减少页面首次加载http请求的次数)
    真实项目中,我们开始图片都不加载,页面首次加载完成,先把第一屏幕中看见的图片进行加载,随着页面的滚动,在下面区域中能够呈现出来的图片进行加载

    • 根据图片懒加载技术,我们还可以扩充出,数据懒加载

    开始加载页面的时候,我们只把首屏或者前两屏的数据从服务器进行请求(有些网站首屏数据是后台渲染好,整体返回给客户端呈现的)

    • 当页面下拉,滚动到哪个区域,在把这个区域需要的数据进行请求(请求回来数据绑定以及图片延迟加载等)
    • 分页展示技术采用的也是数据懒加载思想实现的:如果我们开始请求获取的数据是很多的数据,我们最好分批请求,开始只请求第一页的数据,当页面点击第二页(微博是下拉到一定距离后,再请求第二页数据)的时候请求第二页数据。

    3 优化js

    3.1 去除重复脚本

    页面含有重复的脚本文件会影响性能,这可能和你想象的不一样。在对美国前10大web站点的评审中,发现只有2个站点含有重复脚本。两个主要原因增加了在单一页面中出现重复脚本的几率:团队大小和脚本数量。在这种情况下,重复脚本会创建不必要的HTTP请求,执行无用的JavaScript代码,而影响页面性能。
      IE会产生不必要的HTTP请求,而Firefox不会。在IE中,如果一个不可缓存的外部脚本被页面引入了两次,它会在页面加载时产生两个HTTP请求。即使脚本是可缓存的,在用户重新加载页面时也会产生额外的HTTP请求。
      除了产生没有意义的HTTP请求之外,多次对脚本求值也会浪费时间。因为无论脚本是否可缓存,在Firefox和IE中都会执行冗余的JavaScript代码。
      避免不小心把相同脚本引入两次的一种方法就是在模版系统中实现脚本管理模块。典型的脚本引入方法就是在HTML页面中用SCRIPT标签:

    <script type="text/javascript" src="menu_1.0.17.js"></script>
    复制代码

    3.2 尽量减少DOM访问

    一个复杂的页面意味着要下载更多的字节,而且用JavaScript访问DOM也会更慢。举个例子,想要添加一个事件处理器的时候,循环遍历页面上的500个DOM元素和5000个DOM元素是有区别的。
    操作dom的弊端

    • dom存在映射在机制(js中的dom元素对象和页面中dom结构是存在映射机制的,一改则都改),这种映射机制,是浏览器安卓w3c标准完成对js语言的构建和dom的构建(其实就是构建一个监听机制),操作dom是同事修改两个地址,相对于一些其他的js编程来说消耗性能的。
    • 页面中的dom结构改变或者样式改变,会触发浏览器的回流(浏览器会把dom结构重新进行计算,这个操作很耗性能)和重绘(吧一个元素的样式重新渲染)

    在做dom事件绑定的时候,尽量避免一个个的事件绑定,二采用性能更高的事件委托来实现

    事件委托(事件代理) 把时间板顶给外层容器,当里面的后代元素相关行为被处罚,外层容器绑定的方法也会被触发执行(冒泡传播机制导致),通过的事件源是谁,我们做不同的操作即可


    用JavaScript访问DOM元素是很慢的,所以,为了让页面反应更迅速,应该:

    • 缓存已访问过的元素的索引
    • 先“离线”更新节点,再把它们添到DOM树上
    • 避免用JavaScript修复布局问题


    DOM元素的数量很容易测试,只需要在控制台里输入

    document.getElementsByTagName('*').length
    复制代码

    3.3 用智能的事件处理器

     有时候感觉页面反映不够灵敏,是因为有太多频繁执行的事件处理器被添加到了DOM树的不同元素上,这就是推荐使用事件委托的原因。如果一个div里面有10个按钮,应该只给div容器添加一个事件处理器,而不是给每个按钮都添加一个。事件能够冒泡,所以可以捕获事件并得知哪个按钮是事件源。

    3.4 更多异步操作编译

    • 同步编程会导致:上面东西完不成,下面任务也做不了,我们开发的时候,可以把某一个区域模块都设置为异步编程,这样只要模块之间没有必然的先后顺序,都可以独立进行加载,不会受到上面模块的堵塞影响(用的不多)
    • 尤其是ajax数据请求,我们一般都要使用异步编程,最好是基于promise设计模式进行管理(项目中经常使用fetch、vue、axios)等插件进行ajax请求处理,因为这些插件中就是基于promise设计模式对ajax进行了封装处理
    • 在真实的项目中,我们尽可能避免一次性循环过多数据(因为循环操作是同步编程),尤其是要避免while导致的死循环操作

    3.5 JS中避免使用eval

    • 性能消耗大
    • 代码压缩后,容易出现代码执行错乱问题

    3.6 JS中尽量减少闭包的使用

    • 闭包会形成一个不销毁的栈内存,过多的栈内存累积影响页面的性能
    • 还会容易导致内存的泄露
    • 闭包也有自己的优势:保存和保护,我们只能尽量减少,但是无法避免

    3.7 尽量使用css3动替代js动画

    css3的动画或者变形都开启了硬件加速,性能比js动画好

    3.8 缓存做处理

    对于不经常更新的数据,最好采用浏览器的304缓存做处理
    例如:
    第一次请求css和js下拉,浏览器会把请求的内容缓存起来,如果做了304处理,用户再次请求css和js直接从缓存中读取,不需要再去服务器获取了(减少了http请求次数)
    当用户强制刷新页面(ctrl+f5)或者当前缓存的css或者js发生了变动,都会从新从服务器端拉取
    对于客户端来讲,我们还可以基于localStronge来做一些本地存储,例如:第一次请求的数据或者不经常更新的css和js,我们都可以吧内容存储在本地,下一次页面加载,我们从本地中获取即可,我们设定一定的期限或者一些标识,可以控制在某个阶段重新从服务器获取

    3.9 设计模式

    编写js代码的时候尽可能使用设计模式来构建体系,方便后期的维护,也提高了扩充性等

    3.10 把脚本放在底部

    脚本会阻塞并行下载,HTTP/1.1官方文档建议浏览器每个主机名下并行下载的组件数不要超过两个,如果图片来自多个主机名,并行下载的数量就可以超过两个。如果脚本正在下载,浏览器就不开始任何其它下载任务,即使是在不同主机名下的。
      有时候,并不容易把脚本移动到底部。举个例子,如果脚本是用document.write插入到页面内容中的,就没办法再往下移了。还可能存在作用域问题,在多数情况下,这些问题都是可以解决的。
      一个常见的建议是用推迟(deferred)脚本,有DEFER属性的脚本意味着不能含有document.write,并且提示浏览器告诉他们可以继续渲染。不幸的是,Firefox不支持DEFER属性。在IE中,脚本可能被推迟,但不尽如人意。如果脚本可以推迟,我们就可以把它放到页面底部,页面就可以更快地载入。

    3.11 压缩js

    • 使用在线网站进行压缩
    • 使用html-minifier 对html 中的css 进行压缩
    • 使用uglifjs2对js进行压缩
    • webpack,gulp打包工具

    4 优化html

    4.1 audio或者video标签

    如果当页面中出现audio或者video标签,我们最好设置它们的preload=:页面加载的时候,音视频资源不进行加载,播放的时候再开始加载(减少页面首次加载http请求的次数)

    • preload=auto 页面首次加载的时候就把音频资源进行加载
    • preload=metadata 页面首次加载的时候只能音视资源的头部信息进行加载

    4.2 尽量少用iframe

      用iframe可以把一个HTML文档插入到父文档里,重要的是明白iframe是如何工作的并高效地使用它。
    <iframe>的优点:

    • 引入缓慢的第三方内容,比如标志和广告
    • 安全沙箱
    • 并行下载脚本

    <iframe>的缺点:

    • 代价高昂,即使是空白的iframe
    • 阻塞页面加载
    • 非语义

    4.3 杜绝404

      HTTP请求代价高昂,完全没有必要用一个HTTP请求去获取一个无用的响应(比如404 Not Found),只会拖慢用户体验而没有任何好处。
      有些站点用的是有帮助的404——“你的意思是xxx?”,这样做有利于用户体验,,但也浪费了服务器资源(比如数据库等等)。最糟糕的是链接到的外部JavaScript有错误而且结果是404。首先,这种下载将阻塞并行下载。其次,浏览器会试图解析404响应体,因为它是JavaScript代码,需要找出其中可用的部分。

    5 移动端

    5.1 保证所有组件都小于25K

    这个限制是因为iPhone不能缓存大于25K的组件,注意这里指的是未压缩的大小。这就是为什么缩减内容本身也很重要,因为单纯的gzip可能不够。

    5.2 把组件打包到一个复合文档里

    把各个组件打包成一个像有附件的电子邮件一样的复合文档里,可以用一个HTTP请求获取多个组件(记住一点:HTTP请求是代价高昂的)。用这种方式的时候,要先检查用户代理是否支持(iPhone就不支持)。

    6 cookie

    6.1 给Cookie减肥

    使用cookie的原因有很多,比如授权和个性化。HTTP头中cookie信息在web服务器和浏览器之间交换。重要的是保证cookie尽可能的小,以最小化对用户响应时间的影响。

    • 清除不必要的cookie
    • 保证cookie尽可能小,以最小化对用户响应时间的影响
    • 注意给cookie设置合适的域级别,以免影响其它子域
    • 设置合适的有效期,更早的有效期或者none可以更快的删除cookie,提高用户响应时间

    6.2 把组件放在不含cookie的域下

    当浏览器发送对静态图像的请求时,cookie也会一起发送,而服务器根本不需要这些cookie。所以它们只会造成没有意义的网络通信量,应该确保对静态组件的请求不含cookie。可以创建一个子域,把所有的静态组件都部署在那儿。
    如果域名是www.example.org,可以把静态组件部署到static.example.org。然而,如果已经在顶级域example.org或者www.example.org设置了cookie,那么所有对static.example.org的请求都会含有这些cookie。这时候可以再买一个新域名,把所有的静态组件部署上去,并保持这个新域名不含cookie。Yahoo!用的是yimg.com,YouTube是ytimg.com,Amazon是images-amazon.com等等。
     把静态组件部署在不含cookie的域下还有一个好处是有些代理可能会拒绝缓存带cookie的组件。有一点需要注意:如果不知道应该用example.org还是www.example.org作为主页,可以考虑一下cookie的影响。省略www的话,就只能把cookie写到*.example.org,所以因为性能原因最好用www子域,并且把cookie写到这个子域下。

    7 服务器

    7.1 Gzip组件

      前端工程师可以想办法明显地缩短通过网络传输HTTP请求和响应的时间。毫无疑问,终端用户的带宽速度,网络服务商,对等交换点的距离等等,都是开发团队所无法控制的。但还有别的能够影响响应时间的因素,压缩可以通过减少HTTP响应的大小来缩短响应时间。
    从HTTP/1.1开始,web客户端就有了支持压缩的Accept-Encoding HTTP请求头。

      如果web服务器看到这个请求头,它就会用客户端列出的一种方式来压缩响应。web服务器通过Content-Encoding相应头来通知客户端。

      尽可能多地用gzip压缩能够给页面减肥,这也是提升用户体验最简单的方法。
     
     

    7.2 避免图片src属性为空

    Image with empty string src属性是空字符串的图片很常见,主要以两种形式出现:

    1. straight HTML

    2. JavaScript

    3. var img = new Image(); img.src = “”;

    这两种形式都会引起相同的问题:浏览器会向服务器发送另一个请求。

    7.3 配置ETags

      实体标签(ETags),是服务器和浏览器用来决定浏览器缓存中组件与源服务器中的组件是否匹配的一种机制(“实体”也就是组件:图片,脚本,样式表等等)。添加ETags可以提供一种实体验证机制,比最后修改日期更加灵活。一个ETag是一个字符串,作为一个组件某一具体版本的唯一标识符。唯一的格式约束是字符串必须用引号括起来,源服务器用相应头中的ETag来指定组件的ETag:

      然后,如果浏览器必须验证一个组件,它用If-None-Match请求头来把ETag传回源服务器。如果ETags匹配成功,会返回一个304状态码,这样就减少了12195个字节的响应体。
    GET /i/yahoo.gif HTTP/1.1
          Host: us.yimg.com
          If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
          If-None-Match: "10c24bc-4ab-457e1c1f"
          HTTP/1.1 304 Not Modified

    ** **

    7.4 对Ajax用GET请求

      邮箱团队发现使用XMLHttpRequest时,浏览器的POST请求是通过一个两步的过程来实现的:先发送HTTP头,在发送数据。所以最好用GET请求,它只需要发送一个TCP报文(除非cookie特别多)。IE的URL长度最大值是2K,所以如果要发送的数据超过2K就无法使用GET了。
    POST请求的一个有趣的副作用是实际上没有发送任何数据,就像GET请求一样。正如HTTP说明文档中描述的,GET请求是用来检索信息的。所以它的语义只是用GET请求来请求数据,而不是用来发送需要存储到服务器的数据。
     
     

    7.5 尽早清空缓冲区

     当用户请求一个页面时,服务器需要用大约200到500毫秒来组装HTML页面,在这期间,浏览器闲等着数据到达。PHP中有一个flush()函数,允许给浏览器发送一部分已经准备完毕的HTML响应,以便浏览器可以在后台准备剩余部分的同时开始获取组件,好处主要体现在很忙的后台或者很“轻”的前端页面上(P.S. 也就是说,响应时耗主要在后台方面时最能体现优势)。
      较理想的清空缓冲区的位置是HEAD后面,因为HTML的HEAD部分通常更容易生成,并且允许引入任何CSS和JavaScript文件,这样就可以让浏览器在后台还在处理的时候就开始并行获取组件。
    例如:

    &emsp;<br />... <!-- css, js --><br />    </head><br />    <?php flush(); ?><br />    <body><br />      ... <!-- content --><br /> 
    复制代码

    7.6 使用CDN(内容分发网络)

      用户与服务器的物理距离对响应时间也有影响。把内容部署在多个地理位置分散的服务器上能让用户更快地载入页面。但具体要怎么做呢?
      实现内容在地理位置上分散的第一步是:不要尝试去重新设计你的web应用程序来适应分布式结构。这取决于应用程序,改变结构可能包括一些让人望而生畏的任务,比如同步会话状态和跨服务器复制数据库事务(翻译可能不准确)。缩短用户和内容之间距离的提议可能被推迟,或者根本不可能通过,就是因为这个难题。
      记住终端用户80%到90%的响应时间都花在下载页面组件上了:图片,样式,脚本,Flash等等,这是业绩黄金法则。最好先分散静态内容,而不是一开始就重新设计应用程序结构。这不仅能够大大减少响应时间,还更容易表现出CDN的功劳。
      内容分发网络(CDN)是一组分散在不同地理位置的web服务器,用来给用户更高效地发送内容。典型地,选择用来发送内容的服务器是基于网络距离的衡量标准的。例如:选跳数(hop)最少的或者响应时间最快的服务器。
     

    7.7 添上Expires或者Cache-Control HTTP头

    这条规则有两个方面:

    • 对于静态组件:通过设置一个遥远的将来时间作为Expires来实现永不失效
    • 多余动态组件:用合适的Cache-ControlHTTP头来让浏览器进行条件性的请求

      网页设计越来越丰富,这意味着页面里有更多的脚本,图片和Flash。站点的新访客可能还是不得不提交几个HTTP请求,但通过使用有效期能让组件变得可缓存,这避免了在接下来的浏览过程中不必要的HTTP请求。有效期HTTP头通常被用在图片上,但它们应该用在所有组件上,包括脚本、样式和Flash组件。
      浏览器(和代理)用缓存来减少HTTP请求的数目和大小,让页面能够更快加载。web服务器通过有效期HTTP响应头来告诉客户端,页面的各个组件应该被缓存多久。用一个遥远的将来时间做有效期,告诉浏览器这个响应在2010年4月15日前不会改变。


    如果你用的是Apache服务器,用ExpiresDefault指令来设置相对于当前日期的有效期。下面的例子设置了从请求时间起10年的有效期:
    ExpiresDefault "access plus 10 years"
     
     
     

    7.8 减少dns查询

    域名系统建立了主机名和IP地址间的映射,就像电话簿上人名和号码的映射一样。当你在浏览器输入www.shanghai70.com的时候,浏览器就会联系DNS解析器返回服务器的IP地址。DNS是有成本的,它需要20到120毫秒去查找给定主机名的IP地址。在DNS查找完成之前,浏览器无法从主机名下载任何东西。
      DNS查找被缓存起来更高效,由用户的ISP(网络服务提供商)或者本地网络存在一个特殊的缓存服务器上,但还可以缓存在个人用户的计算机上。DNS信息被保存在操作系统的DNS cache(微软Windows上的”DNS客户端服务”)里。大多数浏览器有独立于操作系统的自己的cache。只要浏览器在自己的cache里还保留着这条记录,它就不会向操作系统查询DNS。
      IE默认缓存DNS查找30分钟,写在DnsCacheTimeout注册表设置中。Firefox缓存1分钟,可以用network.dnsCacheExpiration配置项设置。(Fasterfox把缓存时间改成了1小时 P.S. Fasterfox是FF的一个提速插件)
      如果客户端的DNS cache是空的(包括浏览器的和操作系统的),DNS查找数等于页面上不同的主机名数,包括页面URL,图片,脚本文件,样式表,Flash对象等等组件中的主机名,减少不同的主机名就可以减少DNS查找。
      减少不同主机名的数量同时也减少了页面能够并行下载的组件数量,避免DNS查找削减了响应时间,而减少并行下载数量却增加了响应时间。我的原则是把组件分散在2到4个主机名下,这是同时减少DNS查找和允许高并发下载的折中方案。

    7.9 避免重定向

    重定向用301和302状态码,下面是一个有301状态码的HTTP头

    HTTP/1.1 301 Moved Permanently       Location: example.com/newuri       Content-Type: text/html

    浏览器会自动跳转到Location域指明的URL。重定向需要的所有信息都在HTTP头部,而响应体一般是空的。其实额外的HTTP头,比如ExpiresCache-Control也表示重定向。除此之外还有别的跳转方式:refresh元标签和JavaScript,但如果你必须得做重定向,最好用标准的3xxHTTP状态码,主要是为了让返回按钮能正常使用。
      牢记重定向会拖慢用户体验,在用户和HTML文档之间插入重定向会延迟页面上的所有东西,页面无法渲染,组件也无法开始下载,直到HTML文档被送达浏览器。
      有一种常见的极其浪费资源的重定向,而且web开发人员一般都意识不到这一点,就是URL尾部缺少一个斜线的时候。例如,跳转到www.shanghai70.com/a会返回一个重定向到www.shanghai70.com/b的301响应(注意添在尾部的斜线)。在Apache中可以用Aliasmod_rewrite或者DirectorySlash指令来取消不必要的重定向。
      重定向最常见的用途是把旧站点连接到新的站点,还可以连接同一站点的不同部分,针对用户的不同情况(浏览器类型,用户帐号类型等等)做一些处理。用重定向来连接两个网站是最简单的,只需要少量的额外代码。虽然在这些时候使用重定向减少了开发人员的开发复杂度,但降低了用户体验。一种替代方案是用Aliasmod_rewrite,前提是两个代码路径都在相同的服务器上。如果是因为域名变化而使用了重定向,就可以创建一条CNAME(创建一个指向另一个域名的DNS记录作为别名)结合Alias或者mod_rewrite指令。

    7.10 Json格式传输

    在客户端和服务器端进行数据通信的时候,我们尽量采用json格式进行数据传输

    • json格式的数据,能够清晰明了的展示出数据结构,而且也方便我们获取的操作
    • 相对于很早以前的xml格式传输,json格式的数据更加轻量级
    • 客户端和服务器端都支持json格式数据的处理,处理起来非常的方便

    真实项目中:并不是所有的数据都基于json,我们尽可能这样做,但是对于某些特殊的需求(例如文件流的传输或者文档传输),使用json就不合适了

    转载于:https://juejin.im/post/5cab0fb5f265da251d4b8945

    展开全文
  • 最全前端优化方案

    2020-12-19 16:30:33
    最全前端优化方案笔记
  • 前端优化之webpack

    千次阅读 2020-02-20 17:09:51
    由于前端的快速发展,相关工具的发展速度也是相当迅猛,各大框架例如vue,react都有自己优秀的脚手架工具来帮助我们快速启动一个新项目,也正式因为这个原因,我们对于脚手架中最关键的一环webpack相关的优化知之甚少...

    由于前端的快速发展,相关工具的发展速度也是相当迅猛,各大框架例如vue,react都有自己优秀的脚手架工具来帮助我们快速启动一个新项目,也正式因为这个原因,我们对于脚手架中最关键的一环webpack相关的优化知之甚少,脚手架基本上已经为我们做好了相关的开发准备,但是当我们想要做一些定制化的优化操作时,对webpack的优化也需要有一定的了解,否则无从下手,接下来就让我们进入webpack的优化世界

    构建速度提升

    loader提升

    loader是webpack中最重要的特性,由于webpack自身只支持JavaScript,因此需要一系列的loader来处理那些非JavaScript模块,因此在我们用webpack建项目的时候一定会使用一系列的loader,例如:vue-loader、sass-loader、babel-loader等等,就以babel-loader为例,来看具体配置:
    在这里插入图片描述
    对于loader来说最常用的就是exclude属性,用来避免不必要的转译,上面通过exclude来避免对node_modules中js中进行转译来提升构建速度,但是这样带来的提升效果有限。

    cacheDirectory是对babel-loader的转译结果进行缓存,之后的webpack进行构建时,都会去尝试读取缓存来避免高耗能的babel重新转译过程,cacheDirectory可以指定一个缓存目录或者指定为true,为true时将使用默认的缓存目录node_modules/.cache/babel-loader。

    babel对一些公共方法使用了非常小的辅助代码,默认会注入到每一个需要的文件,这样就造成重复引入,这时候就需要像上面那样引入transform-runtime来告诉babel引入runtime来代替注入
    第三方库优化

    externals

    externals提高构建速度的方法就是在构建时不会将指定的依赖包打包到bundle中,而是在运行时再从外部获取依赖,具体是怎么用的呢?来看个例子:
    在这里插入图片描述
    上面的例子的将vue全家桶都配置在externals中,然后将压缩包合成一个js文件放在cdn上面,这样就不会在构建时将文件打包到bundle中,提升打包速度,同时cdn又可以做缓存,提高访问速度

    DllPlugin

    DllPlugin是用来干什么的呢?DllPlugin会将第三方包到一个单独文件,并且生成一个映射的json文件,打包的生成的文件就是一个依赖库,这个依赖不会随着你的业务代码改变而被重新打包,只有当它自身依赖的包发生变化时才会需要重新打包依赖库,接下来来看具体配置吧:

    在这里插入图片描述
    首先我们需要一个如上面例子那样的dll配置文件,然后编译这个配置文件,生成一个vendor.js和一个映射文件vendor-manifest.json,然后再在我们的webpack配置文件中对进行配置:

    在这里插入图片描述
    happypack

    happypack这是个什么呢?我们都知道webpack是个单线程处理任务的,当又多个任务需要处理的时候,需要排队,那happypack就是用多线程来处理任务,通过并发处理来提高任务处理速度,那么这个需要怎么配置呢?来看具体例子:
    在这里插入图片描述
    减小构建体积

    按需加载(import)

    这里的import是指webpack中的动态加载,它的语法和ES6中的动态加载语法一摸一样,这是官方推荐的按需加载的方式,还是上面tree shaking的例子,我们只想引入plus方法,我们来看具体怎么使用:
    在这里插入图片描述

    我们只需要将入口文件改成上面的形式,其他的都不要变就可以实现按需引入,是不是很简单呢?在vue中路由的按需加载也可以这么用,来看一个简单的例子:
    在这里插入图片描述
    传入一个名字,动态引入对应目录的下的视图文件,这只是一个简单的例子,具体的使用形式还是依据具体的场景

    展开全文
  • [前端优化]基于H5移动端优化总结

    千次阅读 多人点赞 2019-04-27 22:49:00
    一个webAPP 写完了,并不代表就结束了,优化过程非常重要,手机端的软件往往追求的体验和性能。 1)减少js加载体积 很多库能用CDN的尽量使用CDN,这样打包出来的js体积会很小,加载很快。 2)尽量采用比较轻量级的UI ...
  • 做web开发的朋友都应该掌握前端优化这个技巧,其中一个就是滚动延时加载。这个技巧应用在了很多地方,比如新浪微博网页版。以下就为大家详细介绍,需要的朋友可以参考下
  • 前端优化:9 个技巧,提高 Web 性能

    千次阅读 2016-12-16 10:03:15
    虽然许多 CDN 服务可以压缩文件,但如果不使用 CDN,您也可以考虑在源服务器上使用文件压缩方法来改进前端优化。 文件压缩能使网站的内容轻量化,更易于管理。 最常用的文件压缩方法之一是 Gzip。 这是缩小文档、...
  • 前端的面试题总结,很多知识点都在这了。挺全的,准备面试的时候可以看看
  • 讲述可以帮助 改善优化前端的技术,非常有用。主要内容有清理代码、压缩图片、压缩外部资源、使用CDN,以及一些其它方法。这些方法会为你的网站带显著的速度提升和整体性能提升。下面跟着小编一起来看下吧
  • 前端优化合集

    2018-07-12 16:10:54
    前端JavaScript使用规范,以及开发vue.js时的一些使用技巧
  • 前端优化之DNS预解析

    千次阅读 2018-07-09 22:31:39
    前端优化系列之一:DNS预获取 dns-prefetch 提升页面载入速度DNS Prefetch,即DNS预获取,是前端优化的一部分。一般来说,在前端优化中与 DNS 有关的有两点: 一个是减少DNS的请求次数,另一个就是进行DNS预获取 ...
  • 1.1 编写符合当代浏览器性能的代码如果想提高前端性能,就必须理解浏览器的工作原理,哪怕是个大概,这样才能知道性能瓶颈在哪里以及如何优化。下图展示了Webkit浏览器从代码(HTML+CSS)到用户最终看到页面的处理...
  • 前端优化之资源压缩

    2018-08-05 21:45:03
    请求过程中一些潜在的性能优化点 dns是否可以通过缓存减少dns查询时间? 网络请求的过程走最近的网络环境? 相同的静态资源是否可以缓存? 能否减少请求http请求大小? 减少http请求 服务端渲染 0x2 资源的...
  • 前端优化14个性能规则鹌 2011年4月07日 浏览速度是网站最关键指标之一 用户从输入网站到看到页面显示出来,受很 多因素的影响 1:用户网速 2:服务器所在线路 3:DNS解析 4:服务器负载 5:服务器端运行速度(JAVA) 6:前端...
  • 前端优化之if...else判断

    千次阅读 2019-11-06 11:44:28
    前端,我们大多习惯使用if…else if…else来进行判断,但是这样做代码不美观,而且可读性低且性能差,于是写了这么一篇博客。 关于if…else的优化优化前的代码: function daxiao(number) { var n =Math.floor...
  • Yahoo的WEB前端优化34条原则。大型web开发必备的技术知识。很不错哦
  • 前文 之前一年多前接手的一个react项目,前段时间因为做业务中台项目,对公司现有的应用项目做中台化改造,这期间将项目部署到uat环境,测试期间,测试小妹妹和产品大叔都吐槽进入uat项目的时候要load很久,白屏时间...
  • 乾坤微前端优化(一)

    千次阅读 2020-09-08 10:07:33
    前提 1. 同一个技术,都是react,或者都是vue。 2. 会webpack的dll配置。 ...发现各个应用之间,第三方的包都是很多的,假如我们在主应用把这些包抽取出来,后面子应用引入,可以极大地减少子应用包的大小。...
  • 前端优化(一):开启nginx gzip压缩

    千次阅读 2019-07-19 11:52:58
    来和我一起开启前端优化之路吧! 我着重从几个方面入手整理: 整理项目,清除冗余文件。 卸载未用到的npm包。 去除未用到的文件。 抽取公用组件和方法,去掉重复的代码。 抽取第三方js 使用tinypng压缩图片 使用...
  • Web 前端优化最佳实践.rar

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 270,048
精华内容 108,019
关键字:

前端优化