찾다
웹 프론트엔드HTML 튜토리얼阿里技术文章分享:无线性能优化:页面可见时间与异步加载_html/css_WEB-ITnose

如何让页面尽可能早地渲染页面,页面更早可见,让白屏时间更短,尤其是无线环境下,一直是性能优化的话题。

页面可见时间

页面可见要经历以下过程:

  • 解析 HTML 为 DOM,解析 CSS 为 CSSOM(CSS Object Model)
  • 将 DOM 和 CSSOM 合成一棵渲染树( render tree )
  • 完成渲染树的布局(layout)
  • 将渲染树绘制到屏幕

layout

由于 JS 可能随时会改变 DOM 和  CSSOM ,当页面中有大量的 JS 想立刻执行时,浏览器下载并执行,直到完成 CSSOM 下载与构建,而在我们等待时,DOM 构建同样被阻塞。为了 JS 不阻塞 DOM 和 CSSDOM 的构建,不影响首屏可见的时间,测试几种 JS 加载策略对页面可见的影响:

几种异步加载方式测试

  • A. head script: 即普通的将 JS 放在  head  中或放在  body  中间: DEMO 地址
  • B. bottom script: 即常规的优化策略,JS 放 body 的底部: DEMO 地址
  • C. document.write: 以前 PC 优化少用的一种异步加载 JS 的策略: DEMO 地址

    function injectWrite(src){  document.write('<script src="' + src + '"></sc' + 'ript>');}
  • D. getScript: 形如以下,也是 KISSY 内部的 getScript 函数的简易实现: DEMO 地址

    <script> var script = document.createElement('script'); script.src = "//g.tbcdn.com/xx.js"; document.getElementsByTagName('head')[0].appendChild(script);</script>
  • E. 加 async 属性: DEMO 地址

  • F. 加  defer  属性: DEMO 地址
  • G. 同时加  async   defer  属性: DEMO 地址

测试结果

以下提到的 domReady 同  DOMContentLoaded 事件。

A (head script) B (bottom script) C (document.write) D (getScript) E (async) F (defer) G (async + defer)
1 PC Chrome 页面白屏长、domReady:5902.545、onLoad:5931.48 页面先显示、domReady:5805.21、onLoad:5838.255 页面先显示、domReady:5917.95、onLoad:5949.30 页面先显示、domReady:244.41、onLoad:5857.645 页面先显示、domReady:567.01、onLoad:5709.33 页面先显示、domReady:5812.12、onLoad:5845.6 页面先显示、domReady:576.12、onLoad:5743.79
2 iOS Safari 页面白屏长、domReady:6130、onLoad:6268.41 页面白屏长、domReady:5175.80、onLoad:5182.75 页面白屏长、domReady:5617.645、onLoad:5622.115 502s 白屏然后页面显示最后变更 load finish 时间、domReady:502.71、onLoad:6032.95 508s 白屏然后页面显示最后变更 load finish time domReady:508.95、onLoad:5538.135 页面白屏长、domReady:5178.98、onLoad:5193.58 556s 白屏然后页面显示最后变更 load finish 时间、domReady:556、onLoad:5171.95
3 iOS 手淘 WebView 页面白屏长、页面出现 loading 消失、domReady: 5291.29、onLoad:5292.78 页面白屏长、页面未跳转 loading 消失、domReady: 5123.46、onLoad:5127.85 页面白屏长、页面未跳转 loading 消失、domReady: 5074.86、onLoad:5079.875 页面可见快、loading 消失快在 domReady 稍后、domReady:14.06、load finish:5141.735 页面可见快、loading 消失快在 domReady 稍后、domReady:13.89、load finish:5157.15 页面白屏长、loading 先消失再出现页面、domReady: 5132.395、onLoad:5137.52 页面可见快、然后 loading 消失、domReady:13.49、load finish:5124.08
4 Android browser 页面白屏长、domReady: 5097.29、onLoad:5100.37 页面白屏长、domReady: 5177.48、onLoad:5193.66 页面白屏长、domReady: 5125.96、onLoad:5165.06 页面可见快、等 5s 后更新 load finish 时间 domReady:463.33、load finish:5092.90 页面可见快、等 5s 后更新 load finish 时间 domReady:39.34、load finish:5136.55 页面白屏长、domReady: 5092.45、onLoad:5119.81 页面可见快、等 5s 后更新 load finish 时间 domReady:50.49、load finish:5507.668
5 Android 手淘 WebView 白屏时间长、一直 loading 直接页面可见、domReady:5058.91、onLoad:5073.81 页面立即可见、loading 消失快、等 5s 后更新 domReady 时间和 load 时间 domReady:4176.34、onLoad:4209.50 页面立即可见、loading 消失快、domReady:6011.18、onLoad:6031.93 页面可见快、loading 之后消失、等 5s 后更新 load finish 时间 domReady:36.31、load finish:5081.76 页面可见快、loading 随后消失、等 5s 后更新 load finish 时间 domReady:25.11、load finish:5113.81 页面可见快、loading 随后消失、等 5s 后更新 domReady 时间和 load 时间 domReady:5213.11、load finish:5312.19 页面可见快、loading 随后消失、等 5s 后更新 load finish 时间 domReady:89.67、load finish:5589.95

