资讯专栏INFORMATION COLUMN

WEB前端性能优化

raoyi / 2036人阅读

摘要:页面渲染初始化盒子模型相关属性变化窗口事件触发结构变化,比如删除了某个节点获取某些属性,引发回流很多浏览器会对回流做优化,他会等到足够数量的变化发生,在做一次批处理回流。使用框架出现了首屏性能渲染问题。

请求过程中一些潜在的性能优化点

深入理解http请求的过程是前端性能优化的核心!

dns是否可以通过缓存减少dns查询时间?

网络请求的过程走最近的网络环境?

相同的静态资源是否可以缓存?

能否减少请求http请求大小?

减少http请求数量

服务端渲染

DNS解析过程

服务器端请求处理

HTTP状态码

注意:

1、文件合并存在的问题。

首屏渲染问题(公共库合并)

缓存失效问题(不同页面的合并)

2、资源的合并与压缩(html,css,js压缩和混乱,文件合并,开启gzip)。

目的1:减少请求http请求大小

目的2:减少http请求数量

图片相关的优化的核心概念

png8/png24/png32之间的区别?

png8 --- 2^8(256)色 + 支持透明

png24 --- 2^24色 + 不支持透明

png32 --- 2^24色 + 支持透明

不同格式图片的特点和常用的业务场景?

jpg有损压缩,压缩率高,不支持透明(不需要透明图片的的业务场景)

png支持透明,浏览器兼容性好(需要透明图片的业务场景)

webp压缩程度更好,在ios webview中有兼容性问题(安卓全部)

svg矢量图,代码内嵌,相对较小(图片样式相对简单的场景)

对图片的优化有哪些?

