이번에는 페이지 최적화 방법에 대한 요약과 페이지 최적화를 위한 주의사항에 대해 알려드리겠습니다. 실제 사례를 살펴보겠습니다.
공식 웹사이트 홈페이지 로딩 속도를 높이고, 사용자 작업에 보다 신속하게 대응하며, 사용자에게 보다 친근한 경험을 제공합니다.
페이지 요청 수를 줄이고, 요청이 차지하는 대역폭을 줄이고, 리소스를 절약하세요.
은 세분성에 따라 두 가지 범주로 나뉩니다.
페이지 수준 최적화(HTTP 요청 수, 리소스 병합 및 압축, 리소스 로딩 타이밍 등)
코드 수준 최적화( DOM 연산 최적화, CSS 선택 문자 최적화, HTML 구조 최적화)
페이지 수준 최적화 목표는 기본적으로 어떻게 HTTP 요청 수를 줄이고 요청되는 리소스의 양을 줄이는 것입니다. 각 요청에는 시간 비용과 리소스 비용을 모두 포함하는 비용이 있습니다(완전한 요청에는 DNS 주소 지정, 서버와의 연결 설정, 데이터 전송, 서버 응답 대기 및 데이터 수신과 같은 "긴" 프로세스가 필요합니다. 복잡한 프로세스 )
정적 파일 유형에 따라 gulp 도구를 사용하여 js 파일과 css 파일을 병합하고 압축할 수 있습니다.
예를 들어 공식 웹사이트 프로젝트에는 7개의 CSS 파일과 10~20개 이상의 js 파일이 있으며 정적 리소스를 병합하고 압축하면 HTTP 오버헤드를 줄일 수 있습니다.
자주 변경되지 않는 모든 리소스(예: jquery, 다양한 lib 라이브러리, 플러그인 등)를 vender.css, vender.js라는 하나의 파일로 병합하고 압축합니다. 온라인에서 자주 변경되는 파일들은 index.css, index.js라는 이름의 하나의 파일로 병합 압축되어 해시 스탬프로 추가되며, 인덱스 및 기타 파일의 내용은 기본적으로 온라인이 될 때마다 변경되므로 이후에 해시가 추가됩니다. gulp가 자동으로 빌드됩니다. poke도 다르지만 렌더링 유형은 변경되지 않으므로 브라우저의 캐싱 메커니즘을 합리적으로 사용할 수 있습니다.
jq의 lazyload
플러그인을 사용하여 이미지 지연 로딩을 구현하세요. 필요한 이미지 리소스를 로드하기 전에 스크롤 막대가 해당 위치로 스크롤될 때까지 기다립니다. lazyload
插件实现图片懒加载。等滚动条滚动到对应的地方再加载所需要的图片资源。
不直接使用设计给的两倍图,用css的devicePixelRatio
检查设备的像素比,辅助区分视网膜设备还是非视网膜设备来决定加载两倍图还是原始大小的图片。
图片上传到cdn之前在保证不失真的情况下,用gulp-imagemin
工具压缩下大小。
将下图这样的小图片全部做成雪碧图,单色可以考虑用icon-font
来实现。或者直接在页面写svg代码和转成base64写到页面也行,总之是要减少http的请求数。
将首屏第一时间呈现给用户。
具体的做法是除了首屏dom元素之外,将所有的dom元素用一个template
元素进行包裹,等window监听到load事件后,将剩余的dom部分全部插到页面中。(tips:为避免用户可能还没等到window的load事件就开始滚动页面,可以将首屏的范围扩大。)
DNS预读取是一项使浏览器主动去执行域名解析的功能。DNS请求需要的带宽非常小,但是延迟却有点高。
下面是引用MDN的一句话:
在某些浏览器中这个预读取的行为将会与页面实际内容并行发生(而不是串行)。正因如此,某些高延迟的域名的解析过程才不会卡住资源的加载。
这样可以极大的加速(尤其是移动网络环境下)页面的加载。在某些图片较多的页面中,在发起图片加载请求之前预先把域名解析好将会有至少 5% 的图片加载速度提升。
具体做法:head
标签里加上
<link rel="dns-prefetch" href="https://data.dadaabc.com/">
data.dadaabc.com
devicePixelRatio
를 사용하여 장치의 픽셀 비율을 확인하면 레티나 장치와 비레티나 장치를 구별하는 데 도움이 됩니다. 이중 이미지 또는 원본 크기 이미지를 로드합니다. 🎜🎜🎜🎜이미지를 CDN에 업로드하기 전에 gulp-imagemin
도구를 사용하여 왜곡 없이 크기를 압축하세요. 🎜🎜🎜🎜아래와 같은 작은 그림을 모두 스프라이트 그림으로 만들려면 icon-font
를 사용하는 것이 좋습니다. 아니면 페이지에 직접 svg 코드를 작성하고 이를 base64로 변환하여 페이지에 작성할 수도 있습니다. 즉, http 요청 수를 줄여야 합니다. 🎜🎜🎜🎜🎜🎜3. loading 🎜🎜 첫 번째 화면을 사용자에게 즉시 제시합니다. 🎜구체적인 방법은 첫 번째 화면 DOM 요소를 제외한 모든 DOM 요소를 template
요소로 래핑하는 것입니다. 창에서 로드 이벤트를 모니터링한 후 나머지 DOM 부분이 모두 페이지에 삽입됩니다. (팁: 사용자가 창의 로드 이벤트를 기다리기 전에 페이지 스크롤을 시작하는 것을 방지하기 위해 첫 화면의 범위를 확장할 수 있습니다.) 🎜🎜4. DNS 사전 읽기🎜🎜DNS 사전 읽기는 다음을 허용하는 프로세스입니다. 브라우저가 도메인 이름 확인 기능을 적극적으로 수행합니다. DNS 요청에는 대역폭이 거의 필요하지 않지만 대기 시간은 약간 높습니다. 🎜다음은 MDN의 인용문입니다. 🎜일부 브라우저에서는 이 미리 가져오기 동작이 페이지의 실제 콘텐츠와 병렬로(연속적으로 발생하지 않고) 발생합니다. 이로 인해 대기 시간이 긴 일부 도메인 이름의 확인 프로세스는 리소스 로드를 차단하지 않습니다. 🎜이렇게 하면 페이지 로딩 속도가 크게 향상됩니다(특히 모바일 네트워크 환경에서). 이미지가 많은 일부 페이지에서 이미지 로드 요청을 시작하기 전에 도메인 이름을 미리 확인하면 이미지 로드 속도가 5% 이상 향상됩니다.🎜특정 방법: 🎜
head
태그에 🎜var ele = document.getElementById('myp'); ele.style.borderLeft = '1px'; ele.style.borderRight = '2px'; ele.style.padding = '5px';
data.dadaabc.com
을 추가합니다. 다른 정적 리소스가 있는 경우. 연결된 도메인 이름을 모두 함께 추가하세요. 🎜同域下浏览器能并发的请求有限,为了增加并发,尤其是一些静态资源上,可以使用多个域名。但由于域名DNS解析本身也是耗时的,所以也不是越多越好,chrome最大支持6路并发,所以一般设置2-4个域名较为合适。
具体的做法是:再增加cdn域名来下载静态资源。比如图片全部用img.dadaabc.com/
域名,css资源全部用css.dadaabc.com/
域名,这些域名最终全部指向同样的cdn服务器。静态资源域名加前缀可以用gulp-rev-replace
来实现。
统计代码全部放到window的load事件之后执行。为了便于管理统计代码,例如页面加上一些埋点,增加删除统计产品,我们可以借助Google Tag Manager
工具来统一管理。
具体做法是:页面只拉取Google Tag Manager
提供的gtm
代码,该js代码含有全部的统计产品,例如百度、Inspelect等, 这些统计产品也都是通过创建script标签来动态插入到页面中的。另外需要注意的是,google提供的gtm
代码是在google服务器上的,为了让获取该代码的速度更快,我们可以在自己的服务器上执行crontab
定时任务,每分钟获取一次,然后gtm
代码直接从自己服务器上获取。
css文件全部放到head
里,script文件全部放到body
的最底部。
原因:
把样式表移到head
里允许页面逐步渲染。
浏览器负责渲染的GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起(相当于被冻结了),GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
参考资料:从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理
举个例子:
var ele = document.getElementById('myp'); ele.style.borderLeft = '1px'; ele.style.borderRight = '2px'; ele.style.padding = '5px';
三个样式属性被改变,每一个都会影响元素的几何结构,虽然大部分现代浏览器都做了优化,只会引起一次重排,但是像上文一样,如果一个及时的属性被请求,那么就会强制刷新队列,而且这段代码四次访问DOM,一个很显然的优化策略就是把它们的操作合成一次,这样只会修改DOM一次:
var ele = document.getElementById('myp'); ele.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';
总结:同一个DOM的多个属性改变可以写在一起(减少DOM访问,同时把强制渲染队列刷新的风险降为0)
fragment是个轻量级的document对象,它的设计初衷就是为了完成更新和移动节点这样的任务。fragment的一个便利的语法特性是当你附加一个片断到节点时,实际上被添加的是该片断的子节点,而不是片断本身。只触发了一次重排,而且只访问了一次实时的DOM。
例如:
var fragment = document.createDocumentFragment(); var li = document.createElement('li'); li.innerHTML = 'apple'; fragment.appendChild(li); var li = document.createElement('li'); li.innerHTML = 'watermelon'; fragment.appendChild(li); document.getElementById('fruit').appendChild(fragment);
触发大量回调函数的事件,例如拖拽时的mousemove
事件,window对象的resize
、scroll
事件,文字输入、自动完成的keyup
事件等,需要合理使用函数防抖和函数节流机制。具体可以参考我的另外一篇文章函数防抖和函数节流
CSS选择器的解析式其实是从右到左的,例如:
#p1 a { color: red }
如上面的选择器,浏览器必须遍历查找所有的a元素,再去找ID为p1的元素,这样查找的方式显然很低效。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
위 내용은 페이지 최적화 방법 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!