从以上测试结果可以看出以下结论:

  • 横向看, iOS Safari 和 Android browser 的在页面可见、domReady、onLoad 的时间表现一致。
  • 纵向看,bottom script、document.write 和 defer 三列,可知 document.write 和 defer 无任何异步效果,可见时间、domReady、onLoad 的触发时间和 bottom script 的情况一致。
  • 纵向看,async + defer 联合用和 async 的表现一致,故合并为 async。
  • 纵向看,script 放页头(head script)和 script 放 body 底部(bottom script)。iOS Safari 、Android browser 和 iOS WebView 表现一致,即使 script 放在 body 的底部也无济于事,页面白屏时间长,要等到 domReady 5s 多后结束才显示页面;唯独 Android WebView 的表现和 PC 的 Chrome 一致。
  • 单纯看手淘 WebView 容器中 loading 消失的时间,这个时间点 iOS 和 Android 的表现一致,即都是在 UIWebView 的 didFinishLoad 事件触发时消失。这个事件的触发可能在 domReady 之前(如:A3、B3),也可能在 domReady 之后(如:D3、E3);这个事件触发和 JS 中的 onLoad 触发时机也没有必然的联系,可能在 onLoad 之前(如:D3、E3)也可能在 onLoad 几乎同时(如:A5)。 didiFinishLoad 到底是什么时机触发的呢,详见下章。
  • 页面可见时间,getScript 方式和 async 方式页面可见都非常快,domReady 的时间触发得也非常快,客户端的 loading 在 domReady 稍后即消失。原因是因为 最后耗时的 JS 请求异步化了 ,没有阻塞浏览器的 DOM + CSSOM 构建,页面渲染完成就立刻可见了。整体看,如果 domReady 的时间快,则页面可见快;反之如果页面可见快,domReady 的时间不一定快,如 B5、B1、C1、C5、F1、F5。如果异步化耗时长的 JS,domReady 和 onLoad 的时间差距是很大的,不做任何处理 onLoad 的时间 domReady 的时间差 30ms 左右。所以在异步化的前提下,可以用 domReady 的时间作为页面可见的时间。

didFinishLoad 到底什么时候触发

didFinishLoad 是 native 定义的事件,该事件触发时手淘 loading 菊花消失,并且 windvane 中的发出请求不再收集,也就是 native 统计出的 pageLoad 时间。在用户数据平台看到的瀑布流请求,就是在 didFinishLoad 触发前收集到的所有请求。

经过上方测试,客户端的 didFinisheLoad 事件的触发和 JS 中的 domReady(DOMContentLoaded)和 onLoad 触发没有任何关联。可能在 domReady 之前或之后,也可能在 onLoad 之前或之后。

那它到底是什么时候触发呢? iOS 官方文档 是 Sent after a web view finishes loading a frame。 结合收集的用户请求和测试,didFinishLoad 是在连续发起的请求结束之后触发,监听一段时间内无请求则触发。

所以经常会看到 data_sufei 这个 JS 文件,在有些用户的瀑布流里面有,在有些用户的又没有。原因是这个 JS 是 aplus_wap.js 故意 setTimeout 1s 后发出的,如果页面在 1s 前所有的请求都发完了则触发 didFinishLoad,后面的 data_sufei.js 的时间就不算到 pageLoad 的时间;反之如果接近 1s 页面还有图片等请求还在发,则 data_sufei.js 的时间也会被算到里面。

因此在 JS 中用 setTimeout 来延迟发送请求也有可能会影响 didFinishLoad 的时间,建议 setTimeout 的时间设置得更长一点,如 3s。

async 和 defer

script 标签上可以添加 defer 和 async 属性来优化此 script 的下载和执行。

defer :延迟

