Html解析成DOM树,Css解析成CSS树,将DOM树与CSSDOM规则树合并在一起生成Render树,遍历渲染树开始布局,计算每个节点的位置大小信息,将渲染树每个节点绘制到屏幕
阻塞渲染当浏览器遇到一个script标记时,DOM构建将暂停,直至脚本完成执行,然后继续构建DOM。每次去执行JavaScript脚本都会严重的阻塞DOM树的构建,如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM还没下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建
浏览器下载脚本时,会阻塞其他资源并行下载,即使是来自不同域名的资源。因此,最好将脚本放在底部,以提高页面加载速度。link的css样式放在head中,引入的包放在自己的js之前。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> <link rel="stylesheet" type="text/css" href="D:/deng/project/myreports-project/first/index.css" /> </head> <body> <div id='#app'></div> <script src='./index.js'></script> </body> </html>从输入URL到浏览器显示页面发生了什么
浏览器获取资源需要做DNS解析,建立了TCP/IP的连接,所以项目中存在很多域名时会直接导致加载缓慢。
浏览器需要查询域名对应的ip的地址,一般需要耗费20-120毫秒时间。DNS查询完成之前,浏览器无法从服务器下载任何数据,但是可以缓存
IE缓存30分钟,可以通过注册表中DnsCacheTimeout项设置; Firefox缓存1分钟,通过network.dnsCacheExpiration配置;前端缓存最佳实践
在介绍缓存的时候,我们习惯将缓存分为强缓存和协商缓存两种。两者的主要区别是使用本地缓存的时候,是否需要向服务器验证本地缓存是否依旧有效。顾名思义,协商缓存,就是需要和服务器进行协商,最终确定是否使用本地缓存。
页面初始加载时哪些内容是绝对必需的?不是必须展示的资源都可以延迟加载
非首屏使用的数据、样式、脚本、图片等; 用户交互时才会显示的内容。预先加载利用浏览器空闲时间请求将来要使用的资源,以便用户访问下一页面时更快地响应。根据用户行为预判用户去向,预载相关资源。比如search.yahoo.com开始输入时会有额外的资源加载。Chrome 等浏览器的地址栏也有类似的机制。
复杂的页面不仅下载的字节更多,JavaScript DOM操作也更慢。例如,同是添加一个事件处理器,500个元素和5000个元素的页面速度上会有很大区别。而且层级很深对SEO也不友好,结构变化时,回流时更需要时间。
用iframe可以把一个HTML文档插入到父文档里,重要的是明白iframe是如何工作的并高效地使用它。
加载代价昂贵,即使是空的页面; 阻塞页面 load 事件触发; 不利于SEO浏览器一般会限制每个域的并行线程(一般为6个,甚至更少),使用不同的域名可以最大化下载线程,但注意保持在2-4个域名内,以避免DNS查询损耗。
CDN的全称Content Delivery Network,(缩写:CDN)即内容分发网络。
CDN是一个经策略性部署的整体系统,从技术上全面解决由于网络带宽小、用户访问量大、网点分布不均而产生的用户访问网站响应速度慢的根本原因。
CDN目的是通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络“边缘”,使用户可以就近取得所需的内容,解决 Internet 网络拥塞状况,提高用户访问网站的响应速度。
一般的公司不可能在每个城市地区都有服务器,那么用户一次完整的请求要经过的历程将路漫漫其修远兮
前端缓存最佳实践
HTML:使用协商缓存。 CSS&JS&图片:使用强缓存,文件命名带上hash值。Gzip压缩通常可以减少70%的响应大小,对某些文件更可能高达90%,比Deflate更高效。主流 Web 服务器都有相应模块,而且绝大多数浏览器支持gzip解码。所以,应该对HTML、CSS、JS、XML、JSON等文本类型的内容启用压缩,Nginx能直接读取gzip文件。
注意!!! 图片和 PDF 文件不要使用 gzip。它们本身已经压缩过,再使用 gzip 压缩不仅浪费 CPU 资源,而且还可能增加文件体积。浏览器执行XMLHttpRequest POST请求时分成两步,先发送Http Header,再发送data。而GET只使用一个TCP数据包(Http Header与data)发送数据,所以首选GET方法。根据HTTP规范,GET用于获取数据,POST则用于向服务器发送数据,所以Ajax请求数据时使用GET更符合规范。
Load balancing,即负载均衡,是一种计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。
最直接有效的方法就是给服务器升级,提高带宽与内存,既能抵挡cc攻击,又能让并发变高。
我们只需要打开待测试的网页,然后点击Page Speed里的 Start analyzing按钮,它就会自动帮我们测试网络传输性能了
然后结束后能查看当前网页的nodes,listener,deep,可以分析出是否存在内存溢出风险,性能优化需要的修改。
请不要忘记为你的网站加上它,它就好像是你的网站的 ID。无论你有没有 favicon.ico ,用户的浏览器依然会请求它。如果你忘记加上这个档案,你的网站就会返回 404 Not Found,这会让浏览器面红。。。所以你要小心一点,避免给予用户负面的第一印象。要解决这个问题,你可以透过?Favicon Generator?生成 favicon 和 manifest 档案。
把样式表放在中可以让页面渐进渲染,尽早呈现视觉反馈,给用户加载速度很快的感觉。这对内容比较多的页面尤为重要,用户可以先查看已经下载渲染的内容,而不是盯着白屏等待。
CSS表达式,如下面这个例子:
background-color:expression((new Date().getHours()%2?"#B8D4FF":"#F08A00"));这个表示是为了实现背景颜色每2个小时变化一次;这种会导致性能下降。不过应该多数开发人员比较少使用CSS表达式。这里就一笔带过就好了。
对于IE某些版本,@import的行为和放在页面底部一样。所以,不要用它。
浏览器下载脚本时,会阻塞其他资源并行下载,即使是来自不同域名的资源。因此,最好将脚本放在底部,以提高页面加载速度。
JavaScript 操作 DOM 很慢,尤其是 DOM 节点很多时。当然现在前端框架都是使用虚拟DOM,很少直接操作DOM了。
减少绑定事件监听的节点,如通过事件委托,就是子级交互都是一个,不如父级来添加这个事件;尽早处理事件,在DOMContentLoaded即可进行,不用等到load以后。
react提供这个钩子函数来优化不必要的渲染,可以自定义渲染时机
class CounterButton extends React.Component { constructor(props) { super(props); this.state = {count: 1}; } shouldComponentUpdate(nextProps, nextState) { if (this.props.color !== nextProps.color) { return true; } if (this.state.count !== nextState.count) { return true; } return false; } render() { return ( <button color={this.props.color} onClick={() => this.setState(state => ({count: state.count + 1}))}> Count: {this.state.count} </button> ); } }使用第一种,第二种每次render都会执行,第三种每次render都会生成箭头函数。
props的更改会导致子组件更新,props尽量只传需要的数据,避免多余的更新,尽量避免使用{…props}
为list添加key,能帮助react在更新时准确找到要更新的部分。
使用webpack打包压缩代码。
可以将路由打包拆分,将会生成多个js文件,在路由加载到的时候才加载该js文件,像umijs就自带路由系统,能配置路由是否按需加载。
可以将路由打包拆分,将会生成多个js文件,在路由加载到的时候才加载该js文件,具体实现方案的话,如下:
1、基于require.js来实现引入模块的方式(比较老)
let routes = [ {path: '/home', component: resolve => require(['./components/Home.vue'], resolve), children:[ {path: '/detail', component: resolve => require(['./components/Detail.vue'], resolve)} ]} ]2、es6模块化的拆分形式
let routes = [ {path: '/home', component: () => import('./components/Home.vue'), children:[ {path: '/detail', component: () => import('./components/Detail.vue'), resolve)} ]} ]像这种全局引入会导致最终打包文件过大,首次加载时间非常长
import Vue from 'vue'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);v-show和v-if的区别是:v-if是懒加载,当状态为true时才会加载,并且为false时不会占用布局空间;v-show是无论状态是true或者是false,都会进行渲染,并对布局占据空间对于在项目中,需要频繁调用,不需要权限的显示隐藏,可以选择使用v-show,可以减少系统的切换开销。
props的更改会导致子组件更新,props尽量只传需要的数据,避免多余的更新,尽量避免使用{…props}
为list添加key,能帮助react在更新时准确找到要更新的部分。
1、sourcemap 一个可以从中查看源码的文件,但是在线上环境是没必要的,这个就可以关闭
2、别名的使用,使用别名比使用相对路径在服务器上查找文件更快
module.exports = { resolve: { extensions: ['.js', '.vue', '.json'], // 使用这些后缀的文件时就可不写扩展名 alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), } } }3、assetsPublicPath设置为/时能被nginx代理识别,但是无法被文件系统识别,但是访问速度比设置成./时快
module.exports = { build:{ assetsPublicPath: '/', } }4、js文件压缩,webpack使用uglifyjs-webpack-plugin插件压缩js代码
虽然src属性为空字符串,但浏览器仍然会向服务器发起一个HTTP请求:
IE 向页面所在的目录发送请求; Safari、Chrome、Firefox向页面本身发送请求; Opera不执行任何操作。空src产生请求的后果不容小觑:
给服务器造成意外的流量负担,尤其时日 PV 较大时; 浪费服务器计算资源; 可能产生报错。将很多图片图标整合到一张图片,通过background-position来控制显示位置。
不论是压缩后的图片,还是雪碧图,终归还是图片,只要是图片,就还是会占用大量网络传输资源。字体图标是通过css实现的,而且可以通过font-size来改变尺寸,通过color来改变颜色,比图片资源更灵活。
不要使用的width、height缩放图片,如果用到小图片,就使用相应大小的图片。如果需要那么图片本身(mycat.jpg)应该是100x100px的,而不是去缩小500x500px的图片。现在很多云存储支持图片裁剪,能自定义很多种的裁剪方式。
WebP格式,是谷歌公司开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器带宽资源和数据空间。Facebook、Ebay等知名网站已经开始测试并使用WebP格式。
一张图片就是一个标签,浏览器是否发起请求图片是根据的src属性,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给的src赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给src赋值。