跳到主要内容

JS / CSS 标签

主题有两种方式引入 JavaScript 和 CSS:用 script_tagstylesheet_tag 过滤器引入 asset 文件,以及用 {% javascript %}{% stylesheet %} 标签把代码打包在 section 里。用对了页面渲染快,用错了会悄悄阻塞渲染。本文讲两种机制的正确用法,以及怎么把体积压下来。

选对引入方式

  • 全主题共用的资源——全局样式表、公共脚本——放在 assets 目录,在布局里用 stylesheet_tagscript_tag 引入。布局里已经引入的资源,不要在模板或 section 里再引一遍。
  • section 专属的代码放在 section 文件自身的 {% stylesheet %}{% javascript %} 标签里。section 保持自包含、可跨主题移植,不渲染这个 section 的页面也不用为它的代码买单。

正确使用 stylesheet_tag

stylesheet_tag 生成标准的 <link rel="stylesheet"> 标签:

{{ 'theme.css' | shoplaza_asset_url | stylesheet_tag }}
<link href="//static.shoplazza.com/themes/theme-589f053bba.css" rel="stylesheet" type="text/css" media="all" />

注意输出里的 media="all"media<link> 标签的标准 HTML 属性,表示这份样式表在什么场景下生效:all 是默认值(任何场景都生效),screen 表示只在屏幕上浏览时生效,print 表示只在访客打印页面或导出 PDF 时生效。

stylesheet_tag 唯一能配置的就是这个属性的值——在冒号后直接写,它会被原样填进 media

{{ 'theme.css' | shoplaza_asset_url | stylesheet_tag: 'print' }}
<link href="//static.shoplazza.com/themes/theme-589f053bba.css" rel="stylesheet" type="text/css" media="print" />

上面这份 CSS 只在打印时应用。这么标除了语义正确,还有性能收益:浏览器发现样式表的 media 和当前场景不匹配(在屏幕上浏览时遇到 print 样式),会降低它的下载优先级,而且不阻塞页面渲染——页面能更快显示出来。

注意

参数只能像上面这样直接写值。stylesheet_tag 没有 preload 或其他「参数名: 值」形式的选项——stylesheet_tag: preload: true 这样的调用不会报错,而是把整个参数塞进 media 属性,输出坏标签(media="Array")。

别让脚本阻塞渲染

script_tag 生成的始终是阻塞解析的标签——而且它会忽略任何参数,没有办法让它变成延迟加载:

<script src="//static.shoplazza.com/theme.js" type="text/javascript"></script>

阻塞解析的脚本会让浏览器停止构建页面,直到脚本下载执行完毕,直接拖慢首屏。script_tag 只留给极少数确实必须在页面渲染前运行的脚本;其余的用 shoplaza_asset_url 拼 URL、自己写标签:

<script src="{{ 'theme.js' | shoplaza_asset_url }}" defer></script>

执行顺序重要时用 defer(解析完成后按文档顺序执行),无所谓顺序时用 async。无法延迟的脚本放在 body 末尾,不放 head

用 section 标签写自包含代码

在 section 里,{% stylesheet %} 的内容注入在 section 标记之前,{% javascript %} 的内容注入在 </body> 之前——加载行为见 section assets

两条实践保证安全:

  • JavaScript 包进自执行函数。 变量留在闭包内,一个 section 的运行时异常不会波及其他 section:

    {% javascript %}
    (function () {
    const el = document.querySelector('.product-detail');
    // ...
    })();
    {% endjavascript %}
  • {% stylesheet %} 内可以使用 Liquid,可以直接引用主题设置:

    {% stylesheet %}
    .promo-banner {
    background: {{ settings.color_btn_bg }};
    }
    {% endstylesheet %}

    即便如此,全局颜色仍建议通过配色系统的 CSS 变量流转(background: var(--color-btn-bg)),而不是在每个 section 里读 settings——单一来源,换色一致。

把体积压下来

  • 压缩 assets 里发布的 JavaScript 和 CSS 文件。
  • 视觉行为能用 CSS 就不用 JavaScript——过渡、开关、简单交互很少需要脚本。
  • 别为小任务引入重型库;现代 DOM API 能覆盖主题的大多数需求,而每一 KB 都会发给每个访客。
  • 页面专属的代码拆成独立 asset、只在用到它的模板里引入,不要打成一个到处加载的大文件。