对图片进行压缩png24->png8(可以使用:https://tinypng.com/)

CSS雪碧图(可以使用用这个网站生成雪碧图相关的css代码:http://www.spritecow.com)

Image inline(base64编码)

使用矢量图

css、js加载与执行(考虑优化点)

HTMLParser解析器自上而下解析,生成DOM树。
外部资源link、script,浏览器会发起请求。
解析CSS生成CSS规则树,进而构建渲染树(计算element位置,布局layout)。
接着调用操作系统NativeGUI的API进行绘制。

浏览器渲染页面

HTML渲染过程的一些特点

顺序执行、并发加载

外部资源并发请求,一个域名下的并发请求数是有上限的。
所以一般将网站的静态资源托管在多个CDN下。

css阻塞

css在head中可以阻塞页面渲染、css可以阻塞js执行,但是css不阻塞外部脚本的加载。

js阻塞

直接引入的js阻塞页面的渲染(asyn[异步下载、立即执行]、differ[并行下载、顺序执行]这两种方式加载js例外)

js不阻塞资源的加载(预资源加载器)

js顺序执行,阻塞后续js逻辑的执行(单线程)

懒加载、预加载

懒加载:图片进入可视区域之后请求图片资源。
懒加载的实现:
1.JS判断图片是否进入可视区域。
2.当进入时,修改img的src属性为实际图片地址。

预加载:图片等静态资源在使用之前提前请求。
预加载实现:
1.使用标签(
2.使用Image对象(new Image();)
3.使用XMLHTTPRequest对象(资源跨域问题)

回流与重绘

UI线程和js线程互斥。
css性能能让JavaScript变慢。
频繁触发重绘回流,会导致UI频繁渲染,最终导致js变慢。

回流: render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,
这就称为回流(reflow)。

页面渲染初始化

盒子模型相关属性变化

窗口resize事件触发

DOM结构变化,比如删除了某个节点

获取某些属性,引发回流 很多浏览器会对回流做优化,他会等到足够数量的变化发生,在做一次批处理回流。 但是除了render树的直接变化。

获取以下属性时会引发回流
width,height
offsetTop/Left/Width/Height
scrollTop/Left/Width/Height
clientTop/Left/Width/Height
调用了getComputedStyle(), 或者 IE的 currentStyle

重绘: render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会
影响布局的,比如background-color,这就称为重绘。

Chrome中满足以下任意情况就会创建图层:

video、canvas都是一个独立的图层。

3D或透视变换(perspective transform)CSS属性

使用加速视频解码的

拥有3D(WebGL)上下文或加速的2D上下文的节点

混合插件(如Flash)

对自己的opacity做CSS动画或使用一个动画webkit变换的元素

拥有加速CSS过滤器的元素

元素有一个包含复合层的后代节点(一个元素拥有一个子元素,该子元素在自己的层里)

元素有一个z-index较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)

常用的会独立为一个图层的属性:
transform:translateZ(0);
will-change:transform;

怎么优化呢?

将频繁重绘回流的DOM元素多带带作为一个独立图层,那么这个DOM元素重绘和回流的影响只会在这个图层中。(但是:浏览器图层合成也会花比较多的时间,所以,是否新建图层得看实际情况,具体问题,具体分析。)

translate(改变不会触发浏览器重新布局,但是元素仍会占据原始位置)替代top(会触发重新布局)改变。

opacity(不会触发重绘)替代visibility(会触发重绘)。

不要一条一条地修改DOM的样式,预先定义好class,然后修改DOM的className

把DOM离线后修改。(eg:先把DOM给display:none,然后修改100次,再把它显示出来。)

不要把DOM节点的属性值放在一个循环里当成循环里的变量(offsetHeight、offsetWidth)

不要使用table布局,一个小的改动会造成整个table的重新布局。

对动画新建图层。

启用GPU硬件加速。(transform:translate3d(0,0,0)、transform:translateZ(0))

浏览器存储 Cookie相关

Cookie 因为HTTP请求无状态,所以需要cookie去维护客户端状态。

cookie的生成方式:

1.http response header中的 set-cookie(服务端生成,客户端保存)

2.js中可以通过document.cookie可以读写cookie(客户端自身数据的存储)

cookie存储的限制:

1.作为浏览器端存储,大小4kb左右

2.需要设置过期时间`expire

对于cookie的优化:

cookie中在相关域名下面--cdn的流量损耗
解决方法:__ cdn的域名和主站的域名要分开 __

对于cookie的读写操作:

// 写入
document.cookie = "username=hello";
// 读取
let cookie = document.cookie;
/**
  * param [String] cookie
  * return [Object] object
  */
function getCookie(cookie){
    if(!cookie){ return null; }
    let reg = /s*([^;]+)s*=s*([^;]+)s*/g;
    let obj = {};
    cookie.replace(reg,($0,$1,$2) => {
        if($1&&$2){
            obj[$1] = $2;
        }
    });
    return obj;
}

cookie存储数据能力被localstorage替代。
httponly :不允许js读写。(防止盗用cookie)

LocalStorage相关

HTML5设计出来专门用于浏览器存储的

大小为5M左右

仅在客户端使用,不和服务器进行通信

接口封装较好

浏览器本地缓存方案

对于LocalStorage的读写操作:

// 写入
localStorage.setItem("username","hello")
undefined
// 读取
localStorage.getItem("username")
"hello"
SessionStorage相关

会话级别的浏览器存储

大小为5M左右

仅在客户端使用,不和服务器进行通信

接口封装较好

对于表单信息的维护(多页表单数据的维护)

对于 SessionStorage的读写操作:

// 写入
 SessionStorage.setItem("username","hello")
undefined
// 读取
 SessionStorage.getItem("username")
"hello"
IndexedDB(用的比较少)

IndexedDB是一种低级API,用于客户端存储大量结构化数据。

为应用创建离线版本

PWA相关

可靠:在没有网络的环境下也能提供基本的页面访问,而不会出现“未连接到互联网”的页面。

快速:针对网页渲染及网络数据访问有较好优化。

融入(Engaging):应用可以被增加到手机桌面,并且和普通应用一样有全屏、推送等特性。

具体内容查看笔记:

ServiceWorker探索
ServiceWorker和cacheStorage缓存及离线开发

利用ServiceWorker进行多页面通信:

// 主页面发送信息
navigator.serviceWorker.controller.postMessage(value);
// 主页面监听消息
navigator.serviceWorker.addEventListener("message",event => {
    // console.log(event.data);
});

// ServiceWorker接收信息(对其他页面消息分发)
self.addEventListener("message",event => {
    let promise = self.clients.matchAll().then(clientList => {
        let senderID = event.source ? event.source : "unknown";
        clientList.forEach(client => {
            if(client.id === senderID){
                return;
            }
            client.postMessage({
                client: senderID,
                message: event.data
            });
        });
    });
    event.waitUntil(promise);    
});
浏览器缓存 Cache-Control

max-age 当小于缓存时间时,直接加载本地资源(from memory cache),expires(到期时间http/1.0)和max-age相比,max-age具有更高的优先级。

s-maxage 共享缓存,public相关的缓存设备例如CDN,优先级高于max-age,如果客户端访问到的是CDN服务器缓存中的数据切未更改则返回304状态码。(Cache-control:max-age=3600, s-maxage=31536000,就算在max-age时间内,也不直接加载本地文件,而是访问CDN缓存。缓存中的文件如果没有更改,则直接通知客户端304,加载本地文件。感觉和no-cache很像呀)

no-cache (例如:Cache-Control:private, max-age=0, no-cache),不是不缓存的意思,它实际上的机制是,仍然对资源使用缓存,但每一次在使用缓存之前必须(MUST)向服务器对缓存资源进行验证。

no-store 对该文件不适用任何缓存策略。

public 资源将被客户端和代理服务器缓存。

private 资源仅被客户端缓存,代理服务器不缓存。

public VS private 要知道从服务器到浏览器之间并非只有浏览器能够对资源进行缓存,服务器的返回可能会经过一些中间(intermediate)服务器甚至甚至专业的中间缓存服务器,还有CDN。而有些请求返回是用户级别、是私人的,所以你可能不希望这些中间服务器缓存返回。此时你需要将Cache-Control设置为private以避免暴露。

Expires

Expires是http/1.0中定义的浏览器缓存策略。(expires: Wed, 24 Jan 2018 12:19:34 GMT

用来指定资源到期的时间,是服务器端的具体的时间点。

告诉浏览器在过期时间前可以直接从缓存取数据,而无需再次请求。

Last-Modified/If-Modified-Since

基于客户端和服务端协商的缓存机制

last-modified —— response header

if-modified-since —— request header

需要与cache-control共同使用

但是last-modified是有缺点的。

1.某些服务器不能获取精确的修改时间

文件修改时间改了,单文件内容却没有变

Etag/If-None-Match

此缓存策略优先级高于Last-Modified/If-Modified-Since

文件内容的hash值

etag —— response header

if-none-Match —— request header

需要与cache-controlgongt使用

总体缓存流程图

服务器端性能 vue渲染遇到的问题

vue执行过程:
下载vue.js ==> 执行vue.js代码 ==> 生成HTML页面

随着前端浏览器的性能的提升,大量的运算在前端执行。
使用vue框架出现了首屏性能、渲染问题。

优化方案?

构建层模板编译(在构建层做模板编译工作,将模板语法编译成在vueruntime中可以直接执行的js代码)

数据无关的prerender的方式(将vue渲染完成的静态页面返回)

服务端渲染

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107942.html

相关文章

  • 前端性能优化

    摘要:端优谈谈关于前端的缓存的问题我们都知道对页面进行缓存能够有利于减少请求发送,从而达到对页面的优化。而作为一名有追求的前端,势必要力所能及地优化我们前端页面的性能。这种方式主要解决了浅谈前端中的过早优化问题过早优化是万恶之源。 优化向:单页应用多路由预渲染指南 Ajax 技术的出现,让我们的 Web 应用能够在不刷新的状态下显示不同页面的内容,这就是单页应用。在一个单页应用中,往往只有一...

    Dean 评论0 收藏0
  • 前端优化 - 收藏集 - 掘金

    摘要:虽然有着各种各样的不同,但是相同的是,他们前端优化不完全指南前端掘金篇幅可能有点长,我想先聊一聊阅读的方式,我希望你阅读的时候,能够把我当作你的竞争对手,你的梦想是超越我。 如何提升页面渲染效率 - 前端 - 掘金Web页面的性能 我们每天都会浏览很多的Web页面,使用很多基于Web的应用。这些站点看起来既不一样,用途也都各有不同,有在线视频,Social Media,新闻,邮件客户端...

    VincentFF 评论0 收藏0
  • 前端资源系列(4)-前端学习资源分享&前端面试资源汇总

    摘要:特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 特意对前端学习资源做一个汇总,方便自己学习查阅参考,和好友们共同进步。 本以为自己收藏的站点多,可以很快搞定,没想到一入汇总深似海。还有很多不足&遗漏的地方,欢迎补充。有错误的地方,还请斧正... 托管: welcome to git,欢迎交流,感谢star 有好友反应和斧正,会及时更新,平时业务工作时也会不定期更...

    princekin 评论0 收藏0
  • 前端每周清单年度总结与盘点

    摘要:前端每周清单年度总结与盘点在过去的八个月中,我几乎只做了两件事,工作与整理前端每周清单。本文末尾我会附上清单线索来源与目前共期清单的地址,感谢每一位阅读鼓励过的朋友,希望你们能够继续支持未来的每周清单。 showImg(https://segmentfault.com/img/remote/1460000010890043); 前端每周清单年度总结与盘点 在过去的八个月中,我几乎只做了...

    jackwang 评论0 收藏0
  • 鸟瞰前端 , 再论性能优化

    摘要:前端性能优化的涉及点从服务器到协议再到宿主环境本身都要有比较深刻的认识,业界目前主要还是以雅虎总结出来条前端性能优化的黄金军规为参考。 欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 导语 : 从事前端有6年+的时间了,从最开始的美工到重构再到偏向js逻辑开发的前端开发,一直在前端这个行业里面摸索和学习,我现在将自己这些年的一个心得体会来个系统性的梳理写成一篇关于性能优化...

    voidking 评论0 收藏0
  • 王下邀月熊_Chevalier的前端每周清单系列文章索引

    摘要:感谢王下邀月熊分享的前端每周清单,为方便大家阅读,特整理一份索引。王下邀月熊大大也于年月日整理了自己的前端每周清单系列,并以年月为单位进行分类,具体内容看这里前端每周清单年度总结与盘点。 感谢 王下邀月熊_Chevalier 分享的前端每周清单,为方便大家阅读,特整理一份索引。 王下邀月熊大大也于 2018 年 3 月 31 日整理了自己的前端每周清单系列,并以年/月为单位进行分类,具...

    2501207950 评论0 收藏0

发表评论

0条评论

raoyi

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<