HTML 4.0 规范,其作用是,告诉浏览器,等到 DOM+CSSOM 渲染完成,再执行指定脚本。

<script defer src="xx.js"></script>

  • 浏览器开始解析 HTML 网页
  • 解析过程中,发现带有 defer 属性的 script 标签
  • 浏览器继续往下解析 HTML 网页,解析完就渲染到页面上,同时并行下载 script 标签中的外部脚本
  • 浏览器完成解析 HTML 网页,此时再执行下载的脚本,完成后触发 DOMContentLoaded

下载的脚本文件在 DOMContentLoaded 事件触发前执行(即刚刚读取完\标签),而且可以保证执行顺序就是它们在页面上出现的顺序。所以 添加 defer 属性后,domReady 的时间并没有提前,但它可以让页面更快显示出来。

将放在页面上方的 script 加 defer,在 PC Chrome 下其效果相当于 把这个 script 放在底部,页面会先显示。 但对 iOS Safari 和 iOS WebView 加 defer 和 script 放底部一样都是长时间白屏。

async: 异步

HTML 5 规范,其作用是,使用另一个进程下载脚本,下载时不会阻塞渲染,并且下载完成后立刻执行。

<script async src="yy.js"></script>

  • 浏览器开始解析 HTML 网页
  • 解析过程中,发现带有 async 属性的 script 标签
  • 浏览器继续往下解析 HTML 网页,解析完先显示页面并触发 DOMContentLoaded,同时并行下载 script 标签中的外部脚本
  • 脚本下载完成,浏览器暂停解析 HTML 网页,开始执行下载的脚本
  • 脚本执行完毕,浏览器恢复解析 HTML 网页

async 属性可以保证脚本下载的同时,浏览器继续渲染。但是 async 无法保证脚本的执行顺序。哪个脚本先下载结束,就先执行那个脚本。

如何选择 async 和 defer

  • defer  可以保证执行顺序, async  不行【注:
  • async  可以提前触发  domReady , defer  不行【注:Firefox 的  defer  也可以提前触发 domready 】
  • defer  在 iOS 和部分 Android 下依然阻塞渲染,白屏时间长。
  • 当 script 同时加  async  和  defer  属性时,后者不起作用,浏览器行为由  async  属性决定。
  • async  和  defer  的兼容性不一致,好在  async  和  defer  无线端基本都支持, async  不支持 IE 9-。 附  async 兼容性   defer 兼容性

script inject 和 async

  <!-- BAD --><script src="//g.alicdn.com/large.js"></script><!-- GOOD --><script> var script = document.createElement('script'); script.src = "//g.alicdn.com/large.js"; document.getElementsByTagName('head')[0].appendChild(script);</script>

我们通常用这种 inject script 的方式来异步加载文件,特别是以前 Sea.js 、 KISSY 的盛行时,出现大量使用 $.use 来加载页面入口文件。这种方式和  async 的一样都能异步化 JS,不阻塞页面渲染。但真的是最快的吗?

一个常见的页面如下:一个 CSS,两个异步的 JS

JS 使用 script inject 的方式测试结果如下, DEMO :

JS 使用 async 的方式测试结果如下, DEMO :

对比结果发现,通过

也许大家会说,现在 CSS/JS 都预加载到客户端了,怎么加载不重要。但页面有可能分享出去也有可能运行在浏览器中,也有可能预加载失效。

综合上面 async 和 defer,推荐以下用法。

<!-- 现代浏览器用 'async', ie9-用 'defer' --><script src="//g.alicdn.com/alilog/mlog/aplus_wap.js" async defer></script>

其实现在无线站点 aplus.js 可以完全用这种方式引入,既不会阻塞 DOM 和 CSSOM ,也不会延长整个页面  onLoad 时间,而不是原来的 PC 上的  script inject 方式。

如果 aplus.js 在 PC 上这么用,IE 8/IE 9 应用的是 defer 属性,不会阻塞页面渲染,但是这个 JS 需要执行完后才触发 domReady(DOMContentLoaded)事件,故在 IE 8/IE 9 下可能会影响 domReady 的时间。

最后建议

  • 业务 JS 尽量异步,放 body 底部的 JS 在 iOS 上和部分 Android 是无效的,依然会阻塞首屏渲染。
  • 异步的方式尽可能原生用 async ,容器(浏览器、webview 等)级别自带优化,不要通过 JS 去模拟实现,如  getScript/ajax/KISSY.use/$.use  等。
  • 有顺序依赖关系的 JS 可以加 defer,不改变执行顺序,相当于放到页面底部,如 TMS head 中一时无法挪动位置的类库等。
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
HTML의 역할 : 웹 컨텐츠 구조HTML의 역할 : 웹 컨텐츠 구조Apr 11, 2025 am 12:12 AM

HTML의 역할은 태그 및 속성을 통해 웹 페이지의 구조와 내용을 정의하는 것입니다. 1. HTML은 읽기 쉽고 이해하기 쉽게하는 태그를 통해 컨텐츠를 구성합니다. 2. 접근성 및 SEO와 같은 시맨틱 태그 등을 사용하십시오. 3. HTML 코드를 최적화하면 웹 페이지로드 속도 및 사용자 경험이 향상 될 수 있습니다.

HTML 및 코드 : 용어를 자세히 살펴 봅니다HTML 및 코드 : 용어를 자세히 살펴 봅니다Apr 10, 2025 am 09:28 AM

"Code"는 "Code"BroadlyIncludeLugageslikeJavaScriptandPyThonforFunctureS (htMlisAspecificTypeofCodeFocudecturecturingWebContent)

HTML, CSS 및 JavaScript : 웹 개발자를위한 필수 도구HTML, CSS 및 JavaScript : 웹 개발자를위한 필수 도구Apr 09, 2025 am 12:12 AM

HTML, CSS 및 JavaScript는 웹 개발의 세 가지 기둥입니다. 1. HTML은 웹 페이지 구조를 정의하고 등과 같은 태그를 사용합니다. 2. CSS는 색상, 글꼴 크기 등과 같은 선택기 및 속성을 사용하여 웹 페이지 스타일을 제어합니다.

HTML, CSS 및 JavaScript의 역할 : 핵심 책임HTML, CSS 및 JavaScript의 역할 : 핵심 책임Apr 08, 2025 pm 07:05 PM

HTML은 웹 구조를 정의하고 CSS는 스타일과 레이아웃을 담당하며 JavaScript는 동적 상호 작용을 제공합니다. 세 사람은 웹 개발에서 의무를 수행하고 화려한 웹 사이트를 공동으로 구축합니다.

HTML은 초보자를 위해 쉽게 배우나요?HTML은 초보자를 위해 쉽게 배우나요?Apr 07, 2025 am 12:11 AM

HTML은 간단하고 배우기 쉽고 결과를 빠르게 볼 수 있기 때문에 초보자에게 적합합니다. 1) HTML의 학습 곡선은 매끄럽고 시작하기 쉽습니다. 2) 기본 태그를 마스터하여 웹 페이지를 만들기 시작하십시오. 3) 유연성이 높고 CSS 및 JavaScript와 함께 사용할 수 있습니다. 4) 풍부한 학습 리소스와 현대 도구는 학습 과정을 지원합니다.

HTML의 시작 태그의 예는 무엇입니까?HTML의 시작 태그의 예는 무엇입니까?Apr 06, 2025 am 12:04 AM

anexampleStartingtaginhtmlis, whithbeginsaparagraph.startingtagsareessentialinhtmlastheyinitiate rements, definetheirtypes, andarecrucialforstructurituringwebpages 및 smanstlingthedom.

메뉴에서 점선 분할 효과의 중심 정렬을 달성하기 위해 CSS의 Flexbox 레이아웃을 사용하는 방법은 무엇입니까?메뉴에서 점선 분할 효과의 중심 정렬을 달성하기 위해 CSS의 Flexbox 레이아웃을 사용하는 방법은 무엇입니까?Apr 05, 2025 pm 01:24 PM

메뉴에서 점선 분할 효과를 설계하는 방법은 무엇입니까? 메뉴를 설계 할 때는 일반적으로 접시 이름과 가격 사이에 왼쪽과 오른쪽을 정렬하는 것이 어렵지 않지만 점선 또는 중간의 점은 어떻습니까?

온라인 코드 편집기는 코드 입력을 구현하는 데 사용하는 HTML 요소는 무엇입니까?온라인 코드 편집기는 코드 입력을 구현하는 데 사용하는 HTML 요소는 무엇입니까?Apr 05, 2025 pm 01:21 PM

웹 코드 편집기의 HTML 요소 분석 많은 온라인 코드 편집기를 사용하면 사용자가 HTML, CSS 및 JavaScript 코드를 입력 할 수 있습니다. 최근에 누군가가 제안했습니다 ...

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

맨티스BT

맨티스BT

Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기